Пример #1
0
        /// <summary>
        /// Extract all files from absolute path.
        /// </summary>
        /// <param name="fullpath">Absolute path to a file in a PAK archive.</param>
        public void ExtractFile(string fullpath)
        {
            string pakFilePath = Regex.Match(fullpath, ".*.pak").Value;
            string fileMatch   = Path.GetFileName(Regex.Replace(fullpath, ".*.pak", "").Trim());

            PakReader?.Dispose();
            PakReader = new PakReader(pakFilePath);
            byte[] fileBytes = PakReader.GetFile(fileMatch);
            Encdec.ConsoleInfo.LogWait(Level.Info, "{Extract} " + fileMatch);
            if (fileBytes != null)
            {
                FileInfo f = new FileInfo(Path.Combine(Program.Arguments.Input,
                                                       Path.GetFileNameWithoutExtension(pakFilePath), fileMatch).Replace("/", "\\"));
                f.Directory.Create();
                if (!File.Exists(f.FullName))
                {
                    File.WriteAllBytes(f.FullName, fileBytes);
                }
                else
                {
                    int    idx = 1;
                    string newPath;
                    while (File.Exists(newPath = Path.Combine(f.Directory.FullName,
                                                              Path.GetFileNameWithoutExtension(f.Name) + "_" + idx + f.Extension)))
                    {
                        idx++;
                    }
                    File.WriteAllBytes(newPath, fileBytes);
                }
            }
        }
Пример #2
0
 private string GetPakFileListing(string filename)
 {
     using (var pr = new PakReader(filename))
     {
         return(string.Join("\r\n", pr.Files.Keys.OrderBy(o => o)));
     }
 }
Пример #3
0
        private void PreviewFileFromPakEntryInfo(PakEntryInfo pakEntry)
        {
            using (var pr = new PakReader(pakEntry.PakFile))
            {
                switch (GetPreviewTypeFromFilename(pakEntry.EntryFilename))
                {
                case PreviewType.Text:
                    using (var ms = new MemoryStream(pr.GetFile(pakEntry.EntryFilename)))
                    {
                        var text = new StreamReader(ms).ReadToEnd();
                        ShowTextViewer(text);
                    }
                    break;

                case PreviewType.Html:
                    using (var ms = new MemoryStream(pr.GetFile(pakEntry.EntryFilename)))
                    {
                        try
                        {
                            var text = EncryptedHtml.DecodeToString(pakEntry.EntryFilename, ms);
                            ShowTextViewer(text);
                        }
                        catch {
                            // maybe not encrypted, show raw text
                            ms.Seek(0, SeekOrigin.Begin);
                            var text = new StreamReader(ms).ReadToEnd();
                            ShowTextViewer(text);
                        }
                    }
                    break;

                case PreviewType.Xml:
                    using (var ms = new MemoryStream(pr.GetFile(pakEntry.EntryFilename)))
                    {
                        var text = new StreamReader(new AionXmlStreamReader(ms, true)).ReadToEnd();
                        ShowTextViewer(text);
                    }
                    break;

                case PreviewType.Image:
                    using (var ms = new MemoryStream(pr.GetFile(pakEntry.EntryFilename)))
                    {
                        ShowImageViewer(ms);
                    }
                    break;

                case PreviewType.Cgf:
                    using (var ms = new MemoryStream(pr.GetFile(pakEntry.EntryFilename)))
                    {
                        ShowCgfViewer(new CgfLoader(ms));
                    }
                    break;

                default:
                    break;
                }
            }
        }
Пример #4
0
        private static void SaveFile(BinaryReader binaryReader, string directory, string subDirectory, PakItem item)
        {
            var path = Path.Combine(directory, subDirectory, item.Path.Substring(1));
            var dir  = Path.GetDirectoryName(path);

            Directory.CreateDirectory(dir);

            using (var fs = File.Open(path, FileMode.Create))
            {
                var bytes = PakReader.ReadItem(binaryReader, item);
                fs.Write(bytes, 0, bytes.Length);
            }
        }
Пример #5
0
        private static void ExtractPackage()
        {
            PakReader reader = null;

            try
            {
                reader = new PakReader(_pakFile);
            }
            catch (FileNotFoundException e)
            {
                _hasErrored = true;
                Console.Error.WriteLine(e.Message);
                Console.Error.WriteLine("File: '{0}'", e.FileName);
            }

            PakFile file = null;

            try
            {
                file = reader.Read();
            }
            catch (PakReaderException e)
            {
                _hasErrored = true;
                Console.Error.WriteLine(e.Message);
                Console.Error.WriteLine("Reason: {0}", e.InnerException.Message);
                return;
            }

            if (_outputDir == "")
            {
                _outputDir = Path.GetDirectoryName(_pakFile);
            }

            for (int i = 0; i < file.Entries.Count; i++)
            {
                var entry = file.Entries[i];

                entry.Extract(_outputDir);
                Console.WriteLine("[{0}/{1}] Extracted {2}", i + 1, file.Entries.Count, entry.ArchivePath);

                Thread.Sleep(10);
            }

            Console.WriteLine("Extracted all files successfully!");
        }
Пример #6
0
        // Rules:
        // - Filenames are lowercase and use backslash.
        // - Filenames include directories and are relative to the root path.
        // - .pak files are excluded from the listing since they get expanded.
        // - Files contained in .pak files take precedence over local files.
        // - The filemap maps relative paths to a PakReader. If PakReader is null, path is a local file.
        private SortedDictionary <string, PakReader> GenerateFileListing(string subpath)
        {
            var paksToLoad = new List <string>();

            // load pak names and local files
            foreach (var path in Directory.EnumerateFiles(Path.Combine(m_rootPath, subpath), "*", SearchOption.AllDirectories))
            {
                if (Path.GetExtension(path).Equals(".pak", StringComparison.OrdinalIgnoreCase))
                {
                    paksToLoad.Add(path);
                    continue;
                }

                m_fileListing.Add(GetRelativePath(path), null);
            }

            // load filenames from pak, and map each to a PakReader.
            foreach (var pak in paksToLoad)
            {
                var pr = new PakReader(pak);
                foreach (var file in pr.Files.Keys)
                {
                    string    relativePath = GetRelativePath(Path.Combine(Path.GetDirectoryName(pak), file));
                    PakReader existing;
                    if (m_fileListing.TryGetValue(relativePath, out existing))
                    {
                        if (existing == null)
                        {
                            m_fileListing[relativePath] = pr;
                        }
                        // TODO aion gamedata has colliding names... (especially in levels/common)
                        // how should that be handled? could check if models are the same. just ignoring for now...
                        //else
                        //Log.WriteLine("duplicate filename encountered: " + relativePath);
                        //throw new InvalidOperationException("duplicate filename encountered: " + relativePath);
                    }
                    else
                    {
                        m_fileListing.Add(relativePath, pr);
                    }
                }
            }

            return(m_fileListing);
        }
Пример #7
0
        /// <summary>
        /// Fetches all items in the given pak.
        /// </summary>
        /// <param name="pakPath">File path to pak.</param>
        public void Fetch(string pakPath)
        {
            using (FileStream fs = File.Open(pakPath, FileMode.Open))
                using (BinaryReader binaryReader = new BinaryReader(fs))
                {
                    PakReader reader = new PakReader();
                    PakData   pak    = reader.Read(binaryReader);

                    foreach (PakItem item in pak.Items)
                    {
                        string ext = Path.GetExtension(item.Path);
                        if (Extensions == null || Extensions.Count == 0 ||
                            ext.Length > 0 && Extensions.Contains(ext.Substring(1).ToLowerInvariant()))
                        {
                            byte[] data = PakReader.ReadItem(binaryReader, item);
                            string s    = Encoding.UTF8.GetString(data);

                            OnItemFound?.Invoke(item.Path, s);
                        }
                    }
                }
        }
Пример #8
0
        private static void Run(Options options)
        {
            var inp         = options.InputPath;
            var outp        = options.OutputPath;
            var save        = !string.IsNullOrWhiteSpace(outp) && Directory.Exists(outp);
            var pat         = options.Pattern;
            var isDirectory = Directory.Exists(inp);

            Console.WriteLine("Starbound - Asset Search");
            Console.Write("- "); Console.Write($"{(isDirectory ? "Directory" : "File")}: ".PadLeft(11));
            WriteColoredLine(ConsoleColor.Cyan, inp);
            Console.Write("- "); Console.Write("Pattern: ".PadLeft(11));
            WriteColoredLine(ConsoleColor.Cyan, pat);
            if (save)
            {
                Console.Write("- "); Console.Write("Output: ".PadLeft(11));
                WriteColoredLine(ConsoleColor.Cyan, outp);
            }

            Console.WriteLine("Starting search...");


            // Get files
            var files = isDirectory ? GetPaks(options.InputPath)
                : File.Exists(inp) ? new[] { options.InputPath }
                : null;

            if (!(files?.Length > 0))
            {
                Wait("No file(s) found.");
                return;
            }

            if (string.IsNullOrEmpty(pat))
            {
                pat = "*";
            }
            else if (!pat.Contains("/"))
            {
                pat = $"*/{pat}";
            }
            pat = $"^{pat}$";

            var pattern = new Regex(pat.Replace(".", "\\.").Replace('?', '.').Replace("*", ".*"));
            var reader  = new PakReader();

            // Scan files
            foreach (var file in files)
            {
                var fileName = Path.GetFileNameWithoutExtension(file);
                WriteColoredLine(ConsoleColor.Yellow, $"{file}");

                using (var fs = File.Open(file, FileMode.Open))
                    using (var binaryReader = new BinaryReader(fs))
                    {
                        var pak = reader.Read(binaryReader);
                        foreach (var item in pak.Items)
                        {
                            if (!pattern.IsMatch(item.Path))
                            {
                                continue;
                            }
                            Console.WriteLine($"- {item.Path}");

                            if (save)
                            {
                                SaveFile(binaryReader, outp, fileName, item);
                            }
                        }
                        ;
                    }

                //if (save)
                //WriteColoredLine();
            }

            if (options.KeepOpen)
            {
                Wait("Press any key to exit...");
            }
        }
Пример #9
0
        private void PopulatePakTreeNode(TreeNode node)
        {
            var file = node.Tag as FileInfo;

            if (file == null)
            {
                return;
            }

            var ext = Path.GetExtension(file.Name);

            if (ext.Equals(".pak", StringComparison.InvariantCultureIgnoreCase))
            {
                if (node.Nodes.Count == 1 && node.Nodes[0].Text == "Loading...")
                {
                    node.Nodes.Clear();

                    using (var pr = new PakReader(node.FullPath))
                    {
                        var filenames = pr.Files.Keys.OrderBy(o => o);

                        // collect directories
                        var subdirs = new List <string>();
                        foreach (var pakFilename in filenames)
                        {
                            var lastPathSep = pakFilename.LastIndexOf('/');
                            if (lastPathSep == -1)
                            {
                                continue;
                            }
                            subdirs.Add(pakFilename.Substring(0, lastPathSep));
                        }

                        // build the directory structure
                        var dirs = new Dictionary <string, TreeNode>();
                        foreach (var s in subdirs.Distinct().OrderBy(o => o))
                        {
                            var    curNode        = node;
                            string curFullDirName = "";
                            foreach (var dirName in s.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries))
                            {
                                curFullDirName += (curFullDirName == "" ?  "" : "/") + dirName;
                                if (curNode.Nodes.ContainsKey(dirName))
                                {
                                    curNode = curNode.Nodes[dirName];
                                    continue;
                                }
                                var dirNode = new TreeNode(dirName);
                                dirNode.Name               = dirName;
                                dirNode.ImageIndex         = 1;
                                dirNode.SelectedImageIndex = 1;
                                curNode.Nodes.Add(dirNode);
                                curNode = dirNode;

                                dirs.Add(curFullDirName, dirNode);
                            }
                        }

                        // insert the files
                        foreach (var f in filenames)
                        {
                            TreeNode dir;
                            var      fileNode  = new TreeNode();
                            var      lastSlash = f.LastIndexOf('/');
                            if (lastSlash == -1)
                            {
                                dir           = node;
                                fileNode.Text = f;
                            }
                            else
                            {
                                dir           = dirs[f.Substring(0, lastSlash)];
                                fileNode.Text = f.Substring(lastSlash + 1);
                            }
                            SetNodeIconFromFilename(fileNode, f);
                            fileNode.Tag = new PakEntryInfo {
                                PakFile = file.FullName, EntryFilename = f
                            };
                            dir.Nodes.Add(fileNode);
                        }
                    }
                }
            }
        }
Пример #10
0
        private void M_treeView_ItemDrag(object sender, ItemDragEventArgs e)
        {
            var node = e.Item as TreeNode;

            if (node == null)
            {
                return;
            }

            // TODO - drag start immediately copies the file, even if dragging within the app. should only copy if needed.
            // TODO - drag directory

            List <string> selection = new List <string>();

            string tempfile = null;
            string tempdir  = null;
            var    file     = node.Tag as FileInfo;

            if (file != null)
            {
                // just copy the file
                selection.Add(file.FullName);
            }
            else
            {
                var pei = node.Tag as PakEntryInfo;
                if (pei != null)
                {
                    if (string.IsNullOrWhiteSpace(pei.EntryFilename) || pei.EntryFilename.EndsWith("\\") ||
                        pei.EntryFilename.EndsWith("/"))
                    {
                        return;
                    }

                    tempdir  = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
                    tempfile = Path.Combine(tempdir, pei.EntryFilename.Replace("/", "\\"));
                    tempdir  = Path.GetDirectoryName(tempfile);

                    Directory.CreateDirectory(tempdir);

                    var pr = new PakReader(pei.PakFile);
                    File.WriteAllBytes(tempfile, pr.GetFile(pei.EntryFilename));
                    selection.Add(tempfile);
                }
            }

            if (!selection.Any())
            {
                return;
            }

            DataObject data = new DataObject(DataFormats.FileDrop, selection.ToArray());

            DoDragDrop(data, DragDropEffects.Copy);

            if (tempfile != null)
            {
                try
                {
                    File.Delete(tempfile);
                    Directory.Delete(tempdir);
                }
                catch { }
            }
        }
Пример #11
0
        private string MakePathRelativeToPak(string relativePath, PakReader pr)
        {
            string relativeToPak = Path.GetDirectoryName(pr.OriginalPakPath).Substring(m_rootPath.Length);

            return(relativePath.Substring(relativeToPak.Length).TrimStart(new[] { '\\', '/' }));
        }