more bug fixes, can recompress 3DNPCs and a bunch of other BSAs

This commit is contained in:
Timothy Baldridge 2019-07-29 15:24:05 -06:00
parent 8facc9a1f4
commit 39e1a20741
4 changed files with 97 additions and 7 deletions

View File

@ -45,6 +45,14 @@ namespace Compression.BSA.Test
w.Build("c:\\tmp\\built.bsa");
Equal(a.Files.Count(), w.Files.Count());
Equal(a.Files.Select(f => f.Path).ToHashSet(), w.Files.Select(f => f.Path).ToHashSet());
foreach (var pair in Enumerable.Zip(a.Files, w.Files, (ai, bi) => (ai, bi)))
{
Equal(pair.ai.Path, pair.bi.Path);
}
}
using (var b = new BSAReader("c:\\tmp\\built.bsa"))
@ -59,11 +67,11 @@ namespace Compression.BSA.Test
foreach (var pair in Enumerable.Zip(a.Files, b.Files, (ai, bi) => (ai, bi)))
{
idx ++;
Console.WriteLine($" - {pair.ai.Path}");
//Console.WriteLine($" - {pair.ai.Path}");
Equal(pair.ai.Path, pair.bi.Path);
Equal(pair.ai.Compressed, pair.bi.Compressed);
Equal(pair.ai.Size, pair.bi.Size);
//Equal(pair.ai.GetData(), pair.bi.GetData());
Equal(pair.ai.GetData(), pair.bi.GetData());
}
}
@ -72,6 +80,19 @@ namespace Compression.BSA.Test
}
}
private static void Equal(HashSet<string> a, HashSet<string> b)
{
Equal(a.Count, b.Count);
foreach (var itm in a)
Equal(b.Contains(itm));
}
private static void Equal(bool v)
{
if (!v) throw new InvalidDataException("False");
}
public static void Equal(uint a, uint b)
{

View File

@ -30,6 +30,14 @@ namespace Compression.BSA
_offset = 0x24;
}
public IEnumerable<FileEntry> Files
{
get
{
return _files;
}
}
public ArchiveFlags ArchiveFlags
{
get
@ -193,6 +201,7 @@ namespace Compression.BSA
public class FolderRecordBuilder
{
internal IEnumerable<FileEntry> _files;
private string _name;
internal BSABuilder _bsa;
internal ulong _hash;
internal uint _fileCount;
@ -200,6 +209,22 @@ namespace Compression.BSA
internal uint _recordSize;
internal ulong _offset;
public ulong Hash
{
get
{
return _hash;
}
}
public string Name
{
get
{
return _name;
}
}
public ulong SelfSize
{
get
@ -230,8 +255,10 @@ namespace Compression.BSA
public FolderRecordBuilder(BSABuilder bsa, string folderName, IEnumerable<FileEntry> files)
{
_files = files.OrderBy(f => f._hash);
_name = folderName.ToLowerInvariant();
_bsa = bsa;
_hash = folderName.GetBSAHash();
// Folders don't have extensions, so let's make sure we cut it out
_hash = _name.GetBSAHash("");
_fileCount = (uint)files.Count();
_nameBytes = folderName.ToBZString();
_recordSize = sizeof(ulong) + sizeof(uint) + sizeof(uint);
@ -299,9 +326,11 @@ namespace Compression.BSA
if (_bsa.HeaderType == VersionType.SSE)
{
var r = new MemoryStream();
var w = LZ4Stream.Encode(r);
using (var w = LZ4Stream.Encode(r))
(new MemoryStream(_rawData)).CopyTo(w);
_rawData = r.ToArray();
}
}
@ -336,6 +365,20 @@ namespace Compression.BSA
}
}
public ulong Hash { get
{
return _hash;
}
}
public FolderRecordBuilder Folder
{
get
{
return _folder;
}
}
internal void WriteFileRecord(BinaryWriter wtr)
{

View File

@ -218,6 +218,13 @@ namespace Compression.BSA
}
public string Name { get; private set; }
public ulong Hash
{
get
{
return _nameHash;
}
}
internal void LoadFileRecordBlock(BSAReader bsa, BinaryReader src)
{
@ -294,6 +301,21 @@ namespace Compression.BSA
}
}
public ulong Hash {
get
{
return _hash;
}
}
public FolderRecord Folder
{
get
{
return _folder;
}
}
public void CopyDataTo(Stream output)
{
using (var in_file = File.OpenRead(_bsa._fileName))
@ -314,6 +336,10 @@ namespace Compression.BSA
var original_size = rdr.ReadUInt32();
if (_bsa.HeaderType == VersionType.SSE)
{
var settings = new LZ4DecoderSettings()
{
ExtraMemory = 1024 * 1024 * 8
};
var r = LZ4Stream.Decode(rdr.BaseStream);
r.CopyTo(output);
}

View File

@ -80,7 +80,7 @@ namespace Compression.BSA
return GetBSAHash(Path.ChangeExtension(name, null), Path.GetExtension(name));
}
private static ulong GetBSAHash(string name, string ext)
public static ulong GetBSAHash(this string name, string ext)
{
name = name.ToLowerInvariant();
ext = ext.ToLowerInvariant();