mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
implement new BSA framework for old BSA routines
This commit is contained in:
parent
ce4a3e17dd
commit
88fa091d07
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@ -9,17 +10,24 @@ namespace Compression.BSA.Test
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
private const string TestDir = @"D:\MO2 Instances\F4EE";
|
||||
//private const string TestDirBSA = @"D:\MO2 Instances\F4EE";
|
||||
//private const string TestDirBA2 = @"D:\MO2 Instances\F4EE";
|
||||
private const string TestDir = @"D:\MO2 Instances";
|
||||
//private const string TestDir = @"D:\Steam\steamapps\common\Fallout 4";
|
||||
private const string TempDir = @"c:\tmp\out\f4ee";
|
||||
private const string ArchiveTempDir = @"c:\tmp\out\archive";
|
||||
|
||||
//private const string Archive2Location = @"D:\Steam\steamapps\common\Fallout 4\Tools\Archive2\Archive2.exe";
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
foreach (var bsa in Directory.EnumerateFiles(TestDir, "*.ba2", SearchOption.AllDirectories).Skip(0))
|
||||
foreach (var bsa in Directory.EnumerateFiles(TestDir, "*.ba2", SearchOption.AllDirectories)
|
||||
.Concat(Directory.EnumerateFiles(TestDir, "*.bsa", SearchOption.AllDirectories)).Skip(200))
|
||||
{
|
||||
Console.WriteLine($"From {bsa}");
|
||||
Console.WriteLine("Cleaning Output Dir");
|
||||
if (Directory.Exists(TempDir)) Directory.Delete(TempDir, true);
|
||||
if (Directory.Exists(ArchiveTempDir)) Directory.Delete(ArchiveTempDir, true);
|
||||
Directory.CreateDirectory(TempDir);
|
||||
|
||||
Console.WriteLine($"Reading {bsa}");
|
||||
@ -28,6 +36,7 @@ namespace Compression.BSA.Test
|
||||
Parallel.ForEach(a.Files, file =>
|
||||
{
|
||||
var abs_name = Path.Combine(TempDir, file.Path);
|
||||
ViaJson(file.State);
|
||||
|
||||
if (!Directory.Exists(Path.GetDirectoryName(abs_name)))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(abs_name));
|
||||
@ -43,6 +52,22 @@ namespace Compression.BSA.Test
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
Console.WriteLine("Extracting via Archive.exe");
|
||||
if (bsa.ToLower().EndsWith(".ba2"))
|
||||
{
|
||||
var p = Process.Start(Archive2Location, $"\"{bsa}\" -e=\"{ArchiveTempDir}\"");
|
||||
p.WaitForExit();
|
||||
|
||||
foreach (var file in a.Files)
|
||||
{
|
||||
var a_path = Path.Combine(TempDir, file.Path);
|
||||
var b_path = Path.Combine(ArchiveTempDir, file.Path);
|
||||
Equal(new FileInfo(a_path).Length, new FileInfo(b_path).Length);
|
||||
Equal(File.ReadAllBytes(a_path), File.ReadAllBytes(b_path));
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
Console.WriteLine($"Building {bsa}");
|
||||
|
||||
@ -59,9 +84,6 @@ namespace Compression.BSA.Test
|
||||
});
|
||||
|
||||
w.Build("c:\\tmp\\tmp.bsa");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Console.WriteLine($"Verifying {bsa}");
|
||||
@ -163,7 +185,7 @@ namespace Compression.BSA.Test
|
||||
|
||||
for (var idx = 0; idx < a.Length; idx++)
|
||||
if (a[idx] != b[idx])
|
||||
throw new InvalidDataException($"Byte array contents not equal at {idx}");
|
||||
throw new InvalidDataException($"Byte array contents not equal at {idx} - {a[idx]} vs {b[idx]}");
|
||||
}
|
||||
}
|
||||
}
|
@ -250,6 +250,7 @@ namespace Compression.BSA
|
||||
ddsHeader.dwWidth = _width;
|
||||
ddsHeader.dwMipMapCount = _numMips;
|
||||
ddsHeader.PixelFormat.dwSize = ddsHeader.PixelFormat.GetSize();
|
||||
ddsHeader.dwDepth = 1;
|
||||
ddsHeader.dwSurfaceFlags = DDS.DDS_SURFACE_FLAGS_TEXTURE | DDS.DDS_SURFACE_FLAGS_MIPMAP;
|
||||
|
||||
switch ((DXGI_FORMAT)_format)
|
||||
@ -274,7 +275,7 @@ namespace Compression.BSA
|
||||
if (_bsa.UseATIFourCC)
|
||||
ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('A', 'T', 'I', '2'); // this is more correct but the only thing I have found that supports it is the nvidia photoshop plugin
|
||||
else
|
||||
ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('D', 'X', 'T', '5');
|
||||
ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('B', 'C', '5', 'U');
|
||||
ddsHeader.dwPitchOrLinearSize = (uint)(_width * _height); // 8bpp
|
||||
break;
|
||||
case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||
|
@ -11,7 +11,7 @@ using Path = Alphaleonis.Win32.Filesystem.Path;
|
||||
|
||||
namespace Compression.BSA
|
||||
{
|
||||
public class BSABuilder : IDisposable
|
||||
public class BSABuilder : IDisposable, IBSABuilder
|
||||
{
|
||||
internal uint _archiveFlags;
|
||||
internal uint _fileCount;
|
||||
@ -32,6 +32,13 @@ namespace Compression.BSA
|
||||
_offset = 0x24;
|
||||
}
|
||||
|
||||
public BSABuilder(BSAStateObject bsaStateObject) : this()
|
||||
{
|
||||
_version = bsaStateObject.Version;
|
||||
_fileFlags = bsaStateObject.FileFlags;
|
||||
_archiveFlags = bsaStateObject.ArchiveFlags;
|
||||
}
|
||||
|
||||
public IEnumerable<FileEntry> Files => _files;
|
||||
|
||||
public ArchiveFlags ArchiveFlags
|
||||
@ -85,6 +92,18 @@ namespace Compression.BSA
|
||||
return r;
|
||||
}
|
||||
|
||||
public void AddFile(FileStateObject state, Stream src)
|
||||
{
|
||||
var ostate = (BSAFileStateObject) state;
|
||||
|
||||
var r = new FileEntry(this, ostate.Path, src, ostate.FlipCompression);
|
||||
|
||||
lock (this)
|
||||
{
|
||||
_files.Add(r);
|
||||
}
|
||||
}
|
||||
|
||||
public void Build(string outputName)
|
||||
{
|
||||
RegenFolderRecords();
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
|
||||
using K4os.Compression.LZ4.Streams;
|
||||
using File = Alphaleonis.Win32.Filesystem.File;
|
||||
@ -48,19 +49,19 @@ namespace Compression.BSA
|
||||
|
||||
public class BSAReader : IDisposable, IBSAReader
|
||||
{
|
||||
private uint _archiveFlags;
|
||||
private uint _fileCount;
|
||||
private uint _fileFlags;
|
||||
internal uint _archiveFlags;
|
||||
internal uint _fileCount;
|
||||
internal uint _fileFlags;
|
||||
internal string _fileName;
|
||||
private uint _folderCount;
|
||||
private uint _folderRecordOffset;
|
||||
internal uint _folderCount;
|
||||
internal uint _folderRecordOffset;
|
||||
private List<FolderRecord> _folders;
|
||||
private string _magic;
|
||||
internal string _magic;
|
||||
private readonly BinaryReader _rdr;
|
||||
private readonly Stream _stream;
|
||||
private uint _totalFileNameLength;
|
||||
private uint _totalFolderNameLength;
|
||||
private uint _version;
|
||||
internal uint _totalFileNameLength;
|
||||
internal uint _totalFolderNameLength;
|
||||
internal uint _version;
|
||||
|
||||
public BSAReader(string filename) : this(File.OpenRead(filename))
|
||||
{
|
||||
@ -84,7 +85,7 @@ namespace Compression.BSA
|
||||
}
|
||||
}
|
||||
|
||||
public ArchiveStateObject State { get; }
|
||||
public ArchiveStateObject State => new BSAStateObject(this);
|
||||
|
||||
public VersionType HeaderType => (VersionType) _version;
|
||||
|
||||
@ -150,6 +151,29 @@ namespace Compression.BSA
|
||||
}
|
||||
}
|
||||
|
||||
public class BSAStateObject : ArchiveStateObject
|
||||
{
|
||||
public BSAStateObject() { }
|
||||
public BSAStateObject(BSAReader bsaReader)
|
||||
{
|
||||
Magic = bsaReader._magic;
|
||||
Version = bsaReader._version;
|
||||
ArchiveFlags = bsaReader._archiveFlags;
|
||||
FileFlags = bsaReader._fileFlags;
|
||||
|
||||
}
|
||||
|
||||
public override IBSABuilder MakeBuilder()
|
||||
{
|
||||
return new BSABuilder(this);
|
||||
}
|
||||
|
||||
public string Magic { get; set; }
|
||||
public uint Version { get; set; }
|
||||
public uint ArchiveFlags { get; set; }
|
||||
public uint FileFlags { get; set; }
|
||||
}
|
||||
|
||||
public class FolderRecord
|
||||
{
|
||||
private readonly uint _fileCount;
|
||||
@ -181,7 +205,8 @@ namespace Compression.BSA
|
||||
if (bsa.HasFolderNames) Name = src.ReadStringLen(bsa.HeaderType);
|
||||
|
||||
_files = new List<FileRecord>();
|
||||
for (var idx = 0; idx < _fileCount; idx += 1) _files.Add(new FileRecord(bsa, this, src));
|
||||
for (var idx = 0; idx < _fileCount; idx += 1)
|
||||
_files.Add(new FileRecord(bsa, this, src, idx));
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,9 +221,11 @@ namespace Compression.BSA
|
||||
private readonly uint _onDiskSize;
|
||||
private readonly uint _originalSize;
|
||||
private readonly uint _size;
|
||||
internal readonly int _index;
|
||||
|
||||
public FileRecord(BSAReader bsa, FolderRecord folderRecord, BinaryReader src)
|
||||
public FileRecord(BSAReader bsa, FolderRecord folderRecord, BinaryReader src, int index)
|
||||
{
|
||||
_index = index;
|
||||
_bsa = bsa;
|
||||
Hash = src.ReadUInt64();
|
||||
var size = src.ReadUInt32();
|
||||
@ -262,7 +289,7 @@ namespace Compression.BSA
|
||||
}
|
||||
|
||||
public uint Size => _dataSize;
|
||||
public FileStateObject State { get; }
|
||||
public FileStateObject State => new BSAFileStateObject(this);
|
||||
|
||||
public ulong Hash { get; }
|
||||
|
||||
@ -314,4 +341,18 @@ namespace Compression.BSA
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public class BSAFileStateObject : FileStateObject
|
||||
{
|
||||
public BSAFileStateObject() { }
|
||||
public BSAFileStateObject(FileRecord fileRecord)
|
||||
{
|
||||
FlipCompression = fileRecord.FlipCompression;
|
||||
Path = fileRecord.Path;
|
||||
Index = fileRecord._index;
|
||||
}
|
||||
|
||||
public bool FlipCompression { get; set; }
|
||||
public string Path { get; set; }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user