mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
3.0.3.1
This commit is contained in:
parent
de8b55424d
commit
1e35f5fbd8
@ -1,5 +1,9 @@
|
|||||||
### Changelog
|
### Changelog
|
||||||
|
|
||||||
|
#### Version - 3.0.3.1 - 10/30/2022
|
||||||
|
* Fix file verification issues for CreatedBSAs
|
||||||
|
* Fix files during verification where CreatedDate > LastModified
|
||||||
|
|
||||||
#### Version - 3.0.3.0 - 10/26/2022
|
#### Version - 3.0.3.0 - 10/26/2022
|
||||||
* Verify hashes of all installed files
|
* Verify hashes of all installed files
|
||||||
* Verify contents of BSAs during installation
|
* Verify contents of BSAs during installation
|
||||||
|
@ -55,60 +55,57 @@ public class VerifyModlistInstall
|
|||||||
|
|
||||||
_logger.LogInformation("Scanning files");
|
_logger.LogInformation("Scanning files");
|
||||||
var errors = await list.Directives.PMapAllBatchedAsync(_limiter, async directive =>
|
var errors = await list.Directives.PMapAllBatchedAsync(_limiter, async directive =>
|
||||||
{
|
|
||||||
if (directive is ArchiveMeta)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (directive is RemappedInlineFile)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (directive.To.InFolder(Consts.BSACreationDir))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var dest = directive.To.RelativeTo(installFolder);
|
|
||||||
if (!dest.FileExists())
|
|
||||||
{
|
{
|
||||||
return new Result
|
if (!(directive is CreateBSA || directive.IsDeterministic))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (directive.To.InFolder(Consts.BSACreationDir))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var dest = directive.To.RelativeTo(installFolder);
|
||||||
|
if (!dest.FileExists())
|
||||||
{
|
{
|
||||||
Path = directive.To,
|
return new Result
|
||||||
Message = $"File does not exist directive {directive.GetType()}"
|
{
|
||||||
};
|
Path = directive.To,
|
||||||
}
|
Message = $"File does not exist directive {directive.GetType()}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Consts.KnownModifiedFiles.Contains(directive.To.FileName))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (directive is CreateBSA bsa)
|
||||||
|
{
|
||||||
|
return await VerifyBSA(dest, bsa, byTo, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest.Size() != directive.Size)
|
||||||
|
{
|
||||||
|
return new Result
|
||||||
|
{
|
||||||
|
Path = directive.To,
|
||||||
|
Message = $"Sizes do not match got {dest.Size()} expected {directive.Size}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (directive.Size > (1024 * 1024 * 128))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Hashing {Size} file at {Path}", directive.Size.ToFileSizeString(),
|
||||||
|
directive.To);
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = await AbsolutePathExtensions.Hash(dest, token);
|
||||||
|
if (hash != directive.Hash)
|
||||||
|
{
|
||||||
|
return new Result
|
||||||
|
{
|
||||||
|
Path = directive.To,
|
||||||
|
Message = $"Hashes do not match, got {hash} expected {directive.Hash}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (Consts.KnownModifiedFiles.Contains(directive.To.FileName))
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (directive is CreateBSA bsa)
|
|
||||||
{
|
|
||||||
return await VerifyBSA(dest, bsa, byTo, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dest.Size() != directive.Size)
|
|
||||||
{
|
|
||||||
return new Result
|
|
||||||
{
|
|
||||||
Path = directive.To,
|
|
||||||
Message = $"Sizes do not match got {dest.Size()} expected {directive.Size}"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (directive.Size > (1024 * 1024 * 128))
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Hashing {Size} file at {Path}", directive.Size.ToFileSizeString(),
|
|
||||||
directive.To);
|
|
||||||
}
|
|
||||||
|
|
||||||
var hash = await AbsolutePathExtensions.Hash(dest, token);
|
|
||||||
if (hash != directive.Hash)
|
|
||||||
{
|
|
||||||
return new Result
|
|
||||||
{
|
|
||||||
Path = directive.To,
|
|
||||||
Message = $"Hashes do not match, got {hash} expected {directive.Hash}"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}).Where(r => r != null)
|
}).Where(r => r != null)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@ -150,6 +147,9 @@ public class VerifyModlistInstall
|
|||||||
var astate = bsa.FileStates.First(f => f.Path == state.Path);
|
var astate = bsa.FileStates.First(f => f.Path == state.Path);
|
||||||
var srcDirective = byTo[Consts.BSACreationDir.Combine(bsa.TempID, astate.Path)];
|
var srcDirective = byTo[Consts.BSACreationDir.Combine(bsa.TempID, astate.Path)];
|
||||||
|
|
||||||
|
if (!srcDirective.IsDeterministic)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (srcDirective.Hash != hash)
|
if (srcDirective.Hash != hash)
|
||||||
{
|
{
|
||||||
return new Result
|
return new Result
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
using Wabbajack.Hashing.xxHash64;
|
using Wabbajack.Hashing.xxHash64;
|
||||||
using Wabbajack.Paths;
|
using Wabbajack.Paths;
|
||||||
|
|
||||||
@ -12,4 +13,6 @@ public abstract class Directive
|
|||||||
/// location the file will be copied to, relative to the install path.
|
/// location the file will be copied to, relative to the install path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RelativePath To { get; set; }
|
public RelativePath To { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore] public virtual bool IsDeterministic => true;
|
||||||
}
|
}
|
@ -8,4 +8,6 @@ namespace Wabbajack.DTOs.Directives;
|
|||||||
public class ArchiveMeta : Directive
|
public class ArchiveMeta : Directive
|
||||||
{
|
{
|
||||||
public RelativePath SourceDataID { get; set; }
|
public RelativePath SourceDataID { get; set; }
|
||||||
|
|
||||||
|
public override bool IsDeterministic => false;
|
||||||
}
|
}
|
@ -13,4 +13,6 @@ public class CreateBSA : Directive
|
|||||||
public RelativePath TempID { get; set; }
|
public RelativePath TempID { get; set; }
|
||||||
public IArchive State { get; set; }
|
public IArchive State { get; set; }
|
||||||
public AFile[] FileStates { get; set; } = Array.Empty<AFile>();
|
public AFile[] FileStates { get; set; } = Array.Empty<AFile>();
|
||||||
|
|
||||||
|
public override bool IsDeterministic => false;
|
||||||
}
|
}
|
@ -9,4 +9,5 @@ namespace Wabbajack.DTOs.Directives;
|
|||||||
[JsonAlias("RemappedInlineFile, Wabbajack.Lib")]
|
[JsonAlias("RemappedInlineFile, Wabbajack.Lib")]
|
||||||
public class RemappedInlineFile : InlineFile
|
public class RemappedInlineFile : InlineFile
|
||||||
{
|
{
|
||||||
|
public override bool IsDeterministic => false;
|
||||||
}
|
}
|
@ -11,4 +11,5 @@ public class TransformedTexture : FromArchive
|
|||||||
/// The file to apply to the source file to patch it
|
/// The file to apply to the source file to patch it
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ImageState ImageState { get; set; } = new();
|
public ImageState ImageState { get; set; } = new();
|
||||||
|
public override bool IsDeterministic => false;
|
||||||
}
|
}
|
@ -316,7 +316,7 @@ public class StandardInstaller : AInstaller<StandardInstaller>
|
|||||||
var astate = bsa.FileStates.First(f => f.Path == state.Path);
|
var astate = bsa.FileStates.First(f => f.Path == state.Path);
|
||||||
var srcDirective = indexedByDestination[Consts.BSACreationDir.Combine(bsa.TempID, astate.Path)];
|
var srcDirective = indexedByDestination[Consts.BSACreationDir.Combine(bsa.TempID, astate.Path)];
|
||||||
//DX10Files are lossy
|
//DX10Files are lossy
|
||||||
if (astate is not BA2DX10File)
|
if (astate is not BA2DX10File && srcDirective.IsDeterministic)
|
||||||
ThrowOnNonMatchingHash(bsa, srcDirective, astate, hash);
|
ThrowOnNonMatchingHash(bsa, srcDirective, astate, hash);
|
||||||
return (srcDirective, hash);
|
return (srcDirective, hash);
|
||||||
}).ToHashSet();
|
}).ToHashSet();
|
||||||
|
@ -56,6 +56,11 @@ public static class AbsolutePathExtensions
|
|||||||
return new FileInfo(file.ToNativePath()).LastWriteTimeUtc;
|
return new FileInfo(file.ToNativePath()).LastWriteTimeUtc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DateTime CreatedUtc(this AbsolutePath file)
|
||||||
|
{
|
||||||
|
return new FileInfo(file.ToNativePath()).CreationTimeUtc;
|
||||||
|
}
|
||||||
|
|
||||||
public static DateTime LastModified(this AbsolutePath file)
|
public static DateTime LastModified(this AbsolutePath file)
|
||||||
{
|
{
|
||||||
return new FileInfo(file.ToNativePath()).LastWriteTime;
|
return new FileInfo(file.ToNativePath()).LastWriteTime;
|
||||||
|
@ -92,6 +92,10 @@ public class FileHashCache
|
|||||||
if (result == default || result.Hash == default)
|
if (result == default || result.Hash == default)
|
||||||
return default;
|
return default;
|
||||||
|
|
||||||
|
// Fix for strange issue where dates are messed up on some systems
|
||||||
|
if (file.LastModifiedUtc() < file.CreatedUtc())
|
||||||
|
file.Touch();
|
||||||
|
|
||||||
if (result.LastModified == file.LastModifiedUtc().ToFileTimeUtc())
|
if (result.LastModified == file.LastModifiedUtc().ToFileTimeUtc())
|
||||||
{
|
{
|
||||||
return result.Hash;
|
return result.Hash;
|
||||||
|
Loading…
Reference in New Issue
Block a user