diff --git a/OpenKh.Bbs/Bbsa.cs b/OpenKh.Bbs/Bbsa.cs index 34216b5fe..9a31b7b72 100644 --- a/OpenKh.Bbs/Bbsa.cs +++ b/OpenKh.Bbs/Bbsa.cs @@ -217,6 +217,7 @@ public class Header [Data] public int Archive4Sector { get; set; } public Partition[] Partitions { get; set; } public Directory[] _directories; + public DirectoryEntry[] DirectoryEntries { get; set; } = Array.Empty(); } protected class ArchivePartitionHeader @@ -252,6 +253,14 @@ internal static Directory Read(Stream stream, int baseOffset, int x, int DirEntr return dir; } + + internal static DirectoryEntry[] ReadAll(Stream stream, int baseOffset, int DirEntriescount) + { + stream.Position = baseOffset; + + return Enumerable.Range(0, DirEntriescount) + .Select(x => DirectoryEntry.Read(stream)).ToArray(); + } } public class DirectoryEntry { @@ -290,10 +299,10 @@ protected Bbsa(Stream stream) _header.Partitions = ReadPartitions(stream, 0x30, _header.PartitionCount); ReadPartitionLba(_header.Partitions, stream, _header.PartitionOffset); + _header.DirectoryEntries = Directory.ReadAll(stream, _header.DirectoryOffset, _header.DirectoryEntriesCount); _header._directories = Enumerable.Range(0, _header.DirectoryCount) .Select(x => Directory.Read(stream, _header.DirectoryOffset, x, _header.DirectoryEntriesCount, _header.DirectoryCount)).ToArray(); - int header2Offset = _header.ArchivePartitionSector * 0x800; stream.Position = header2Offset; _header2 = BinaryMapping.ReadObject(stream); @@ -615,9 +624,38 @@ public IEnumerable Files file.Offset==0?0:GetArchiveIndex(_header, file.Offset)); } } + + foreach (var file in GetDirectoryEntryTail()) + { + NameDictionary.TryGetValue(file.FileHash, out var fileName); + NameDictionary.TryGetValue(file.DirectoryHash, out var folderName); + + yield return new Entry( + this, + file.Offset, + file.Size, + fileName, + "", + folderName, + file.FileHash, + file.DirectoryHash, + (uint)file.LocationOffset, + file.Offset==0?0:GetArchiveIndex(_header, file.Offset)); + } } } + private IEnumerable GetDirectoryEntryTail() + { + if (_header.DirectoryCount == 0) + return _header.DirectoryEntries; + + int entriesPerDirectory = _header.DirectoryEntriesCount / _header.DirectoryCount; + int groupedEntriesCount = entriesPerDirectory * _header.DirectoryCount; + + return _header.DirectoryEntries.Skip(groupedEntriesCount); + } + public int GetOffset(string fileName) { var directory = Path.GetDirectoryName(fileName).Replace('\\', '/');