Beispiel #1
0
        public void UnpackFromKey(FileEntryKey entryKey)
        {
            string entryPath = _volume.GetEntryPath(entryKey, ParentDirectory);

            if (string.IsNullOrEmpty(entryPath))
            {
                Program.Log($"Could not determine entry path for Entry key at name Index {entryKey.NameIndex}");
                return;
            }

            string fullEntryPath = Path.Combine(OutDir ?? string.Empty, entryPath);

            if (entryKey.Flags.HasFlag(EntryKeyFlags.Directory))
            {
                if (_fileIndexesToExtract.Count == 0) // Make sure not to spam when not needed
                {
                    if (!_volume.IsPatchVolume || _volume.NoUnpack)
                    {
                        Program.Log($"[:] Entering Directory: {entryPath}");
                    }
                }

                var childEntryBTree = new FileEntryBTree(_volume.TableOfContents.Data, (int)_volume.TableOfContents.RootAndFolderOffsets[(int)entryKey.EntryIndex]);
                var childUnpacker   = new EntryUnpacker(_volume, OutDir, entryPath, _fileIndexesToExtract);
                childEntryBTree.TraverseAndUnpack(childUnpacker);
            }
            else
            {
                if (_fileIndexesToExtract.Count != 0 && !_fileIndexesToExtract.Contains((int)entryKey.EntryIndex))
                {
                    return;
                }

                if (!_volume.IsPatchVolume || _volume.NoUnpack)
                {
                    Program.Log($"[:] Extracting: {entryPath}");
                }

                var nodeBTree = new FileInfoBTree(_volume.TableOfContents.Data, (int)_volume.TableOfContents.NodeTreeOffset);
                var nodeKey   = new FileInfoKey(entryKey.EntryIndex);

                uint nodeIndex = nodeBTree.SearchIndexByKey(nodeKey);

                if (nodeIndex != FileInfoKey.InvalidIndex)
                {
                    _volume.UnpackNode(nodeKey, fullEntryPath);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Loads the table of contents from the underlaying stream.
        /// </summary>
        /// <returns></returns>
        public bool LoadTOC()
        {
            var sr = new SpanReader(Data, Endian.Big);

            byte[] magic = sr.ReadBytes(4);
            if (!magic.AsSpan().SequenceEqual(SEGMENT_MAGIC.AsSpan()))
            {
                Program.Log($"Volume TOC magic did not match, found ({string.Join('-', magic.Select(e => e.ToString("X2")))})");
                return(false);
            }

            NameTreeOffset          = sr.ReadUInt32();
            FileExtensionTreeOffset = sr.ReadUInt32();
            NodeTreeOffset          = sr.ReadUInt32();
            uint entryTreeCount = sr.ReadUInt32();

            RootAndFolderOffsets = new List <uint>((int)entryTreeCount);
            for (int i = 0; i < entryTreeCount; i++)
            {
                RootAndFolderOffsets.Add(sr.ReadUInt32());
            }


            FileNames = new StringBTree(Data, (int)NameTreeOffset);
            FileNames.LoadEntries();

            Extensions = new StringBTree(Data, (int)FileExtensionTreeOffset);
            Extensions.LoadEntries();

            FileInfos = new FileInfoBTree(Data, (int)NodeTreeOffset);
            FileInfos.LoadEntries();

            Files = new List <FileEntryBTree>((int)entryTreeCount);

            for (int i = 0; i < entryTreeCount; i++)
            {
                Files.Add(new FileEntryBTree(Data, (int)RootAndFolderOffsets[i]));
                Files[i].LoadEntries();
            }

            return(true);
        }