mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
80 lines
2.4 KiB
C#
80 lines
2.4 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Wabbajack.Common;
|
|
using File = Alphaleonis.Win32.Filesystem.File;
|
|
|
|
namespace Compression.BSA
|
|
{
|
|
public class TES3Builder : IBSABuilder
|
|
{
|
|
private TES3ArchiveState _state;
|
|
private (TES3FileState state, Stream data)[] _files;
|
|
|
|
public TES3Builder(TES3ArchiveState state)
|
|
{
|
|
_state = state;
|
|
_files = new (TES3FileState state, Stream data)[_state.FileCount];
|
|
}
|
|
|
|
public async Task AddFile(FileStateObject state, Stream src)
|
|
{
|
|
var cstate = (TES3FileState)state;
|
|
_files[state.Index] = (cstate, src);
|
|
}
|
|
|
|
public async Task Build(AbsolutePath filename)
|
|
{
|
|
await using var fs = await filename.Create();
|
|
await using var bw = new BinaryWriter(fs);
|
|
|
|
bw.Write(_state.VersionNumber);
|
|
bw.Write(_state.HashOffset);
|
|
bw.Write(_state.FileCount);
|
|
|
|
foreach (var (state, _) in _files)
|
|
{
|
|
bw.Write(state.Size);
|
|
bw.Write(state.Offset);
|
|
}
|
|
|
|
foreach (var (state, _) in _files)
|
|
{
|
|
bw.Write(state.NameOffset);
|
|
}
|
|
|
|
var orgPos = bw.BaseStream.Position;
|
|
|
|
foreach (var (state, _) in _files)
|
|
{
|
|
if (bw.BaseStream.Position != orgPos + state.NameOffset)
|
|
throw new InvalidDataException("Offsets don't match when writing TES3 BSA");
|
|
bw.Write(Encoding.ASCII.GetBytes((string)state.Path));
|
|
bw.Write((byte)0);
|
|
}
|
|
|
|
bw.BaseStream.Position = _state.HashOffset + 12;
|
|
foreach (var (state, _) in _files)
|
|
{
|
|
bw.Write(state.Hash1);
|
|
bw.Write(state.Hash2);
|
|
}
|
|
|
|
if (bw.BaseStream.Position != _state.DataOffset)
|
|
throw new InvalidDataException("Data offset doesn't match when writing TES3 BSA");
|
|
|
|
foreach (var (state, data) in _files)
|
|
{
|
|
bw.BaseStream.Position = _state.DataOffset + state.Offset;
|
|
await data.CopyToAsync(bw.BaseStream);
|
|
await data.DisposeAsync();
|
|
}
|
|
}
|
|
|
|
public async ValueTask DisposeAsync()
|
|
{
|
|
}
|
|
}
|
|
}
|