/// <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> private void BuildDirectoryTree(DirectoryRecord.DirectoryEntry directoryEntry, DirectoryTreeNode root) { if (!RecordOffsets.ContainsKey(directoryEntry.Offset)) { return; // TODO throw error } 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 var currentDirectory = RecordOffsets[directoryEntry.Offset] as DirectoryRecord; _directories.Add(currentDirectory); var 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); } } else if (RecordOffsets[directoryEntry.Offset] is FileRecord) { var currentFile = RecordOffsets[directoryEntry.Offset] as FileRecord; _files.Add(currentFile); currentFile.ContainingDirectory = root; root.Files.Add(currentFile); } }
/// <summary> /// Builds a linked list of FREE records by traversing FREE records in GGPK file /// </summary> /// <returns>Linked list containing list of FREE records</returns> private LinkedList <FreeRecord> BuildFreeList() { var ggpkRecord = RecordOffsets[0] as GgpkRecord; if (ggpkRecord == null) { throw new Exception("First record isn't GGPK record"); } // First level only contains a empty string name directory record and a free record var firstFreeRecordOffset = ggpkRecord.RecordOffsets .Where(RecordOffsets.ContainsKey).FirstOrDefault(o => RecordOffsets[o] is FreeRecord); if (firstFreeRecordOffset == 0) // default value { throw new Exception("Couldn't find first FREE record offset"); } var currentFreeRecord = RecordOffsets[firstFreeRecordOffset] as FreeRecord; if (currentFreeRecord == null) { throw new Exception("Couldn't find first FREE record"); } var freeList = new LinkedList <FreeRecord>(); while (true) { freeList.AddLast(currentFreeRecord); _freeRecords.Add(currentFreeRecord); var nextFreeOFfset = currentFreeRecord.NextFreeOffset; if (nextFreeOFfset == 0) { break; } if (!RecordOffsets.ContainsKey(nextFreeOFfset)) { throw new Exception("Failed to find next FREE record in map of record offsets"); } currentFreeRecord = RecordOffsets[currentFreeRecord.NextFreeOffset] as FreeRecord; if (currentFreeRecord == null) { throw new Exception("Found a record that wasn't a FREE record while looking for next FREE record"); } } return(freeList); }