Exemplo n.º 1
0
        /// <summary>
        /// Create a element of the TreeView
        /// </summary>
        public TreeViewItem CreateNode(RecordTreeNode rtn)
        {
            var tvi = new TreeViewItem {
                Tag = rtn
            };
            var stack = new StackPanel {
                Orientation = Orientation.Horizontal
            };

            stack.Children.Add(new Image // Icon
            {
                Source = rtn is IFileRecord ? IconFile : IconDir,
                Width  = 20,
                Height = 20,
                Margin = new Thickness(0, 0, 2, 0)
            });
            stack.Children.Add(new TextBlock {
                Text = rtn.Name, FontSize = 16
            });                                                                   // File/Directory Name
            tvi.Header = stack;
            if (!(rtn is IFileRecord))
            {
                tvi.Items.Add("Loading . . ."); // Add expand button
            }
            tvi.ContextMenu = TreeMenu;
            return(tvi);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Find the record with a <paramref name="path"/>
        /// </summary>
        /// <param name="path">Path in GGPK under <paramref name="parent"/></param>
        /// <param name="parent">Where to start searching, null for ROOT directory in GGPK</param>
        /// <returns>null if not found</returns>
        public virtual RecordTreeNode FindRecord(string path, RecordTreeNode parent = null)
        {
            parent ??= rootDirectory;
            var SplittedPath = path.Split('/', '\\');

            foreach (var name in SplittedPath)
            {
                var next = parent.GetChildItem(name);
                if (next == null)
                {
                    return(null);
                }
                parent = next;
            }
            return(parent);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Find the record with a <paramref name="path"/>
        /// <param name="path">Path in GGPK from <paramref name="parent"/></param>
        /// <param name="parent">null for ROOT directory in GGPK</param>
        /// </summary>
        public virtual RecordTreeNode FindRecord(string path, RecordTreeNode parent = null)
        {
            var SplittedPath = Regex.Replace(path, @"^ROOT(/|\\)", "").Split('/', '\\');

            parent ??= rootDirectory;
            foreach (var name in SplittedPath)
            {
                var next = parent.GetChildItem(name);
                if (next == null)
                {
                    return(null);
                }
                parent = next;
            }
            return(parent);
        }
Exemplo n.º 4
0
 /// <summary>
 /// Get the file list under a node
 /// </summary>
 /// <param name="record">File/Directory Record</param>
 /// <param name="list">File list (use <see cref="BundleSortComparer"/> when reading)</param>
 /// <param name="regex">Regular Expression for filtering files by their path</param>
 public static void RecursiveFileList(RecordTreeNode record, ICollection <IFileRecord> list, string regex = null)
 {
     if (record is IFileRecord fr)
     {
         if (regex == null || Regex.IsMatch(record.GetPath(), regex))
         {
             list.Add(fr);
         }
     }
     else
     {
         foreach (var f in record.Children)
         {
             RecursiveFileList(f, list, regex);
         }
     }
 }
Exemplo n.º 5
0
 /// <summary>
 /// Get the file list under a node to export/replace
 /// </summary>
 /// <param name="record">File/Directory Record to export</param>
 /// <param name="path">Path to save</param>
 /// <param name="list">File list (use <see cref="BundleSortComparer"/> when reading)</param>
 /// <param name="export">True for export False for replace</param>
 /// <param name="regex">Regular Expression for filtering files by their path</param>
 public static void RecursiveFileList(RecordTreeNode record, string path, ICollection <KeyValuePair <IFileRecord, string> > list, bool export, string regex = null)
 {
     if (record is IFileRecord fr)
     {
         if ((export || File.Exists(path)) && (regex == null || Regex.IsMatch(record.GetPath(), regex)))
         {
             list.Add(new(fr, path));
         }
     }
     else
     {
         foreach (var f in record.Children)
         {
             RecursiveFileList(f, path + "\\" + f.Name, list, export, regex);
         }
     }
 }
Exemplo n.º 6
0
        public virtual void BuildBundleTree(LibBundle.Records.FileRecord fr, RecordTreeNode parent)
        {
            var SplittedPath = fr.path.Split('/');
            var path         = "";

            for (var i = 0; i < SplittedPath.Length; i++)
            {
                var name         = SplittedPath[i];
                var isFile       = (i + 1 == SplittedPath.Length);
                var parentOfFile = (i + 2 == SplittedPath.Length);
                var next         = parent.GetChildItem(name);
                path += name;
                if (!isFile)
                {
                    path += "/";
                }
                if (next == null)
                { // No exist node, Build a new node
                    if (isFile)
                    {
                        next = new BundleFileNode(name, fr, this);
                    }
                    else if (parentOfFile)
                    {
                        next = new BundleDirectoryNode(name, path, fr.parent.NameHash, fr.parent.Offset, fr.parent.Size, this);
                    }
                    else
                    {
                        next = new BundleDirectoryNode(name, path, 0, 0, 0, this);
                    }
                    parent.Children.Add(next);
                    next.Parent = parent;
                }
                else if (parentOfFile && next.Offset == 0)
                {
                    ((BundleDirectoryNode)next).Hash = fr.parent.NameHash;
                    next.Offset = fr.parent.Offset;
                    next.Length = fr.parent.Size;
                }
                parent = next;
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Find the record with a <paramref name="path"/>
        /// </summary>
        public RecordTreeNode FindRecord(string path, RecordTreeNode parent = null)
        {
            var SplittedPath = path.Split(new char[] { '/', '\\' });

            if (parent == null)
            {
                parent = rootDirectory;
            }
            for (int i = 0; i < SplittedPath.Length; i++)
            {
                var name = SplittedPath[i];
                var next = parent.GetChildItem(name);
                if (next == null)
                {
                    return(null);
                }
                parent = next;
            }
            return(parent);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Load GGPK
        /// </summary>
        /// <param name="path">Path to GGPK file</param>
        public GGPKContainer(string path, bool BundleMode = false, bool SteamMode = false, bool BuildTree = true)
        {
            // Steam Mode (No GGPK)
            if (SteamMode)
            {
                if (BundleMode)
                {
                    throw new NotSupportedException("BundleMode and SteamMode cannot be both true");
                }
                Environment.CurrentDirectory = Directory.GetParent(path).FullName;
                Index = new IndexContainer(path);
                if (BuildTree)
                {
                    rootDirectory = FakeBundles2 = new BundleDirectoryNode("Bundles2", "", MurmurHash2Unsafe.Hash("bundles2", 0), 0, 0, this);
                    foreach (var f in Index.Files)
                    {
                        BuildBundleTree(f, rootDirectory);
                    }
                }
                return;
            }

            // Open File
            fileStream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
            Reader     = new BinaryReader(fileStream);
            Writer     = new BinaryWriter(fileStream);

            // Read ROOT Directory Record
            BaseRecord ggpk;

            while ((ggpk = GetRecord()) is not GGPKRecord)
            {
                ;
            }
            ggpkRecord         = ggpk as GGPKRecord;
            rootDirectory      = GetRecord(ggpkRecord.RootDirectoryOffset) as DirectoryRecord;
            rootDirectory.Name = "ROOT";

            // Build Linked FreeRecord List
            LinkedFreeRecords = new LinkedList <FreeRecord>();
            var NextFreeOffset = ggpkRecord.FirstFreeRecordOffset;

            while (NextFreeOffset > 0)
            {
                FreeRecord current = GetRecord(NextFreeOffset) as FreeRecord;
                LinkedFreeRecords.AddLast(current);
                NextFreeOffset = current.NextFreeOffset;
            }

            // Read Bundles
            OriginalBundles2 = rootDirectory.Children.FirstOrDefault(d => d.GetNameHash() == MurmurHash2Unsafe.Hash("bundles2", 0)) as DirectoryRecord;
            if (OriginalBundles2?.Children.FirstOrDefault(r => r.Name == "_.index.bin") is FileRecord _index)
            {
                IndexRecord = _index;
                if (BundleMode)
                {
                    return;
                }
                fileStream.Seek(_index.DataBegin, SeekOrigin.Begin);
                Index = new IndexContainer(Reader);
                if (BuildTree)
                {
                    FakeBundles2 = new BundleDirectoryNode("Bundles2", "", MurmurHash2Unsafe.Hash("bundles2", 0), (int)OriginalBundles2.Offset, OriginalBundles2.Length, this);
                    rootDirectory.Children.Remove(OriginalBundles2);
                    rootDirectory.Children.Add(FakeBundles2);
                    foreach (var f in Index.Files)
                    {
                        BuildBundleTree(f, FakeBundles2);
                    }
                }
                _RecordOfBundle = new Dictionary <LibBundle.Records.BundleRecord, FileRecord>(Index.Bundles.Length);
            } // else BundleMode = true;
        }