示例#1
0
        /// <summary>
        /// Extract all files from PBO.
        /// Will extract to extractionDir if specified.
        /// If not will output in the current Dir of the PBO
        /// </summary>
        /// <param name="pbo"></param>
        /// <param name="path"></param>
        public void ExtractAll(PBO pbo, string extractionDir = null)
        {
            try
            {
                PushOnEvent($"Starting full extraction of {pbo.LongName}", EventType.Debug);

                //Get outoput dir depending on if extractionDir was passed
                string outputDir = extractionDir ?? Path.GetDirectoryName(pbo.LongName);

                //Run through each file in the PBO and write to disk
                foreach (PBOFile file in pbo.Files)
                {
                    //Calculate file name
                    string fileName = Path.Combine(outputDir, file.FileName);

                    //Write to disk
                    WriteToFile(fileName, ExtractFileData(file));
                }

                PushOnEvent($"Successfully extracted {pbo.LongName}", EventType.Debug);
            }
            catch (Exception ex)
            {
                PushOnEvent($"Failed to extract {pbo.LongName}\n{ex.Message}", EventType.Error);
            }
        }
示例#2
0
        internal void ReadHeader(PBO pbo)
        {
            try
            {
                _client.PushOnEvent($"Starting Header Read for {pbo.LongName}", EventType.Debug);

                //Get the signature
                PBOFile sig = ReadDatablock();

                //_client.PushOnEvent($"Signature read Packing Method: {sig.PackingMethod}", EventType.Debug);

                //Look for a prefix
                if (sig.PackingMethod == PackingMethod.Product)
                {
                    string possiblePrefix;
                    do
                    {
                        possiblePrefix = ReadString();
                        if (possiblePrefix != string.Empty)
                        {
                            pbo.Prefix = new PBOPrefix(possiblePrefix, ReadString());
                        }
                    } while (possiblePrefix != string.Empty);
                }

                //Read all file header structs
                PBOFile file;
                do
                {
                    file = ReadDatablock();
                    if (file.FileName != string.Empty)
                    {
                        pbo.Files.Add(file);
                        _client.PushOnEvent($"File found: {file.FileName}", EventType.Info);
                    }
                } while (file.FileName != string.Empty);

                //Update the file offsets for each file
                foreach (PBOFile pbofile in pbo.Files)
                {
                    pbofile.Offset       = BaseStream.Position;
                    BaseStream.Position += pbofile.DataSize;
                }

                _client.PushOnEvent($"Header read successfully from {pbo.LongName}", EventType.Debug);
            }
            catch (Exception ex)
            {
                _client.PushOnEvent($"Failed to read header for {pbo.LongName}\n {ex.Message}", EventType.Error);
            }
        }
示例#3
0
        private static void ExtractPbo(string pboFile, string outputFolder, IEnumerable <string> ignorePrefixes, bool minify)
        {
            var pboArchive = new PBO(pboFile, true);

            if (pboArchive.Prefix == null)
            {
                Console.WriteLine($"{pboArchive.FileName} has no prefix");
                return;
            }

            foreach (var ignorePrefix in ignorePrefixes)
            {
                if (pboArchive.Prefix.Contains(ignorePrefix))
                {
                    return;
                }
            }

            Console.WriteLine($"Extracting {pboArchive.FileName}");

            var pboDirectoryPath = Path.Join(outputFolder, ConvertPathSeparator(pboArchive.Prefix));

            if (!minify)
            {
                pboArchive.ExtractFiles(pboArchive.FileEntries, outputFolder);
                return;
            }

            var allowedEntries  = pboArchive.FileEntries.Where(IsAllowedFile);
            var minifiedEntries = pboArchive.FileEntries.Except(allowedEntries);

            pboArchive.ExtractFiles(allowedEntries, pboDirectoryPath);

            foreach (var ignoredEntry in minifiedEntries)
            {
                var filename = Path.Join(pboDirectoryPath, ConvertPathSeparator(ignoredEntry.FileName));
                Directory.CreateDirectory(Path.GetDirectoryName(filename));
                File.Create(filename).Dispose();
            }
        }
示例#4
0
        /// <summary>
        /// Extract all files from PBO.
        /// Will extract to extractionDir if specified.
        /// If not will output in the current Dir of the PBO
        /// </summary>
        /// <param name="pbo"></param>
        /// <param name="path"></param>
        public void ExtractAll(string filePath, string extractionDir = null)
        {
            if (!File.Exists(filePath))
            {
                PushOnEvent($"File {filePath} does not exist", EventType.Error);
                return;
            }

            PBO pbo = AnalyzePBO(filePath);

            try
            {
                PushOnEvent($"Starting full extraction of {pbo.LongName}", EventType.Debug);

                //Get outoput dir depending on if extractionDir was passed
                string outputDir = extractionDir ?? Path.GetDirectoryName(pbo.LongName);

                if (pbo.Prefix != null)
                {
                    WriteToFile($"{outputDir}\\${pbo.Prefix.PrefixName.ToUpper()}$", Encoding.ASCII.GetBytes(pbo.Prefix.PrefixValue));
                }

                //Run through each file in the PBO and write to disk
                foreach (PBOFile file in pbo.Files)
                {
                    //Calculate file name
                    string fileName = Path.Combine(outputDir, file.FileName);

                    //Write to disk
                    WriteToFile(fileName, ExtractFileData(file));
                }

                PushOnEvent($"Successfully extracted {pbo.LongName}", EventType.Debug);
            }
            catch (Exception ex)
            {
                PushOnEvent($"Failed to extract {pbo.LongName}\n{ex.Message}", EventType.Error);
            }
        }
示例#5
0
        /// <summary>
        /// Analyzes the contents of the PBO File and returns it as a PBO object
        /// </summary>
        /// <param name="File"></param>
        public PBO AnalyzePBO(string file)
        {
            try
            {
                PushOnEvent("AnalyzePBO Started", EventType.Debug);

                //Create A PBO object to store all the PBO's attributes
                PBO pbo = new PBO();

                pbo.LongName = file;

                pbo.ShortName = Path.GetFileName(file);

                //Open FileStream
                FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read);

                //Create new instance of PBOReader
                PBOReader _reader = new PBOReader(stream, this);

                //Assign Reader
                pbo.Reader = _reader;

                //Read the header
                _reader.ReadHeader(pbo);

                //Set analysed flag
                pbo.PBOAnalysed = true;

                PushOnEvent("AnalyzePBO Finished", EventType.Debug);

                //Return object
                return(pbo);
            }
            catch (Exception ex)
            {
                PushOnEvent(ex.Message, EventType.Error);
                return(null);
            }
        }
示例#6
0
        static void Main(string[] args)
        {
            //New PBOToolsClient instance
            PBOSharpClient client = new PBOSharpClient();

            //Assign EH
            client.onEvent += Client_onEvent;

            //AnalyzePBO
            PBO pbo = client.AnalyzePBO($"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}\\Workspace\\MyMission.Altis.pbo");

            //Extract with PBO object
            //client.ExtractAll(pbo, $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}\\PBOOutput");

            //Extract with file path
            //client.ExtractAll($"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}\\Workspace\\MyMission.Altis.pbo");

            //client.PackPBO(
            //    $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}\\PBOOutput\\MyMission.Altis",
            //    $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}\\PBOOutput",
            //    "MyMission.Altis.pbo");

            //Extract specific files data
            //byte[] fileData = client.ExtractFileData(pbo.Files[0]);

            //Access list of all files within the pbo
            //pbo.Files

            //Access file data attributes
            //pbo.Files[0].FileName
            //pbo.Files[0].FileNameShort
            //pbo.Files[0].PackingMethod
            //pbo.Files[0].OriginalSize
            //pbo.Files[0].Reserved
            //pbo.Files[0].Timestamp
            //pbo.Files[0].DataSize
            //pbo.Files[0].Offset
        }
示例#7
0
        private static int Dependencies(DependenciesOptions opts)
        {
            if (string.IsNullOrEmpty(opts.ModsBasePath))
            {
                opts.ModsBasePath = @"C:\Program Files (x86)\Steam\steamapps\common\Arma 3\!Workshop";
            }
            Console.WriteLine($"Build index of mods pbo and files from '{opts.ModsBasePath}'");
            var mods     = Directory.GetDirectories(opts.ModsBasePath);
            var modsData = new List <ModInfo>();

            foreach (var mod in mods)
            {
                var path = Path.Combine(mod, "addons");
                if (Directory.Exists(path))
                {
                    var infos = new ModInfo();
                    infos.Path = mod;
                    infos.Pbos = new List <PboInfo>();
                    var allPBOs = Directory.GetFiles(Path.Combine(mod, "addons"), "*.pbo");
                    foreach (var pboPath in allPBOs)
                    {
                        var pbo      = new PBO(pboPath);
                        var pboInfos = new PboInfo();
                        pboInfos.Mod   = infos;
                        pboInfos.Path  = pboPath;
                        pboInfos.Files = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                        foreach (var entry in pbo.FileEntries)
                        {
                            if (string.Equals(Path.GetExtension(entry.FileName), ".p3d", StringComparison.OrdinalIgnoreCase))
                            {
                                pboInfos.Files.Add(Path.Combine(pbo.Prefix, entry.FileName));
                            }
                        }
                        if (pboInfos.Files.Count > 0)
                        {
                            infos.Pbos.Add(pboInfos);
                        }
                    }
                    if (infos.Pbos.Count > 0)
                    {
                        infos.WorkshopId = GetWorkshopId(mod);
                        modsData.Add(infos);
                    }
                }
            }

            var allPbos = modsData.SelectMany(m => m.Pbos);

            Console.WriteLine($"Read WRP from '{opts.Source}'");
            var source = StreamHelper.Read <AnyWrp>(opts.Source);

            Console.WriteLine("Compute model list");
            var models = source.GetEditableWrp().GetNonDummyObjects().Select(e => e.Model).Distinct().ToHashSet(StringComparer.OrdinalIgnoreCase);

            var usedPbo = new HashSet <PboInfo>();

            foreach (var model in models)
            {
                if (!model.StartsWith("a3\\"))
                {
                    var pbo = allPbos.FirstOrDefault(p => p.Files.Contains(model));
                    if (pbo != null)
                    {
                        usedPbo.Add(pbo);
                    }
                    else
                    {
                        Console.Error.WriteLine($"Model '{model}' was not found.");
                    }
                }
            }

            var usedMods = usedPbo.GroupBy(p => p.Mod).Select(m => new ModInfo()
            {
                Path       = m.Key.Path,
                WorkshopId = m.Key.WorkshopId,
                Pbos       = m.Select(p => new PboInfo()
                {
                    Path  = p.Path,
                    Files = p.Files.Where(f => models.Contains(f)).ToHashSet(StringComparer.OrdinalIgnoreCase)
                }).ToList()
            }).ToList();

            if (string.IsNullOrEmpty(opts.ReportFile))
            {
                opts.ReportFile = Path.ChangeExtension(opts.Source, ".txt");
            }

            Console.WriteLine($"Write full report to '{opts.ReportFile}'");
            using (var writer = new StreamWriter(opts.ReportFile, false))
            {
                foreach (var mod in usedMods)
                {
                    Console.WriteLine($"  Depends on '{Path.GetFileName(mod.Path)}' (Workshop #{mod.WorkshopId})");
                    writer.WriteLine($"Depends on '{Path.GetFileName(mod.Path)}'");
                    writer.WriteLine($"   Workshop #{mod.WorkshopId}");
                    writer.WriteLine($"   '{mod.Path}')");
                    foreach (var pbo in mod.Pbos)
                    {
                        writer.WriteLine($"  Content from '{Path.GetFileName(pbo.Path)}'");
                        foreach (var file in pbo.Files)
                        {
                            writer.WriteLine($"    '{file}'");
                        }
                        writer.WriteLine();
                    }
                    writer.WriteLine();
                    writer.WriteLine();
                }

                writer.WriteLine($"Project drive minimal setup (using bankrev)");
                foreach (var mod in usedMods)
                {
                    foreach (var pbo in mod.Pbos)
                    {
                        writer.WriteLine($@"  bankrev -f ""P:"" -prefix ""{pbo.Path}"" ");
                    }
                }
            }

            Console.WriteLine("Done");
            return(0);
        }