Ejemplo n.º 1
0
        public static void Extract(string FileName, Action <int, int> processedEvent, bool is64 = false)
        {
            using (FileStream fs = new FileStream(FileName, FileMode.Open))
            {
                BinaryReader br = new BinaryReader(fs);

                BPKG pkg = new BPKG(fs, is64);

                for (var i = 0; i < pkg.Files.Length; i++)
                {
                    BPKG_FTE fte = pkg.Files[i];
                    // Seek to location of binary file data
                    fs.Position = fte.FileDataOffset;

                    byte[] packedFileData   = br.ReadBytes(fte.FileDataSizeStored);
                    byte[] unpackedFileData = Unpack(packedFileData, fte.FileDataSizeStored,
                                                     fte.FileDataSizeSheared, fte.FileDataSizeUnpacked,
                                                     fte.IsEncrypted, fte.IsCompressed);

                    string extractedPath = $"{FileName}.files\\{fte.FilePath}";
                    string extractedDir  = new FileInfo(extractedPath).DirectoryName;
                    if (!Directory.Exists(extractedDir))
                    {
                        ;
                    }
                    Directory.CreateDirectory(extractedDir);

                    if (extractedPath.EndsWith("xml") || extractedPath.EndsWith("x16"))
                    {
                        // decode bxml
                        MemoryStream output = new MemoryStream();
                        MemoryStream input  = new MemoryStream(unpackedFileData);

                        Convert(input, BXML.DetectType(input), output, BXML_TYPE.BXML_PLAIN);

                        using (WinFileIO writer = new WinFileIO(output.ToArray()))
                        {
                            writer.OpenForWriting(extractedPath);
                            writer.WriteBlocks((int)output.Length);
                        }
                    }
                    else
                    {
                        // extract raw
                        File.WriteAllBytes(extractedPath, unpackedFileData);
                    }
                    processedEvent(i + 1, pkg.Files.Length);
                }
            }
        }
Ejemplo n.º 2
0
        public static void Compress(string Folder, Action <int, int> reportProgress, bool is64 = false, int compression = 1)
        {
            string[] files = Directory.EnumerateFiles(Folder, "*", SearchOption.AllDirectories).ToArray();

            MemoryStream fileTableEntriesStream = new MemoryStream();
            MemoryStream fileTableStream        = new MemoryStream();

            for (var i = 0; i < files.Length; i++)
            {
                reportProgress(i + 1, files.Length);

                string path = files[i].Replace(Folder, "").TrimStart('\\');

                byte[] unpackedFileBuffer;
                using (FileStream fis = new FileStream(files[i], FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 2 << 15))
                    using (MemoryStream buf = new MemoryStream())
                    {
                        if (path.EndsWith(".xml") || path.EndsWith(".x16"))
                        {
                            // encode bxml
                            Convert(fis, BXML.DetectType(fis), buf, BXML_TYPE.BXML_BINARY);
                        }
                        else
                        {
                            // compress raw
                            fis.CopyTo(buf);
                        }

                        unpackedFileBuffer = buf.ToArray();
                    }

                BPKG_FTE entry = new BPKG_FTE
                {
                    FilePathLength       = path.Length,
                    FilePath             = path,
                    IsCompressed         = true,
                    IsEncrypted          = true,
                    FileDataOffset       = (int)fileTableStream.Position,
                    FileDataSizeUnpacked = unpackedFileBuffer.Length
                };

                byte[] packedFileBuffer = Pack(unpackedFileBuffer, out entry.FileDataSizeSheared, out entry.FileDataSizeStored, entry.IsEncrypted, entry.IsCompressed, compression);
                fileTableStream.Write(packedFileBuffer, 0, packedFileBuffer.Length);

                entry.WriteTo(fileTableEntriesStream, is64);
            }

            MemoryStream packageStream = new MemoryStream();
            BinaryWriter package       = new BinaryWriter(packageStream);

            package.Write(new[]
            {
                (byte)'U', (byte)'O', (byte)'S', (byte)'E', (byte)'D', (byte)'A', (byte)'L', (byte)'B'
            });                                          // Signature
            package.Write(2);                            // Version
            package.Write(new byte[] { 0, 0, 0, 0, 0 }); // Unknown 1

            if (is64)
            {
                package.Write(fileTableStream.Length);
                package.Write((long)files.Length);
            }
            else
            {
                package.Write((int)fileTableStream.Length);
                package.Write(files.Length);
            }

            package.Write(true);         // Is compressed
            package.Write(true);         // Is encrypted
            package.Write(new byte[62]); // Unknown 2

            int FTESizePacked;

            byte[] packedFTEBuffer = Pack(fileTableEntriesStream.ToArray(), out _, out FTESizePacked, true, true, compression);

            if (is64)
            {
                package.Write((long)FTESizePacked);
                package.Write(fileTableEntriesStream.Length);
            }
            else
            {
                package.Write(FTESizePacked);
                package.Write((int)fileTableEntriesStream.Length);
            }

            package.Write(packedFTEBuffer);

            int globalOffset = (int)packageStream.Position + (is64 ? 8 : 4);

            if (is64)
            {
                package.Write((long)globalOffset);
            }
            else
            {
                package.Write(globalOffset);
            }

            // Write the packed file data
            package.Write(fileTableStream.ToArray());

            WinFileIO writer = new WinFileIO(packageStream.ToArray());

            writer.OpenForWriting(Folder.Replace(".files", ""));
            writer.WriteBlocks((int)packageStream.Length);
            writer.Close();
        }