Beispiel #1
0
        public void Compress(string Folder, Action <int, int> processedEvent, bool is64 = false, int compression = 9)
        {
            string file_path;

            byte[] buffer_packed;
            byte[] buffer_unpacked;

            string[] files = Directory.EnumerateFiles(Folder, "*", SearchOption.AllDirectories).ToArray();

            int FileCount = files.Count();

            BPKG_FTE     FileTableEntry = new BPKG_FTE();
            MemoryStream mosTablems     = new MemoryStream();
            BinaryWriter mosTable       = new BinaryWriter(mosTablems);
            MemoryStream mosFilesms     = new MemoryStream();
            BinaryWriter mosFiles       = new BinaryWriter(mosFilesms);

            for (int i = 0; i < FileCount; i++)
            {
                file_path = files[i].Replace(Folder, "").TrimStart('\\');
                FileTableEntry.FilePathLength = file_path.Length;

                if (is64)
                {
                    mosTable.Write((long)FileTableEntry.FilePathLength);
                }
                else
                {
                    mosTable.Write(FileTableEntry.FilePathLength);
                }

                FileTableEntry.FilePath = file_path;
                mosTable.Write(Encoding.Unicode.GetBytes(FileTableEntry.FilePath));
                FileTableEntry.Unknown_001 = 2;
                mosTable.Write(FileTableEntry.Unknown_001);
                FileTableEntry.IsCompressed = true;
                mosTable.Write(FileTableEntry.IsCompressed);
                FileTableEntry.IsEncrypted = true;
                mosTable.Write(FileTableEntry.IsEncrypted);
                FileTableEntry.Unknown_002 = 0;
                mosTable.Write(FileTableEntry.Unknown_002);

                FileStream   fis = new FileStream(files[i], FileMode.Open);
                MemoryStream tmp = new MemoryStream();


                //stopWatch.Start();
                //Console.Write("\rCompressing Files: {0}/{1}", (i + 1), FileCount);
                processedEvent((i + 1), FileCount);

                if (file_path.EndsWith(".xml") || file_path.EndsWith(".x16"))
                {
                    // encode bxml
                    BXML bxml = new BXML(XOR_KEY);
                    Convert(fis, bxml.DetectType(fis), tmp, BXML_TYPE.BXML_BINARY);
                }
                else
                {
                    // compress raw
                    fis.CopyTo(tmp);
                }
                fis.Close();
                fis = null;

                FileTableEntry.FileDataOffset       = (int)mosFiles.BaseStream.Position;
                FileTableEntry.FileDataSizeUnpacked = (int)tmp.Length;

                if (is64)
                {
                    mosTable.Write((long)FileTableEntry.FileDataSizeUnpacked);
                }
                else
                {
                    mosTable.Write(FileTableEntry.FileDataSizeUnpacked);
                }

                buffer_unpacked = tmp.ToArray();
                tmp.Close();
                tmp             = null;
                buffer_packed   = Pack(buffer_unpacked, FileTableEntry.FileDataSizeUnpacked, out FileTableEntry.FileDataSizeSheared, out FileTableEntry.FileDataSizeStored, FileTableEntry.IsEncrypted, FileTableEntry.IsCompressed, compression);
                buffer_unpacked = null;
                mosFiles.Write(buffer_packed);
                buffer_packed = null;

                if (is64)
                {
                    mosTable.Write((long)FileTableEntry.FileDataSizeSheared);
                }
                else
                {
                    mosTable.Write(FileTableEntry.FileDataSizeSheared);
                }

                if (is64)
                {
                    mosTable.Write((long)FileTableEntry.FileDataSizeStored);
                }
                else
                {
                    mosTable.Write(FileTableEntry.FileDataSizeStored);
                }

                if (is64)
                {
                    mosTable.Write((long)FileTableEntry.FileDataOffset);
                }
                else
                {
                    mosTable.Write(FileTableEntry.FileDataOffset);
                }

                FileTableEntry.Padding = new byte[60];
                mosTable.Write(FileTableEntry.Padding);
            }

            Console.Write("\r\nWriting File Entries...\n");

            MemoryStream output = new MemoryStream();
            BinaryWriter bw     = new BinaryWriter(output);

            byte[] Signature = new byte[8] {
                (byte)'U', (byte)'O', (byte)'S', (byte)'E', (byte)'D', (byte)'A', (byte)'L', (byte)'B'
            };
            bw.Write(Signature);
            int Version = 2;

            bw.Write(Version);
            byte[] Unknown_001 = new byte[5] {
                0, 0, 0, 0, 0
            };
            bw.Write(Unknown_001);
            int FileDataSizePacked = (int)mosFiles.BaseStream.Length;

            if (is64)
            {
                bw.Write((long)FileDataSizePacked);
                bw.Write((long)FileCount);
            }
            else
            {
                bw.Write(FileDataSizePacked);
                bw.Write(FileCount);
            }

            bool IsCompressed = true;

            bw.Write(IsCompressed);
            bool IsEncrypted = true;

            bw.Write(IsEncrypted);
            byte[] Unknown_002 = new byte[62];
            bw.Write(Unknown_002);

            int FileTableSizeUnpacked = (int)mosTable.BaseStream.Length;
            int FileTableSizeSheared  = FileTableSizeUnpacked;
            int FileTableSizePacked   = FileTableSizeUnpacked;

            buffer_unpacked = mosTablems.ToArray();
            mosTable.Close();
            mosTablems.Close();
            mosTable        = null;
            mosTablems      = null;
            buffer_packed   = Pack(buffer_unpacked, FileTableSizeUnpacked, out FileTableSizeSheared, out FileTableSizePacked, IsEncrypted, IsCompressed, compression);
            buffer_unpacked = null;

            if (is64)
            {
                bw.Write((long)FileTableSizePacked);
            }
            else
            {
                bw.Write(FileTableSizePacked);
            }

            if (is64)
            {
                bw.Write((long)FileTableSizeUnpacked);
            }
            else
            {
                bw.Write(FileTableSizeUnpacked);
            }

            bw.Write(buffer_packed);
            buffer_packed = null;

            int OffsetGlobal = (int)output.Position + (is64 ? 8 : 4);

            if (is64)
            {
                bw.Write((long)OffsetGlobal);
            }
            else
            {
                bw.Write(OffsetGlobal);
            }

            buffer_packed = mosFilesms.ToArray();
            mosFiles.Close();
            mosFilesms.Close();
            mosFiles   = null;
            mosFilesms = null;
            bw.Write(buffer_packed);
            buffer_packed = null;
            File.WriteAllBytes(Folder.Replace(".files", ""), output.ToArray());
            bw.Close();
            output.Close();
            bw     = null;
            output = null;
            Console.Write("\nDone!");
        }
Beispiel #2
0
        public void Extract(string FileName, Action <int, int> processedEvent, bool is64 = false)
        {
            FileStream   fs = new FileStream(FileName, FileMode.Open);
            BinaryReader br = new BinaryReader(fs);
            string       file_path;

            byte[] buffer_packed;
            byte[] buffer_unpacked;

            byte[] Signature = br.ReadBytes(8);
            uint   Version   = br.ReadUInt32();

            byte[] Unknown_001        = br.ReadBytes(5);
            int    FileDataSizePacked = is64 ? (int)br.ReadInt64() : br.ReadInt32();
            int    FileCount          = is64 ? (int)br.ReadInt64() : br.ReadInt32();
            bool   IsCompressed       = br.ReadByte() == 1;
            bool   IsEncrypted        = br.ReadByte() == 1;

            byte[] Unknown_002           = br.ReadBytes(62);
            int    FileTableSizePacked   = is64 ? (int)br.ReadInt64() : br.ReadInt32();
            int    FileTableSizeUnpacked = is64 ? (int)br.ReadInt64() : br.ReadInt32();

            buffer_packed = br.ReadBytes(FileTableSizePacked);
            int OffsetGlobal = is64 ? (int)br.ReadInt64() : br.ReadInt32();

            OffsetGlobal = (int)br.BaseStream.Position; // don't trust value, read current stream location.

            byte[] FileTableUnpacked = Unpack(buffer_packed, FileTableSizePacked, FileTableSizePacked, FileTableSizeUnpacked, IsEncrypted, IsCompressed);
            buffer_packed = null;
            MemoryStream ms  = new MemoryStream(FileTableUnpacked);
            BinaryReader br2 = new BinaryReader(ms);

            Console.Write("\rReading File Entries...\n");

            for (int i = 0; i < FileCount; i++)
            {
                BPKG_FTE FileTableEntry = new BPKG_FTE();
                FileTableEntry.FilePathLength       = is64 ? (int)br2.ReadInt64() : br2.ReadInt32();
                FileTableEntry.FilePath             = Encoding.Unicode.GetString(br2.ReadBytes(FileTableEntry.FilePathLength * 2));
                FileTableEntry.Unknown_001          = br2.ReadByte();
                FileTableEntry.IsCompressed         = br2.ReadByte() == 1;
                FileTableEntry.IsEncrypted          = br2.ReadByte() == 1;
                FileTableEntry.Unknown_002          = br2.ReadByte();
                FileTableEntry.FileDataSizeUnpacked = is64 ? (int)br2.ReadInt64() : br2.ReadInt32();
                FileTableEntry.FileDataSizeSheared  = is64 ? (int)br2.ReadInt64() : br2.ReadInt32();
                FileTableEntry.FileDataSizeStored   = is64 ? (int)br2.ReadInt64() : br2.ReadInt32();
                FileTableEntry.FileDataOffset       = (is64 ? (int)br2.ReadInt64() : br2.ReadInt32()) + OffsetGlobal;
                FileTableEntry.Padding = br2.ReadBytes(60);

                file_path = string.Format("{0}.files\\{1}", FileName, FileTableEntry.FilePath);
                if (!Directory.Exists((new FileInfo(file_path)).DirectoryName))
                {
                    Directory.CreateDirectory((new FileInfo(file_path)).DirectoryName);
                }

                // Console.Write("\rExtracting Files: {0}/{1}", (i + 1), FileCount);

                br.BaseStream.Position = FileTableEntry.FileDataOffset;
                buffer_packed          = br.ReadBytes(FileTableEntry.FileDataSizeStored);
                buffer_unpacked        = Unpack(buffer_packed, FileTableEntry.FileDataSizeStored, FileTableEntry.FileDataSizeSheared, FileTableEntry.FileDataSizeUnpacked, FileTableEntry.IsEncrypted, FileTableEntry.IsCompressed);
                buffer_packed          = null;
                FileTableEntry         = null;

                if (file_path.EndsWith("xml") || file_path.EndsWith("x16"))
                {
                    // decode bxml
                    MemoryStream temp    = new MemoryStream();
                    MemoryStream temp2   = new MemoryStream(buffer_unpacked);
                    BXML         bns_xml = new BXML(XOR_KEY);
                    Convert(temp2, bns_xml.DetectType(temp2), temp, BXML_TYPE.BXML_PLAIN);
                    temp2.Close();
                    File.WriteAllBytes(file_path, temp.ToArray());
                    temp.Close();
                    buffer_unpacked = null;
                }
                else
                {
                    // extract raw
                    File.WriteAllBytes(file_path, buffer_unpacked);
                    buffer_unpacked = null;
                }
                processedEvent((i + 1), FileCount);
            }
            br2.Close();
            ms.Close();
            br2 = null;
            ms  = null;
            br.Close();
            fs.Close();
            br = null;
            fs = null;
            Console.Write("\nDone!");
        }