private static void BuildDirectoryTree(long fileOffset, DirectoryTreeNode root, Dictionary <long, BaseRecord> recordOffsets) { if (!recordOffsets.ContainsKey(fileOffset)) { return; } if (recordOffsets[fileOffset] is DirectoryRecord) { DirectoryRecord directoryRecord = recordOffsets[fileOffset] as DirectoryRecord; DirectoryTreeNode directoryTreeNode = new DirectoryTreeNode { Name = directoryRecord.Name, Parent = root, Children = new List <DirectoryTreeNode>(), Files = new List <FileRecord>(), Record = directoryRecord }; root.Children.Add(directoryTreeNode); DirectoryRecord.DirectoryEntry[] entries = directoryRecord.Entries; for (int i = 0; i < entries.Length; i++) { DirectoryRecord.DirectoryEntry directoryEntry = entries[i]; DirectoryTreeMaker.BuildDirectoryTree(directoryEntry.Offset, directoryTreeNode, recordOffsets); } return; } if (recordOffsets[fileOffset] is FileRecord) { FileRecord fileRecord = recordOffsets[fileOffset] as FileRecord; fileRecord.ContainingDirectory = root; root.Files.Add(fileRecord); } }
/// <summary> /// Builds a directory tree by traversing the list of record headers found in the pack file /// </summary> /// <param name="recordOffsets">Map of record offsets and headers to create directory tree from</param> /// <returns>Root node of directory tree</returns> internal static DirectoryTreeNode BuildDirectoryTree(Dictionary <long, BaseRecord> recordOffsets) { // This offset is a directory, add it as a child of root and process all of it's entries GGPKRecord currentDirectory = recordOffsets[0] as GGPKRecord; DirectoryTreeNode root = new DirectoryTreeNode() { Children = new List <DirectoryTreeNode>(), Files = new List <FileRecord>(), Name = "", Parent = null, Record = null, }; // First level only contains a empty string name directory record and a free record foreach (var Offset in currentDirectory.RecordOffsets) { if (!recordOffsets.ContainsKey(Offset)) { continue; } if (recordOffsets[Offset] is DirectoryRecord) { DirectoryRecord firstDirectory = recordOffsets[Offset] as DirectoryRecord; foreach (var item in firstDirectory.Entries) { BuildDirectoryTree(item, root, recordOffsets); } } } return(root); }
/// <summary> /// Recursivly creates a directory tree by traversing PDIR records. Adds FILE records to the current directory /// tree node. Recursivly traverses PDIR records and adds them to the current directory tree node's children. /// </summary> /// <param name="directoryEntry">Directory Entry</param> /// <param name="root">Parent node</param> /// <param name="recordOffsets">Map of record offsets and headers to create directory tree from</param> private static void BuildDirectoryTree(DirectoryRecord.DirectoryEntry directoryEntry, DirectoryTreeNode root, IReadOnlyDictionary <long, BaseRecord> recordOffsets) { if (!recordOffsets.ContainsKey(directoryEntry.Offset)) { return; } var record = recordOffsets[directoryEntry.Offset] as DirectoryRecord; if (record != null) { // This offset is a directory, add it as a child of root and process all of it's entries DirectoryRecord currentDirectory = record; DirectoryTreeNode child = new DirectoryTreeNode { Name = currentDirectory.Name, Parent = root, Children = new List <DirectoryTreeNode>(), Files = new List <FileRecord>(), Record = currentDirectory, }; root.Children.Add(child); foreach (var entry in currentDirectory.Entries) { BuildDirectoryTree(entry, child, recordOffsets); } } else { var file = recordOffsets[directoryEntry.Offset] as FileRecord; if (file == null) { return; } FileRecord currentFile = file; currentFile.ContainingDirectory = root; root.Files.Add(currentFile); } }
/// <summary> /// Recursivly creates a directory tree by traversing PDIR records. Adds FILE records to the current directory /// tree node. Recursivly traverses PDIR records and adds them to the current directory tree node's children. /// </summary> /// <param name="directoryEntry">Directory Entry</param> /// <param name="root">Parent node</param> /// <param name="recordOffsets">Map of record offsets and headers to create directory tree from</param> private static void BuildDirectoryTree(DirectoryRecord.DirectoryEntry directoryEntry, DirectoryTreeNode root, Dictionary<long, BaseRecord> recordOffsets) { if (!recordOffsets.ContainsKey(directoryEntry.Offset)) { return; } if (recordOffsets[directoryEntry.Offset] is DirectoryRecord) { // This offset is a directory, add it as a child of root and process all of it's entries DirectoryRecord currentDirectory = recordOffsets[directoryEntry.Offset] as DirectoryRecord; DirectoryTreeNode child = new DirectoryTreeNode() { Name = currentDirectory.Name, Parent = root, Children = new List<DirectoryTreeNode>(), Files = new List<FileRecord>(), Record = currentDirectory, }; root.Children.Add(child); foreach (var entry in currentDirectory.Entries) { BuildDirectoryTree(entry, child, recordOffsets); } } else if (recordOffsets[directoryEntry.Offset] is FileRecord) { FileRecord currentFile = recordOffsets[directoryEntry.Offset] as FileRecord; // Skip empty .dat Files under Data/ //if (root.Name.Equals("Data") && currentFile.DataLength == 12) // return; currentFile.ContainingDirectory = root; root.Files.Add(currentFile); } }
/// <summary> /// Recursivly creates a directory tree by traversing PDIR records. Adds FILE records to the current directory /// tree node. Recursivly traverses PDIR records and adds them to the current directory tree node's children. /// </summary> /// <param name="directoryEntry">Directory Entry</param> /// <param name="root">Parent node</param> /// <param name="recordOffsets">Map of record offsets and headers to create directory tree from</param> private static void BuildDirectoryTree(DirectoryRecord.DirectoryEntry directoryEntry, DirectoryTreeNode root, Dictionary <long, BaseRecord> recordOffsets) { if (!recordOffsets.ContainsKey(directoryEntry.Offset)) { return; } if (recordOffsets[directoryEntry.Offset] is DirectoryRecord) { // This offset is a directory, add it as a child of root and process all of it's entries DirectoryRecord currentDirectory = recordOffsets[directoryEntry.Offset] as DirectoryRecord; DirectoryTreeNode child = new DirectoryTreeNode() { Name = currentDirectory.Name, Parent = root, Children = new List <DirectoryTreeNode>(), Files = new List <FileRecord>(), Record = currentDirectory, }; root.Children.Add(child); foreach (var entry in currentDirectory.Entries) { BuildDirectoryTree(entry, child, recordOffsets); } } else if (recordOffsets[directoryEntry.Offset] is FileRecord) { FileRecord currentFile = recordOffsets[directoryEntry.Offset] as FileRecord; // Skip empty .dat Files under Data/ //if (root.Name.Equals("Data") && currentFile.DataLength == 12) // return; currentFile.ContainingDirectory = root; root.Files.Add(currentFile); } }
public void SerializeRecords(string pathToBin, Action <string> output) { if (output != null) { output(Environment.NewLine); output("Serializing... "); } var Serialized = File.Create(pathToBin); var s = new BinaryWriter(Serialized); foreach (var record in RecordOffsets) { s.Write(record.Key); var baseRecord = record.Value; if (baseRecord is FileRecord) { s.Write((byte)1); FileRecord fr = (FileRecord)baseRecord; s.Write(fr.RecordBegin); s.Write(fr.Length); s.Write(fr.Hash); s.Write(fr.Name); s.Write(fr.DataBegin); s.Write(fr.DataLength); } else if (baseRecord is GgpkRecord) { s.Write((byte)2); GgpkRecord gr = (GgpkRecord)baseRecord; s.Write(gr.RecordBegin); s.Write(gr.Length); s.Write(gr.RecordOffsets.Length); foreach (long l in gr.RecordOffsets) { s.Write(l); } } else if (baseRecord is FreeRecord) { s.Write((byte)3); FreeRecord fr = (FreeRecord)baseRecord; s.Write(fr.RecordBegin); s.Write(fr.Length); s.Write(fr.NextFreeOffset); } else if (baseRecord is DirectoryRecord) { s.Write((byte)4); DirectoryRecord dr = (DirectoryRecord)baseRecord; s.Write(dr.RecordBegin); s.Write(dr.Length); s.Write(dr.Hash); s.Write(dr.Name); s.Write(dr.EntriesBegin); s.Write(dr.Entries.Count); foreach (var directoryEntry in dr.Entries) { s.Write(directoryEntry.EntryNameHash); s.Write(directoryEntry.Offset); } } } Serialized.Flush(); Serialized.Close(); output?.Invoke("Done!" + Environment.NewLine); }