Example #1
0
        private static IReadOnlyList <AssetFileEntry> FillAssetsFilesFromOldFormat(EndianBinaryReader reader, int offset)
        {
            var fileCount          = reader.ReadInt32();
            var assetFilesInMemory = new AssetFileEntry[fileCount];

            for (var i = 0; i < fileCount; ++i)
            {
                var fileName   = reader.ReadStringToNull();
                var fileOffset = reader.ReadInt32();
                fileOffset += offset;
                var fileSize = reader.ReadInt32();

                var originalPosition = reader.Position;
                reader.Position = fileOffset;

                var buf = new byte[fileSize];
                reader.Read(buf, 0, fileSize);
                reader.Position = originalPosition;

                var memory     = new MemoryStream(buf, false);
                var memoryFile = new AssetFileEntry(memory, fileName, false);
                assetFilesInMemory[i] = memoryFile;
            }

            return(assetFilesInMemory);
        }
Example #2
0
        private static IReadOnlyList <AssetFileEntry> ReadFormat6(EndianBinaryReader reader, bool padding)
        {
            var bundleSize       = reader.ReadInt64();
            var compressedSize   = reader.ReadInt32();
            var uncompressedSize = reader.ReadInt32();
            var flag             = reader.ReadInt32();

            if (padding)
            {
                reader.ReadByte();
            }

            byte[] blocksInfoBytes;
            if ((flag & 0x80) == 0)
            {
                blocksInfoBytes = reader.ReadBytes(compressedSize);
            }
            else
            {
                var originalPosition = reader.Position;
                reader.Position = reader.BaseStream.Length - compressedSize;
                blocksInfoBytes = reader.ReadBytes(compressedSize);
                reader.Position = originalPosition;
            }

            Stream extraStream;

            byte[] rawBytes;
            switch (flag & 0x3f)
            {
            case 0:
                extraStream = new MemoryStream(blocksInfoBytes, false);
                break;

            case 1:
                rawBytes    = SevenZip.Compression.LZMA.SevenZipHelper.Decompress(blocksInfoBytes);
                extraStream = new MemoryStream(rawBytes, false);
                break;

            case 2:
            case 3:
                rawBytes = new byte[uncompressedSize];
                var resultSize = LZ4Codec.Decode(blocksInfoBytes, 0, blocksInfoBytes.Length, rawBytes, 0, uncompressedSize);
                extraStream = new MemoryStream(rawBytes, false);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(flag), flag, null);
            }

            AssetFileEntry[] assetFilesInMemory;

            using (var blocksInfoReader = new EndianBinaryReader(extraStream, Endian.BigEndian)) {
                blocksInfoReader.Position = 0x10;
                var blockCount = blocksInfoReader.ReadInt32();
                using (var assetsDataStream = new MemoryStream()) {
                    for (var i = 0; i < blockCount; ++i)
                    {
                        uncompressedSize = blocksInfoReader.ReadInt32();
                        compressedSize   = blocksInfoReader.ReadInt32();
                        flag             = blocksInfoReader.ReadInt16();

                        var    compressedBytes = reader.ReadBytes(compressedSize);
                        byte[] uncompressedBytes;
                        switch (flag & 0x3f)
                        {
                        case 0:
                            assetsDataStream.Write(compressedBytes, 0, compressedSize);
                            break;

                        case 1:
                            uncompressedBytes = SevenZip.Compression.LZMA.SevenZipHelper.Decompress(compressedBytes);
                            assetsDataStream.Write(uncompressedBytes, 0, uncompressedSize);
                            break;

                        case 2:
                        case 3:
                            uncompressedBytes = new byte[uncompressedSize];
                            var resultSize = LZ4Codec.Decode(compressedBytes, 0, compressedBytes.Length, uncompressedBytes, 0, uncompressedSize);
                            assetsDataStream.Write(uncompressedBytes, 0, uncompressedSize);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(nameof(flag), flag, null);
                        }
                    }

                    assetsDataStream.Position = 0;

                    using (var assetsDataReader = new EndianBinaryReader(assetsDataStream, Endian.BigEndian)) {
                        var entryCount          = blocksInfoReader.ReadInt32();
                        var temporaryAssetFiles = new List <AssetFileEntry>();

                        for (var i = 0; i < entryCount; ++i)
                        {
                            var entryOffset = blocksInfoReader.ReadInt64();
                            var entrySize   = blocksInfoReader.ReadInt64();
                            var flags       = blocksInfoReader.ReadInt32(); // My guess is: flags=0 => "empty shell"; flags!=0(==4) => real file
                            var fileName    = blocksInfoReader.ReadStringToNull();

                            assetsDataReader.Position = entryOffset;
                            var buf = new byte[entrySize];
                            assetsDataReader.Read(buf, 0, (int)entrySize);
                            var memory = new MemoryStream(buf, false);

                            var memoryFile = new AssetFileEntry(memory, fileName, false);

                            if (flags != 0)
                            {
                                temporaryAssetFiles.Add(memoryFile);
                            }
                        }

                        assetFilesInMemory = temporaryAssetFiles.ToArray();
                    }
                }
            }

            extraStream.Dispose();

            return(assetFilesInMemory);
        }