diff --git a/CHANGELOG.md b/CHANGELOG.md index 077c91e8..a725d436 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This is now the only way to include extra games in the install process, implicit * Includes a "Favor performance over RAM" optional mode (defaults to off) that will use excessive amounts of RAM in exchange for almost 1GB/sec install speed on the correct hardware. Don't enable this unless you have a fast SSD and at least 2.5GB of RAM for every install thread. +* If a downloaded file doesn't match the expected hash, try alternative download locations, if allowed #### Version - 2.2.2.0 - 8/31/2020 diff --git a/Wabbajack.Lib/Downloaders/DownloadDispatcher.cs b/Wabbajack.Lib/Downloaders/DownloadDispatcher.cs index 438d8002..8f83d94e 100644 --- a/Wabbajack.Lib/Downloaders/DownloadDispatcher.cs +++ b/Wabbajack.Lib/Downloaders/DownloadDispatcher.cs @@ -104,8 +104,9 @@ namespace Wabbajack.Lib.Downloaders { if (await Download(archive, destination)) { - await destination.FileHashCachedAsync(); - return DownloadResult.Success; + var downloadedHash = await destination.FileHashCachedAsync(); + if (downloadedHash == archive.Hash || archive.Hash == default) + return DownloadResult.Success; } diff --git a/Wabbajack.VirtualFileSystem/FileExtractor2/FileExtractor.cs b/Wabbajack.VirtualFileSystem/FileExtractor2/FileExtractor.cs index 0bf2da8d..bbf2d888 100644 --- a/Wabbajack.VirtualFileSystem/FileExtractor2/FileExtractor.cs +++ b/Wabbajack.VirtualFileSystem/FileExtractor2/FileExtractor.cs @@ -24,8 +24,21 @@ namespace Wabbajack.VirtualFileSystem Definitions.FileType.RAR_OLD, Definitions.FileType.RAR_NEW, Definitions.FileType._7Z); - + private static Extension OMODExtension = new Extension(".omod"); + private static Extension BSAExtension = new Extension(".bsa"); + + public static readonly HashSet ExtractableExtensions = new HashSet + { + new Extension(".bsa"), + new Extension(".ba2"), + new Extension(".7z"), + new Extension(".7zip"), + new Extension(".rar"), + new Extension(".zip"), + OMODExtension + }; + /// /// When true, will allow 7z to use multiple threads and cache more data in memory, potentially @@ -64,11 +77,16 @@ namespace Wabbajack.VirtualFileSystem } } - case Definitions.FileType.TES3: case Definitions.FileType.BSA: case Definitions.FileType.BA2: return await GatheringExtractWithBSA(sFn, (Definitions.FileType)sig, shouldExtract, mapfn); - + + case Definitions.FileType.TES3: + if (sFn.Name.FileName.Extension == BSAExtension) + return await GatheringExtractWithBSA(sFn, (Definitions.FileType)sig, shouldExtract, mapfn); + else + throw new Exception($"Invalid file format {sFn.Name}"); + default: throw new Exception($"Invalid file format {sFn.Name}"); diff --git a/Wabbajack.VirtualFileSystem/VirtualFile.cs b/Wabbajack.VirtualFileSystem/VirtualFile.cs index 63bdf4b2..10cbf753 100644 --- a/Wabbajack.VirtualFileSystem/VirtualFile.cs +++ b/Wabbajack.VirtualFileSystem/VirtualFile.cs @@ -177,16 +177,27 @@ namespace Wabbajack.VirtualFileSystem public static async Task Analyze(Context context, VirtualFile parent, IStreamFactory extractedFile, IPath relPath, int depth = 0) { - await using var stream = await extractedFile.GetStream(); - var hash = await stream.xxHashAsync(); - stream.Position = 0; + Hash hash = default; + if (extractedFile is NativeFileStreamFactory) + { + hash = await ((AbsolutePath)extractedFile.Name).FileHashCachedAsync(); + } + else + { + await using var hstream = await extractedFile.GetStream(); + hash = await hstream.xxHashAsync(); + } + if (TryGetFromCache(context, parent, relPath, extractedFile, hash, out var vself)) + { + return vself; + } + + + await using var stream = await extractedFile.GetStream(); var sig = await FileExtractor2.ArchiveSigs.MatchesAsync(stream); stream.Position = 0; - if (sig.HasValue && TryGetFromCache(context, parent, relPath, extractedFile, hash, out var vself)) - return vself; - var self = new VirtualFile { Context = context, @@ -204,7 +215,7 @@ namespace Wabbajack.VirtualFileSystem self.ExtendedHashes = await ExtendedHashes.FromStream(stream); // Can't extract, so return - if (!sig.HasValue) return self; + if (!sig.HasValue || !FileExtractor2.ExtractableExtensions.Contains(relPath.FileName.Extension)) return self; try {