private Directory BuildContentTree(Stream stream, GENESTRT nameTable, PACKTOC toc, PACKTOC.DirectoryEntry dirEnt) { Directory dir = new Directory(nameTable.Strings[(int)dirEnt.NameIndex]); for (uint i = dirEnt.FirstEntryIndex; i < dirEnt.FirstEntryIndex + dirEnt.NumEntries; i++) { PACKTOC.Entry entry = toc.Entries[(int)i]; string name = nameTable.Strings[(int)entry.NameIndex]; if (entry is PACKTOC.UncompressedFileEntry uFileEntry) { byte[] rawData = new byte[uFileEntry.Size]; stream.Seek((long)uFileEntry.Offset, SeekOrigin.Begin); stream.Read(rawData); dir.Children.Add(new File(name, rawData, false, uFileEntry.Size)); } else if (entry is PACKTOC.DirectoryEntry directoryEntry) { dir.Children.Add(this.BuildContentTree(stream, nameTable, toc, directoryEntry)); } else if (entry is PACKTOC.CompressedFileEntry cFileEntry) { byte[] rawData = new byte[cFileEntry.CompressedSize]; stream.Seek((long)cFileEntry.Offset, SeekOrigin.Begin); stream.Read(rawData); dir.Children.Add(new File(name, rawData, true, cFileEntry.UncompressedSize)); } } return(dir); }
private void WriteFiles(Stream stream, PACKTOC toc, GENESTRT nameTable) { List <Node> nodes = this.FlattenTree(this.RootDirectory); for (uint i = 0; i < nodes.Count; i++) { Node node = nodes[(int)i]; if (node is Directory dir) { PACKTOC.DirectoryEntry entry = new PACKTOC.DirectoryEntry(); entry.NameIndex = nameTable.AddString(node.Name); entry.PackageIndex = 0; entry.FirstEntryIndex = 0; entry.NumEntries = 0; for (uint j = i + 1; j < nodes.Count; j++) { Node node2 = nodes[(int)j]; if (dir.Children.Contains(node2)) { if (entry.FirstEntryIndex == 0) { entry.FirstEntryIndex = j; } entry.NumEntries++; } } toc.Entries.Add(entry); } else if (node is File file) { if (file.Compressed) { PACKTOC.CompressedFileEntry entry = new PACKTOC.CompressedFileEntry(); entry.NameIndex = nameTable.AddString(node.Name); entry.PackageIndex = 0; entry.Offset = 0; // Filled in later. entry.UncompressedSize = file.UncompressedSize; entry.CompressedSize = (ulong)file.RawData.Length; toc.Entries.Add(entry); } else { PACKTOC.UncompressedFileEntry entry = new PACKTOC.UncompressedFileEntry(); entry.NameIndex = nameTable.AddString(node.Name); entry.PackageIndex = 0; entry.Offset = 0; // Filled in later. entry.Size = (ulong)file.RawData.Length; toc.Entries.Add(entry); } stream.Write(file.RawData); stream.PadTo(0x200); } } }