mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Debug code and fixes for BA2 duplicate file bug
This commit is contained in:
parent
a1c5cfad82
commit
77acf01fa0
@ -75,6 +75,7 @@ namespace Compression.BSA.Test
|
|||||||
[InlineData(Game.Fallout4, 22223)] // 10mm SMG
|
[InlineData(Game.Fallout4, 22223)] // 10mm SMG
|
||||||
[InlineData(Game.Fallout4, 4472)] // True Storms
|
[InlineData(Game.Fallout4, 4472)] // True Storms
|
||||||
[InlineData(Game.Morrowind, 44537)]
|
[InlineData(Game.Morrowind, 44537)]
|
||||||
|
[InlineData(Game.Fallout4, 43474)] // EM 2 Rifle
|
||||||
public async Task BSACompressionRecompression(Game game, int modid)
|
public async Task BSACompressionRecompression(Game game, int modid)
|
||||||
{
|
{
|
||||||
var filename = await DownloadMod(game, modid);
|
var filename = await DownloadMod(game, modid);
|
||||||
@ -109,6 +110,11 @@ namespace Compression.BSA.Test
|
|||||||
|
|
||||||
Assert.Equal(file.Size, absName.Size);
|
Assert.Equal(file.Size, absName.Size);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Check Files should be case insensitive
|
||||||
|
Assert.Equal(a.Files.Count(), a.Files.Select(f => f.Path).ToHashSet().Count);
|
||||||
|
Assert.Equal(a.Files.Count(), a.Files.Select(f => f.Path.ToString().ToLowerInvariant()).ToHashSet().Count);
|
||||||
|
|
||||||
TestContext.WriteLine($"Building {bsa}");
|
TestContext.WriteLine($"Building {bsa}");
|
||||||
|
|
||||||
@ -132,6 +138,7 @@ namespace Compression.BSA.Test
|
|||||||
|
|
||||||
// Check same number of files
|
// Check same number of files
|
||||||
Assert.Equal(a.Files.Count(), b.Files.Count());
|
Assert.Equal(a.Files.Count(), b.Files.Count());
|
||||||
|
|
||||||
|
|
||||||
await a.Files.Zip(b.Files, (ai, bi) => (ai, bi))
|
await a.Files.Zip(b.Files, (ai, bi) => (ai, bi))
|
||||||
.PMap(Queue, pair =>
|
.PMap(Queue, pair =>
|
||||||
|
@ -108,6 +108,18 @@ namespace Compression.BSA
|
|||||||
|
|
||||||
public IEnumerable<IFile> Files { get; private set; }
|
public IEnumerable<IFile> Files { get; private set; }
|
||||||
public ArchiveStateObject State => new BA2StateObject(this);
|
public ArchiveStateObject State => new BA2StateObject(this);
|
||||||
|
public void Dump(Action<string> print)
|
||||||
|
{
|
||||||
|
print($"HeaderMagic: {_headerMagic}");
|
||||||
|
print($"Number of Files: {_numFiles}");
|
||||||
|
print($"----------------------------");
|
||||||
|
|
||||||
|
foreach (var file in Files)
|
||||||
|
{
|
||||||
|
print("\n");
|
||||||
|
file.Dump(print);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonName("BA2State")]
|
[JsonName("BA2State")]
|
||||||
@ -218,6 +230,12 @@ namespace Compression.BSA
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dump(Action<string> print)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
private void WriteHeader(BinaryWriter bw)
|
private void WriteHeader(BinaryWriter bw)
|
||||||
{
|
{
|
||||||
var ddsHeader = new DDS_HEADER();
|
var ddsHeader = new DDS_HEADER();
|
||||||
@ -426,6 +444,17 @@ namespace Compression.BSA
|
|||||||
internal int _index;
|
internal int _index;
|
||||||
|
|
||||||
public bool Compressed => _size != 0;
|
public bool Compressed => _size != 0;
|
||||||
|
|
||||||
|
public void Dump(Action<string> print)
|
||||||
|
{
|
||||||
|
print($"FullPath: {FullPath}");
|
||||||
|
print($"Name Hash: {_nameHash}");
|
||||||
|
print($"Offset: {_offset}");
|
||||||
|
print($"Flags: {_flags:x}");
|
||||||
|
print($"Real Size: {_realSize}");
|
||||||
|
print($"Index: {_index}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public BA2FileEntry(BA2Reader ba2Reader, int index)
|
public BA2FileEntry(BA2Reader ba2Reader, int index)
|
||||||
{
|
{
|
||||||
@ -442,6 +471,8 @@ namespace Compression.BSA
|
|||||||
_realSize = _rdr.ReadUInt32();
|
_realSize = _rdr.ReadUInt32();
|
||||||
_align = _rdr.ReadUInt32();
|
_align = _rdr.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string FullPath { get; set; }
|
public string FullPath { get; set; }
|
||||||
|
|
||||||
@ -473,6 +504,7 @@ namespace Compression.BSA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonName("BA2FileEntryState")]
|
[JsonName("BA2FileEntryState")]
|
||||||
|
@ -65,6 +65,20 @@ namespace Compression.BSA
|
|||||||
internal uint _totalFileNameLength;
|
internal uint _totalFileNameLength;
|
||||||
internal uint _totalFolderNameLength;
|
internal uint _totalFolderNameLength;
|
||||||
internal uint _version;
|
internal uint _version;
|
||||||
|
|
||||||
|
public void Dump(Action<string> print)
|
||||||
|
{
|
||||||
|
print($"File Name: {_fileName}");
|
||||||
|
print($"File Count: {_fileCount}");
|
||||||
|
print($"Magic: {_magic}");
|
||||||
|
|
||||||
|
foreach (var file in Files)
|
||||||
|
{
|
||||||
|
print("\n");
|
||||||
|
file.Dump(print);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public BSAReader(AbsolutePath filename)
|
public BSAReader(AbsolutePath filename)
|
||||||
{
|
{
|
||||||
@ -225,6 +239,18 @@ namespace Compression.BSA
|
|||||||
private readonly uint _originalSize;
|
private readonly uint _originalSize;
|
||||||
private readonly uint _size;
|
private readonly uint _size;
|
||||||
internal readonly int _index;
|
internal readonly int _index;
|
||||||
|
|
||||||
|
|
||||||
|
public void Dump(Action<string> print)
|
||||||
|
{
|
||||||
|
print($"Name: {_name}");
|
||||||
|
print($"Offset: {_offset}");
|
||||||
|
print($"On Disk Size: {_onDiskSize}");
|
||||||
|
print($"Original Size: {_originalSize}");
|
||||||
|
print($"Size: {_size}");
|
||||||
|
print($"Index: {_index}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public FileRecord(BSAReader bsa, FolderRecord folderRecord, BinaryReader src, int index)
|
public FileRecord(BSAReader bsa, FolderRecord folderRecord, BinaryReader src, int index)
|
||||||
{
|
{
|
||||||
|
@ -14,6 +14,8 @@ namespace Compression.BSA
|
|||||||
IEnumerable<IFile> Files { get; }
|
IEnumerable<IFile> Files { get; }
|
||||||
|
|
||||||
ArchiveStateObject State { get; }
|
ArchiveStateObject State { get; }
|
||||||
|
|
||||||
|
void Dump(Action<string> print);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IBSABuilder : IAsyncDisposable
|
public interface IBSABuilder : IAsyncDisposable
|
||||||
@ -59,5 +61,7 @@ namespace Compression.BSA
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="output"></param>
|
/// <param name="output"></param>
|
||||||
void CopyDataTo(Stream output);
|
void CopyDataTo(Stream output);
|
||||||
|
|
||||||
|
void Dump(Action<string> print);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,11 @@ namespace Compression.BSA
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dump(Action<string> print)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonName("TES3Archive")]
|
[JsonName("TES3Archive")]
|
||||||
@ -120,6 +125,11 @@ namespace Compression.BSA
|
|||||||
fs.CopyToLimit(output, (int)Size);
|
fs.CopyToLimit(output, (int)Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dump(Action<string> print)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public uint Offset { get; set; }
|
public uint Offset { get; set; }
|
||||||
public uint NameOffset { get; set; }
|
public uint NameOffset { get; set; }
|
||||||
public uint Hash1 { get; set; }
|
public uint Hash1 { get; set; }
|
||||||
|
@ -18,7 +18,8 @@ namespace Wabbajack.CLI
|
|||||||
typeof(MyFiles),
|
typeof(MyFiles),
|
||||||
typeof(DeleteFile),
|
typeof(DeleteFile),
|
||||||
typeof(Changelog),
|
typeof(Changelog),
|
||||||
typeof(FindSimilar)
|
typeof(FindSimilar),
|
||||||
|
typeof(BSADump)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ namespace Wabbajack.CLI
|
|||||||
(DeleteFile opts) => opts.Execute(),
|
(DeleteFile opts) => opts.Execute(),
|
||||||
(Changelog opts) => opts.Execute(),
|
(Changelog opts) => opts.Execute(),
|
||||||
(FindSimilar opts) => opts.Execute(),
|
(FindSimilar opts) => opts.Execute(),
|
||||||
|
(BSADump opts) => opts.Execute(),
|
||||||
errs => 1);
|
errs => 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
Wabbajack.CLI/Verbs/BSADump.cs
Normal file
22
Wabbajack.CLI/Verbs/BSADump.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CommandLine;
|
||||||
|
using Compression.BSA;
|
||||||
|
using Wabbajack.Common;
|
||||||
|
|
||||||
|
namespace Wabbajack.CLI.Verbs
|
||||||
|
{
|
||||||
|
[Verb("bsa-dump", HelpText = "Print detailed info about the contents of a BSA")]
|
||||||
|
public class BSADump : AVerb
|
||||||
|
{
|
||||||
|
[Option('i', "input", Required = true, HelpText = "Input BSA to dump")]
|
||||||
|
public string Input { get; set; } = "";
|
||||||
|
|
||||||
|
protected override async Task<ExitCode> Run()
|
||||||
|
{
|
||||||
|
await using var bsa = BSADispatch.OpenRead(Input.RelativeTo(AbsolutePath.GetCurrentDirectory()));
|
||||||
|
bsa.Dump(line => Console.WriteLine(line));
|
||||||
|
return ExitCode.Ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -61,6 +61,7 @@ namespace Wabbajack.Test
|
|||||||
DownloadAndInstall(Game.SkyrimSpecialEdition, 12604, "SkyUI"),
|
DownloadAndInstall(Game.SkyrimSpecialEdition, 12604, "SkyUI"),
|
||||||
DownloadAndInstall(Game.Fallout4, 11925, "Anti-Tank Rifle"),
|
DownloadAndInstall(Game.Fallout4, 11925, "Anti-Tank Rifle"),
|
||||||
DownloadAndInstall(Game.SkyrimSpecialEdition, 4783, "Frost Armor UNP"),
|
DownloadAndInstall(Game.SkyrimSpecialEdition, 4783, "Frost Armor UNP"),
|
||||||
|
DownloadAndInstall(Game.Fallout4, 43474, "EM 2 Rifle No.9 Mk1"),
|
||||||
DownloadAndInstall(Game.SkyrimSpecialEdition, 32359, "Frost Armor HDT"));
|
DownloadAndInstall(Game.SkyrimSpecialEdition, 32359, "Frost Armor HDT"));
|
||||||
|
|
||||||
// We're going to fully patch this mod from another source.
|
// We're going to fully patch this mod from another source.
|
||||||
|
@ -359,7 +359,7 @@ namespace Wabbajack.VirtualFileSystem
|
|||||||
public async Task<IndexRoot> Integrate(ICollection<VirtualFile> files)
|
public async Task<IndexRoot> Integrate(ICollection<VirtualFile> files)
|
||||||
{
|
{
|
||||||
Utils.Log($"Integrating {files.Count} files");
|
Utils.Log($"Integrating {files.Count} files");
|
||||||
var allFiles = AllFiles.Concat(files).GroupBy(f => f.Name).Select(g => g.Last()).ToImmutableList();
|
var allFiles = AllFiles.Concat(files).GroupBy(f => f.FullPath).Select(g => g.Last()).ToImmutableList();
|
||||||
|
|
||||||
var byFullPath = Task.Run(() => allFiles.SelectMany(f => f.ThisAndAllChildren)
|
var byFullPath = Task.Run(() => allFiles.SelectMany(f => f.ThisAndAllChildren)
|
||||||
.ToDictionary(f => f.FullPath));
|
.ToDictionary(f => f.FullPath));
|
||||||
|
Loading…
Reference in New Issue
Block a user