Ejemplo n.º 1
0
        private static void UE4ChunkUnzip(string source, string destination)
        {
            if (!File.Exists(source))
            {
                return;
            }
            using (BinaryReader inReader = new BinaryReader(File.Open(source, FileMode.Open)))
            {
                using (BinaryWriter binaryWriter = new BinaryWriter(File.Open(destination, FileMode.Create)))
                {
                    FCompressedChunkInfo fcompressedChunkInfo1 = new FCompressedChunkInfo();
                    fcompressedChunkInfo1.Serialize(inReader);
                    FCompressedChunkInfo fcompressedChunkInfo2 = new FCompressedChunkInfo();
                    fcompressedChunkInfo2.Serialize(inReader);

                    long num1 = fcompressedChunkInfo1.CompressedSize;
                    long num2 = fcompressedChunkInfo1.UncompressedSize;
                    if (num2 == 2653586369L)
                    {
                        num2 = 131072L;
                    }
                    long length = (fcompressedChunkInfo2.UncompressedSize + num2 - 1L) / num2;

                    FCompressedChunkInfo[] fcompressedChunkInfoArray = new FCompressedChunkInfo[length];
                    long val2 = 0L;

                    for (int index = 0; index < length; ++index)
                    {
                        fcompressedChunkInfoArray[index] = new FCompressedChunkInfo();
                        fcompressedChunkInfoArray[index].Serialize(inReader);
                        val2 = Math.Max(fcompressedChunkInfoArray[index].CompressedSize, val2);
                    }

                    for (long index = 0L; index < length; ++index)
                    {
                        FCompressedChunkInfo fcompressedChunkInfo3 = fcompressedChunkInfoArray[index];
                        byte[] buffer = ZlibStream.UncompressBuffer(inReader.ReadBytes((int)fcompressedChunkInfo3.CompressedSize));
                        binaryWriter.Write(buffer);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        protected byte[] LoadCompressedChunk(BinaryReader reader)
        {
            try
            {
                FCompressedChunkInfo PackageFileTag = new FCompressedChunkInfo();
                PackageFileTag.CompressedSize   = reader.ReadInt64();
                PackageFileTag.UncompressedSize = reader.ReadInt64();
                FCompressedChunkInfo Summary = new FCompressedChunkInfo();
                Summary.CompressedSize   = reader.ReadInt64();
                Summary.UncompressedSize = reader.ReadInt64();

                bool bWasByteSwapped = PackageFileTag.CompressedSize != PACKAGE_FILE_TAG;
                bool bHeaderWasValid = true;

                if (bWasByteSwapped)
                {
                    bHeaderWasValid = PackageFileTag.CompressedSize == PACKAGE_FILE_TAG_SWAPPED;
                    if (bHeaderWasValid)
                    {
                        // not supported
                        //Summary.CompressedSize = BYTESWAP_ORDER64(Summary.CompressedSize);
                        //Summary.UncompressedSize = BYTESWAP_ORDER64(Summary.UncompressedSize);
                        //PackageFileTag.UncompressedSize = BYTESWAP_ORDER64(PackageFileTag.UncompressedSize);
                    }
                }
                else
                {
                    bHeaderWasValid = PackageFileTag.CompressedSize == PACKAGE_FILE_TAG;
                }

                // Handle change in compression chunk size in backward compatible way.
                long LoadingCompressionChunkSize = PackageFileTag.UncompressedSize;
                if (LoadingCompressionChunkSize == PACKAGE_FILE_TAG)
                {
                    LoadingCompressionChunkSize = LOADING_COMPRESSION_CHUNK_SIZE;
                }

                // Figure out how many chunks there are going to be based on uncompressed size and compression chunk size.
                long TotalChunkCount = (Summary.UncompressedSize + LoadingCompressionChunkSize - 1) / LoadingCompressionChunkSize;

                // Allocate compression chunk infos and serialize them, keeping track of max size of compression chunks used.
                FCompressedChunkInfo[] CompressionChunks = new FCompressedChunkInfo[TotalChunkCount];
                long MaxCompressedSize = 0;
                for (int ChunkIndex = 0; ChunkIndex < TotalChunkCount; ChunkIndex++)
                {
                    CompressionChunks[ChunkIndex].CompressedSize   = reader.ReadInt64();
                    CompressionChunks[ChunkIndex].UncompressedSize = reader.ReadInt64();
                    if (bWasByteSwapped)
                    {
                        // not supported
                        //CompressionChunks[ChunkIndex].CompressedSize = BYTESWAP_ORDER64(CompressionChunks[ChunkIndex].CompressedSize);
                        //CompressionChunks[ChunkIndex].UncompressedSize = BYTESWAP_ORDER64(CompressionChunks[ChunkIndex].UncompressedSize);
                    }
                    MaxCompressedSize = Math.Max(CompressionChunks[ChunkIndex].CompressedSize, MaxCompressedSize);
                }

                byte[] DeCompressedBuffer = new byte[Summary.UncompressedSize];

                int offset = 0;
                // Iterate over all chunks, serialize them into memory and decompress them directly into the destination pointer
                for (long ChunkIndex = 0; ChunkIndex < TotalChunkCount; ChunkIndex++)
                {
                    // Read compressed data.
                    byte[]        initialSkip      = reader.ReadBytes(2);
                    byte[]        CompressedBuffer = reader.ReadBytes((int)CompressionChunks[ChunkIndex].CompressedSize - 6);
                    byte[]        finalSkip        = reader.ReadBytes(4);
                    MemoryStream  ms   = new MemoryStream(CompressedBuffer);
                    DeflateStream gzip = new DeflateStream(ms, CompressionMode.Decompress);
                    gzip.Read(DeCompressedBuffer, offset, (int)CompressionChunks[ChunkIndex].UncompressedSize);
                    // Decompress into dest pointer directly.
                    offset += (int)CompressionChunks[ChunkIndex].UncompressedSize;
                }
                return(DeCompressedBuffer);
            }
            catch
            {
                return(null);
            }
        }