Exemplo n.º 1
0
        public Shader(AssetPreloadData preloadData) : base(preloadData)
        {
            if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 5 || sourceFile.version[0] > 5) //5.5.0 and up
            {
                var str = preloadData.Dump();
                m_Script = Encoding.UTF8.GetBytes(str ?? "Serialized Shader can't be read");
            }
            else
            {
                m_Script = reader.ReadBytes(reader.ReadInt32());
                if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 3) //5.3 - 5.4
                {
                    reader.AlignStream(4);
                    var m_PathName        = reader.ReadAlignedString();
                    var decompressedSize  = reader.ReadUInt32();
                    var m_SubProgramBlob  = reader.ReadBytes(reader.ReadInt32());
                    var decompressedBytes = new byte[decompressedSize];
                    using (var decoder = new Lz4DecoderStream(new MemoryStream(m_SubProgramBlob)))
                    {
                        decoder.Read(decompressedBytes, 0, (int)decompressedSize);
                    }

                    m_Script = m_Script.Concat(decompressedBytes.ToArray()).ToArray();
                }
            }
        }
Exemplo n.º 2
0
        private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
        {
            foreach (var blockInfo in m_BlocksInfo)
            {
                switch (blockInfo.flags & 0x3F) //kStorageBlockCompressionTypeMask
                {
                default:                        //None
                {
                    reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
                    break;
                }

                case 1:     //LZMA
                {
                    SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
                    break;
                }

                case 2:     //LZ4
                case 3:     //LZ4HC
                {
                    var compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize));
                    using (var lz4Stream = new Lz4DecoderStream(compressedStream))
                    {
                        lz4Stream.CopyTo(blocksStream, blockInfo.uncompressedSize);
                    }
                    break;
                }
                }
            }
            blocksStream.Position = 0;
        }
        private void ReadBlocks(EndianBinaryReader varReader, Stream varBlocksStream)
        {
            foreach (var blockInfo in BlocksInfo)
            {
                switch (blockInfo.GetCompressionType())
                {
                default:     //None
                {
                    varReader.BaseStream.CopyTo(varBlocksStream, blockInfo.compressedSize);
                    break;
                }

                case Compression.CompressionType.kCompressionLzma:     //LZMA
                {
                    SevenZipHelper.StreamDecompress(varReader.BaseStream, varBlocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
                    break;
                }

                case Compression.CompressionType.kCompressionLz4:     //LZ4
                case Compression.CompressionType.kCompressionLz4HC:   //LZ4HC
                {
                    var compressedStream = new MemoryStream(varReader.ReadBytes((int)blockInfo.compressedSize));
                    using (var lz4Stream = new Lz4DecoderStream(compressedStream))
                    {
                        lz4Stream.CopyTo(varBlocksStream, blockInfo.uncompressedSize);
                    }
                    break;
                }
                }
            }
            varBlocksStream.Position = 0;
        }
Exemplo n.º 4
0
        public bool Read(AssetsFileReader reader)
        {
            header = new ClassDatabaseFileHeader();
            header.Read(reader);
            if (header.header != "cldb" || header.fileVersion > 4 || header.fileVersion < 1)
            {
                valid = false;
                return(valid);
            }
            classes = new List <ClassDatabaseType>();

            long             classTablePos = reader.Position;
            AssetsFileReader newReader     = reader;

            if (header.compressionType != 0)
            {
                classTablePos = 0;
                MemoryStream ms;
                if (header.compressionType == 1) //lz4
                {
                    byte[] uncompressedBytes = new byte[header.uncompressedSize];
                    using (MemoryStream tempMs = new MemoryStream(reader.ReadBytes((int)header.compressedSize)))
                    {
                        Lz4DecoderStream decoder = new Lz4DecoderStream(tempMs);
                        decoder.Read(uncompressedBytes, 0, (int)header.uncompressedSize);
                        decoder.Dispose();
                    }
                    ms = new MemoryStream(uncompressedBytes);
                }
                else if (header.compressionType == 2) //lzma
                {
                    using (MemoryStream tempMs = new MemoryStream(reader.ReadBytes((int)header.compressedSize)))
                    {
                        ms = SevenZipHelper.StreamDecompress(tempMs);
                    }
                }
                else
                {
                    valid = false;
                    return(valid);
                }

                newReader           = new AssetsFileReader(ms);
                newReader.bigEndian = false;
            }

            newReader.Position = header.stringTablePos;
            stringTable        = newReader.ReadBytes((int)header.stringTableLen);
            newReader.Position = classTablePos;
            uint size = newReader.ReadUInt32();

            for (int i = 0; i < size; i++)
            {
                ClassDatabaseType cdt = new ClassDatabaseType();
                cdt.Read(newReader, header.fileVersion, header.flags);
                classes.Add(cdt);
            }
            valid = true;
            return(valid);
        }
        public static byte[] DecompressFromLZ4(Stream stream, int rawLength)
        {
            using (stream)
            {
#if NETSTANDARD2_0
                var inputLength = rawLength;
                var inputBuffer = new byte[inputLength];
                stream.Read(inputBuffer, 0, rawLength);
                var guessedOutputLength = inputLength * 10;
                var outputBuffer        = new byte[guessedOutputLength];
                var actualOutputLength  = LZ4Codec.Decode(
                    inputBuffer, 0, inputLength,
                    outputBuffer, 0, guessedOutputLength);
                if (actualOutputLength < guessedOutputLength)
                {
                    return(outputBuffer.Take(actualOutputLength).ToArray());
                }
                else
                {
                    return(outputBuffer);
                }
#else
                using (Lz4DecoderStream streamInner = new Lz4DecoderStream(stream))
                {
                    byte[] output = new byte[rawLength];
                    streamInner.Read(output, 0, rawLength);
                    return(output);
                }
#endif
            }
        }
Exemplo n.º 6
0
        public static string[] ConvertMultiple(Shader shader)
        {
            if (shader.compressedBlob != null) //5.5 and up
            {
                var strs = new string[shader.platforms.Length];
                for (var i = 0; i < shader.platforms.Length; i++)
                {
                    var compressedBytes = new byte[shader.compressedLengths[i]];
                    Buffer.BlockCopy(shader.compressedBlob, (int)shader.offsets[i], compressedBytes, 0, (int)shader.compressedLengths[i]);
                    var decompressedBytes = new byte[shader.decompressedLengths[i]];
                    using (var decoder = new Lz4DecoderStream(new MemoryStream(compressedBytes)))
                    {
                        decoder.Read(decompressedBytes, 0, (int)shader.decompressedLengths[i]);
                    }
                    using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
                    {
                        var program  = new ShaderProgram(blobReader, shader.version);
                        var m_Script = ConvertSerializedShader(shader.m_ParsedForm, shader.platforms[i]);
                        strs[i] = header + program.Export(m_Script);
                    }
                }

                return(strs);
            }

            return(null);
        }
Exemplo n.º 7
0
        public BundleFile(string fileName)
        {
            if (Path.GetExtension(fileName) == ".lz4")
            {
                byte[] filebuffer;

                using (BinaryReader lz4Stream = new BinaryReader(File.OpenRead(fileName)))
                {
                    int version          = lz4Stream.ReadInt32();
                    int uncompressedSize = lz4Stream.ReadInt32();
                    int compressedSize   = lz4Stream.ReadInt32();
                    int something        = lz4Stream.ReadInt32(); //1

                    var lz4buffer = lz4Stream.ReadBytes(compressedSize);
                    using (var inputStream = new MemoryStream(lz4buffer))
                    {
                        var decoder = new Lz4DecoderStream(inputStream);
                        filebuffer = new byte[uncompressedSize];
                        decoder.Read(filebuffer, 0, uncompressedSize);
                        decoder.Dispose();
                    }
                }
                using (var b_Stream = new EndianBinaryReader(new MemoryStream(filebuffer)))
                {
                    readBundle(b_Stream);
                }
            }
            else
            {
                using (var b_Stream = new EndianBinaryReader(File.OpenRead(fileName)))
                {
                    readBundle(b_Stream);
                }
            }
        }
Exemplo n.º 8
0
        private ContentReader GetContentReaderFromXnb(string originalAssetName, Stream stream, BinaryReader xnbReader, Action <IDisposable> recordDisposableObject)
        {
            // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file
            byte x        = xnbReader.ReadByte();
            byte n        = xnbReader.ReadByte();
            byte b        = xnbReader.ReadByte();
            byte platform = xnbReader.ReadByte();

            if (x != 'X' || n != 'N' || b != 'B' ||
                !(targetPlatformIdentifiers.Contains((char)platform)))
            {
                throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
            }

            byte version = xnbReader.ReadByte();
            byte flags   = xnbReader.ReadByte();

            bool compressedLzx = (flags & ContentCompressedLzx) != 0;
            bool compressedLz4 = (flags & ContentCompressedLz4) != 0;

            if (version != 5 && version != 4)
            {
                throw new ContentLoadException("Invalid XNB version");
            }

            // The next int32 is the length of the XNB file
            int xnbLength = xnbReader.ReadInt32();

            Stream decompressedStream = null;

#if WEB
            decompressedStream = stream;
#else
            if (compressedLzx || compressedLz4)
            {
                // Decompress the xnb
                int decompressedSize = xnbReader.ReadInt32();

                if (compressedLzx)
                {
                    int compressedSize = xnbLength - 14;
                    decompressedStream = new LzxDecoderStream(stream, decompressedSize, compressedSize);
                }
                else if (compressedLz4)
                {
                    decompressedStream = new Lz4DecoderStream(stream);
                }
            }
            else
            {
                decompressedStream = stream;
            }
#endif

            var reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice,
                                           originalAssetName, version, recordDisposableObject);

            return(reader);
        }
Exemplo n.º 9
0
        public Shader(AssetPreloadData preloadData, bool readSwitch)
        {
            var sourceFile = preloadData.sourceFile;
            var a_Stream   = preloadData.sourceFile.a_Stream;

            a_Stream.Position     = preloadData.Offset;
            preloadData.extension = ".txt";

            if (sourceFile.platform == -2)
            {
                uint m_ObjectHideFlags    = a_Stream.ReadUInt32();
                PPtr m_PrefabParentObject = sourceFile.ReadPPtr();
                PPtr m_PrefabInternal     = sourceFile.ReadPPtr();
            }

            m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32());

            if (readSwitch)
            {
                if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 5 || sourceFile.version[0] > 5)//5.5.0 and up
                {
                    a_Stream.Position = preloadData.Offset;
                    var str     = (string)ShaderResource.ResourceManager.GetObject($"Shader{sourceFile.version[0]}{sourceFile.version[1]}");
                    var members = new JavaScriptSerializer().Deserialize <List <ClassMember> >(str);
                    m_Script = ReadSerializedShader(members, a_Stream);
                }
                else
                {
                    m_Script = a_Stream.ReadBytes(a_Stream.ReadInt32());
                    if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 3) //5.3 - 5.4
                    {
                        a_Stream.AlignStream(4);
                        a_Stream.ReadAlignedString(a_Stream.ReadInt32());//m_PathName
                        var decompressedSize  = a_Stream.ReadUInt32();
                        var m_SubProgramBlob  = a_Stream.ReadBytes(a_Stream.ReadInt32());
                        var decompressedBytes = new byte[decompressedSize];
                        using (var mstream = new MemoryStream(m_SubProgramBlob))
                        {
                            var decoder = new Lz4DecoderStream(mstream);
                            decoder.Read(decompressedBytes, 0, (int)decompressedSize);
                            decoder.Dispose();
                        }
                        m_Script = m_Script.Concat(decompressedBytes.ToArray()).ToArray();
                    }
                }
            }
            else
            {
                if (m_Name != "")
                {
                    preloadData.Text = m_Name;
                }
                else
                {
                    preloadData.Text = preloadData.TypeString + " #" + preloadData.uniqueID;
                }
                preloadData.SubItems.AddRange(new[] { preloadData.TypeString, preloadData.Size.ToString() });
            }
        }
Exemplo n.º 10
0
        public Shader(AssetPreloadData preloadData, bool readSwitch)
        {
            var sourceFile = preloadData.sourceFile;
            var reader     = preloadData.InitReader();

            m_Name = reader.ReadAlignedString();

            if (readSwitch)
            {
                if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 5 || sourceFile.version[0] > 5)//5.5.0 and up
                {
                    var str = (string)ShaderResource.ResourceManager.GetObject($"Shader{sourceFile.version[0]}{sourceFile.version[1]}");
                    if (str == null)
                    {
                        str = preloadData.ViewStruct();
                        if (str == null)
                        {
                            m_Script = Encoding.UTF8.GetBytes("Serialized Shader can't be read");
                        }
                        else
                        {
                            m_Script = Encoding.UTF8.GetBytes(str);
                        }
                    }
                    else
                    {
                        reader.Position = preloadData.Offset;
                        var sb      = new StringBuilder();
                        var members = new JavaScriptSerializer().Deserialize <List <ClassMember> >(str);
                        ClassStructHelper.ReadClassStruct(sb, members, reader);
                        m_Script = Encoding.UTF8.GetBytes(sb.ToString());
                        //m_Script = ReadSerializedShader(members, a_Stream);
                    }
                }
                else
                {
                    m_Script = reader.ReadBytes(reader.ReadInt32());
                    if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 3) //5.3 - 5.4
                    {
                        reader.AlignStream(4);
                        reader.ReadAlignedString();//m_PathName
                        var decompressedSize  = reader.ReadUInt32();
                        var m_SubProgramBlob  = reader.ReadBytes(reader.ReadInt32());
                        var decompressedBytes = new byte[decompressedSize];
                        using (var decoder = new Lz4DecoderStream(new MemoryStream(m_SubProgramBlob)))
                        {
                            decoder.Read(decompressedBytes, 0, (int)decompressedSize);
                        }
                        m_Script = m_Script.Concat(decompressedBytes.ToArray()).ToArray();
                    }
                }
            }
            else
            {
                preloadData.extension = ".txt";
                preloadData.Text      = m_Name;
            }
        }
Exemplo n.º 11
0
        public static ContentReaderShim GetContentReaderFromXnb(string originalAssetName, Stream stream, BinaryReader xnbReader)
        {
            // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file
            byte x        = xnbReader.ReadByte();
            byte n        = xnbReader.ReadByte();
            byte b        = xnbReader.ReadByte();
            byte platform = xnbReader.ReadByte();

            if (x != 'X' || n != 'N' || b != 'B' ||
                !(targetPlatformIdentifiers.Contains((char)platform)))
            {
                throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
            }

            byte version = xnbReader.ReadByte();
            byte flags   = xnbReader.ReadByte();

            bool compressedLzx = (flags & ContentCompressedLzx) != 0;
            bool compressedLz4 = (flags & ContentCompressedLz4) != 0;

            if (version != 6 && version != 5)
            {
                throw new ContentLoadException("Invalid XNB version");
            }

            // The next int32 is the length of the XNB file
            int xnbLength = xnbReader.ReadInt32();

            Stream decompressedStream = null;

            if (compressedLzx || compressedLz4)
            {
                // Decompress the xnb
                int decompressedSize = xnbReader.ReadInt32();

                if (compressedLzx)
                {
                    int compressedSize = xnbLength - 14;
                    decompressedStream = new LzxDecoderStream(stream, decompressedSize, compressedSize);
                }
                else if (compressedLz4)
                {
                    decompressedStream = new Lz4DecoderStream(stream);
                }
            }
            else
            {
                decompressedStream = stream;
            }

            var reader = new ContentReaderShim(decompressedStream, version);

            return(reader);
        }
Exemplo n.º 12
0
        private byte[] DecompressHeader(byte[] data)
        {
            var decompressedSize = ReadScrambledInt1(data, 0x20);
            var decompressed     = new byte[decompressedSize];

            var lz4 = new Lz4DecoderStream(new MemoryStream(data, 0x27, data.Length - 0x27));

            lz4.Read(decompressed, 0, decompressedSize);

            return(decompressed);
        }
Exemplo n.º 13
0
        public static bool IsBundleDataCompressed(AssetBundleFile bundle)
        {
            AssetsFileReader reader = bundle.reader;

            reader.Position = bundle.bundleHeader6.GetBundleInfoOffset();
            MemoryStream     blocksInfoStream;
            AssetsFileReader memReader;
            int compressedSize = (int)bundle.bundleHeader6.compressedSize;

            byte[] uncompressedBytes;
            switch (bundle.bundleHeader6.GetCompressionType())
            {
            case 1:
                uncompressedBytes = new byte[bundle.bundleHeader6.decompressedSize];
                using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize)))
                {
                    MemoryStream decoder = SevenZipHelper.StreamDecompress(mstream, compressedSize);
                    decoder.Read(uncompressedBytes, 0, (int)bundle.bundleHeader6.decompressedSize);
                    decoder.Dispose();
                }
                blocksInfoStream = new MemoryStream(uncompressedBytes);
                break;

            case 2:
            case 3:
                uncompressedBytes = new byte[bundle.bundleHeader6.decompressedSize];
                using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize)))
                {
                    var decoder = new Lz4DecoderStream(mstream);
                    decoder.Read(uncompressedBytes, 0, (int)bundle.bundleHeader6.decompressedSize);
                    decoder.Dispose();
                }
                blocksInfoStream = new MemoryStream(uncompressedBytes);
                break;

            default:
                blocksInfoStream = null;
                break;
            }

            var uncompressedInf = bundle.bundleInf6;

            if (bundle.bundleHeader6.GetCompressionType() != 0)
            {
                using (memReader = new AssetsFileReader(blocksInfoStream))
                {
                    memReader.Position = 0;
                    uncompressedInf    = new AssetBundleBlockAndDirectoryList06();
                    uncompressedInf.Read(0, memReader);
                }
            }

            return(uncompressedInf.blockInf.Any(inf => (inf.flags & 0x3f) != 0));
        }
Exemplo n.º 14
0
 public static byte[] DecompressFromLZ4(Stream stream, int rawLength)
 {
     using (stream)
     {
         using (Lz4DecoderStream streamInner = new Lz4DecoderStream(stream))
         {
             byte[] output = new byte[rawLength];
             streamInner.Read(output, 0, rawLength);
             return(output);
         }
     }
 }
Exemplo n.º 15
0
        private static void lz4decompress(byte[] src, byte[] dst)
        {
            using (var inputStream = new MemoryStream(src))
            {
                var decoder = new Lz4DecoderStream(inputStream);

                for (int i = 0; ;)
                {
                    int nRead = decoder.Read(dst, i, dst.Length - i);
                    if (nRead == 0)
                    {
                        break;
                    }
                    i += nRead;
                }
            }
        }
Exemplo n.º 16
0
        public static void UnpackInfoOnly(this AssetBundleFile bundle)
        {
            AssetsFileReader reader = bundle.reader;

            reader.Position = 0;
            if (bundle.Read(reader, true))
            {
                reader.Position = bundle.bundleHeader6.GetBundleInfoOffset();
                MemoryStream     blocksInfoStream;
                AssetsFileReader memReader;
                int compressedSize = (int)bundle.bundleHeader6.compressedSize;
                switch (bundle.bundleHeader6.GetCompressionType())
                {
                case 1:
                    using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize)))
                    {
                        blocksInfoStream = SevenZipHelper.StreamDecompress(mstream);
                    }
                    break;

                case 2:
                case 3:
                    byte[] uncompressedBytes = new byte[bundle.bundleHeader6.decompressedSize];
                    using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize)))
                    {
                        var decoder = new Lz4DecoderStream(mstream);
                        decoder.Read(uncompressedBytes, 0, (int)bundle.bundleHeader6.decompressedSize);
                        decoder.Dispose();
                    }
                    blocksInfoStream = new MemoryStream(uncompressedBytes);
                    break;

                default:
                    blocksInfoStream = null;
                    break;
                }
                if (bundle.bundleHeader6.GetCompressionType() != 0)
                {
                    using (memReader = new AssetsFileReader(blocksInfoStream))
                    {
                        memReader.Position = 0;
                        bundle.bundleInf6.Read(0, memReader);
                    }
                }
            }
        }
Exemplo n.º 17
0
        public BundleFile(string fileName)
        {
            if (Path.GetExtension(fileName) == ".lz4")
            {
                byte[] filebuffer;

                using (BinaryReader lz4Stream = new BinaryReader(File.OpenRead(fileName)))
                {
                    int version          = lz4Stream.ReadInt32();
                    int uncompressedSize = lz4Stream.ReadInt32();
                    int compressedSize   = lz4Stream.ReadInt32();
                    int something        = lz4Stream.ReadInt32(); //1

                    byte[] lz4buffer = new byte[compressedSize];
                    lz4Stream.Read(lz4buffer, 0, compressedSize);

                    using (var inputStream = new MemoryStream(lz4buffer))
                    {
                        var decoder = new Lz4DecoderStream(inputStream);

                        filebuffer = new byte[uncompressedSize]; //is this ok?
                        for (;;)
                        {
                            int nRead = decoder.Read(filebuffer, 0, uncompressedSize);
                            if (nRead == 0)
                            {
                                break;
                            }
                        }
                    }
                }

                using (var b_Stream = new EndianStream(new MemoryStream(filebuffer), EndianType.BigEndian))
                {
                    readBundle(b_Stream);
                }
            }
            else
            {
                using (var b_Stream = new EndianStream(File.OpenRead(fileName), EndianType.BigEndian))
                {
                    readBundle(b_Stream);
                }
            }
        }
Exemplo n.º 18
0
        private static string ConvertSerializedShader(Shader shader)
        {
            var shaderPrograms = new ShaderProgram[shader.platforms.Length];

            for (var i = 0; i < shader.platforms.Length; i++)
            {
                var compressedBytes = new byte[shader.compressedLengths[i]];
                Buffer.BlockCopy(shader.compressedBlob, (int)shader.offsets[i], compressedBytes, 0, (int)shader.compressedLengths[i]);
                var decompressedBytes = new byte[shader.decompressedLengths[i]];
                using (var decoder = new Lz4DecoderStream(new MemoryStream(compressedBytes)))
                {
                    decoder.Read(decompressedBytes, 0, (int)shader.decompressedLengths[i]);
                }
                using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
                {
                    shaderPrograms[i] = new ShaderProgram(blobReader, shader.version);
                }
            }

            return(ConvertSerializedShader(shader.m_ParsedForm, shader.platforms, shaderPrograms));
        }
Exemplo n.º 19
0
        public static string Convert(Shader shader)
        {
            if (shader.m_SubProgramBlob != null) //5.3 - 5.4
            {
                var decompressedBytes = new byte[shader.decompressedSize];
                using (var decoder = new Lz4DecoderStream(new MemoryStream(shader.m_SubProgramBlob)))
                {
                    decoder.Read(decompressedBytes, 0, (int)shader.decompressedSize);
                }
                using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
                {
                    var program = new ShaderProgram(blobReader);
                    return(program.Export(Encoding.UTF8.GetString(shader.m_Script)));
                }
            }

            if (shader.compressedBlob != null) //5.5 and up
            {
                //TODO

                /*for (var i = 0; i < shader.platforms.Count; i++)
                 * {
                 *  var compressedBytes = new byte[shader.compressedLengths[i]];
                 *  Array.Copy(shader.compressedBlob, shader.offsets[i], compressedBytes, 0, shader.compressedLengths[i]);
                 *  var decompressedBytes = new byte[shader.decompressedLengths[i]];
                 *  using (var decoder = new Lz4DecoderStream(new MemoryStream(compressedBytes)))
                 *  {
                 *      decoder.Read(decompressedBytes, 0, (int)shader.decompressedLengths[i]);
                 *  }
                 *  using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
                 *  {
                 *      new ShaderProgram(blobReader);
                 *  }
                 * }*/
                return(shader.Dump());
            }
            return(Encoding.UTF8.GetString(shader.m_Script));
        }
Exemplo n.º 20
0
        public static string Convert(this Shader shader)
        {
            if (shader.m_SubProgramBlob != null) //5.3 - 5.4
            {
                var decompressedBytes = new byte[shader.decompressedSize];
                using (var decoder = new Lz4DecoderStream(new MemoryStream(shader.m_SubProgramBlob)))
                {
                    decoder.Read(decompressedBytes, 0, (int)shader.decompressedSize);
                }
                using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
                {
                    var program = new ShaderProgram(blobReader, shader.version);
                    return(header + program.Export(Encoding.UTF8.GetString(shader.m_Script)));
                }
            }

            if (shader.compressedBlob != null) //5.5 and up
            {
                return(header + ConvertSerializedShader(shader));
            }

            return(header + Encoding.UTF8.GetString(shader.m_Script));
        }
Exemplo n.º 21
0
        private void ReadFormat6(EndianStream b_Stream, bool padding = false)
        {
            var bundleSize       = b_Stream.ReadInt64();
            int compressedSize   = b_Stream.ReadInt32();
            int uncompressedSize = b_Stream.ReadInt32();
            int flag             = b_Stream.ReadInt32();

            if (padding)
            {
                b_Stream.ReadByte();
            }
            byte[] blocksInfoBytes;
            if ((flag & 0x80) != 0)//at end of file
            {
                var position = b_Stream.Position;
                b_Stream.Position = b_Stream.BaseStream.Length - compressedSize;
                blocksInfoBytes   = b_Stream.ReadBytes(compressedSize);
                b_Stream.Position = position;
            }
            else
            {
                blocksInfoBytes = b_Stream.ReadBytes(compressedSize);
            }
            EndianStream blocksInfo;

            switch (flag & 0x3F)
            {
            default:    //None
            {
                blocksInfo = new EndianStream(new MemoryStream(blocksInfoBytes), EndianType.BigEndian);
                break;
            }

            case 1:    //LZMA
            {
                blocksInfo = new EndianStream(SevenZipHelper.StreamDecompress(new MemoryStream(blocksInfoBytes)), EndianType.BigEndian);
                break;
            }

            case 2:    //LZ4
            case 3:    //LZ4HC
            {
                byte[] uncompressedBytes = new byte[uncompressedSize];
                using (var mstream = new MemoryStream(blocksInfoBytes))
                {
                    var decoder = new Lz4DecoderStream(mstream);
                    decoder.Read(uncompressedBytes, 0, uncompressedSize);
                    decoder.Dispose();
                }
                blocksInfo = new EndianStream(new MemoryStream(uncompressedBytes), EndianType.BigEndian);
                break;
            }
                //case 4:LZHAM?
            }
            using (blocksInfo)
            {
                blocksInfo.Position = 0x10;
                int          blockcount = blocksInfo.ReadInt32();
                EndianStream assetsData;
                var          assetsDataStream = new MemoryStream();
                for (int i = 0; i < blockcount; i++)
                {
                    uncompressedSize = blocksInfo.ReadInt32();
                    compressedSize   = blocksInfo.ReadInt32();
                    flag             = blocksInfo.ReadInt16();
                    var compressedBytes = b_Stream.ReadBytes(compressedSize);
                    switch (flag & 0x3F)
                    {
                    default:    //None
                    {
                        assetsDataStream.Write(compressedBytes, 0, compressedSize);
                        break;
                    }

                    case 1:    //LZMA
                    {
                        var uncompressedBytes = new byte[uncompressedSize];
                        using (var mstream = new MemoryStream(compressedBytes))
                        {
                            var decoder = SevenZipHelper.StreamDecompress(mstream, uncompressedSize);
                            decoder.Read(uncompressedBytes, 0, uncompressedSize);
                            decoder.Dispose();
                        }
                        assetsDataStream.Write(uncompressedBytes, 0, uncompressedSize);
                        break;
                    }

                    case 2:    //LZ4
                    case 3:    //LZ4HC
                    {
                        var uncompressedBytes = new byte[uncompressedSize];
                        using (var mstream = new MemoryStream(compressedBytes))
                        {
                            var decoder = new Lz4DecoderStream(mstream);
                            decoder.Read(uncompressedBytes, 0, uncompressedSize);
                            decoder.Dispose();
                        }
                        assetsDataStream.Write(uncompressedBytes, 0, uncompressedSize);
                        break;
                    }
                        //case 4:LZHAM?
                    }
                }
                assetsData = new EndianStream(assetsDataStream, EndianType.BigEndian);
                using (assetsData)
                {
                    var entryinfo_count = blocksInfo.ReadInt32();
                    for (int i = 0; i < entryinfo_count; i++)
                    {
                        var memFile          = new MemoryAssetsFile();
                        var entryinfo_offset = blocksInfo.ReadInt64();
                        var entryinfo_size   = blocksInfo.ReadInt64();
                        var unknown          = blocksInfo.ReadInt32();
                        memFile.fileName    = blocksInfo.ReadStringToNull();
                        assetsData.Position = entryinfo_offset;
                        var buffer = new byte[entryinfo_size];
                        assetsData.Read(buffer, 0, (int)entryinfo_size);
                        memFile.memStream = new MemoryStream(buffer);
                        MemoryAssetsFileList.Add(memFile);
                    }
                }
            }
        }
Exemplo n.º 22
0
        public bool Unpack(AssetsFileReader reader, AssetsFileWriter writer)
        {
            reader.Position = 0;
            if (Read(reader, true))
            {
                reader.Position = bundleHeader6.GetBundleInfoOffset();
                MemoryStream     blocksInfoStream;
                AssetsFileReader memReader;
                int compressedSize = (int)bundleHeader6.compressedSize;
                switch (bundleHeader6.GetCompressionType())
                {
                case 1:
                    using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize)))
                    {
                        blocksInfoStream = SevenZipHelper.StreamDecompress(mstream);
                    }
                    break;

                case 2:
                case 3:
                    byte[] uncompressedBytes = new byte[bundleHeader6.decompressedSize];
                    using (MemoryStream mstream = new MemoryStream(reader.ReadBytes(compressedSize)))
                    {
                        var decoder = new Lz4DecoderStream(mstream);
                        decoder.Read(uncompressedBytes, 0, (int)bundleHeader6.decompressedSize);
                        decoder.Dispose();
                    }
                    blocksInfoStream = new MemoryStream(uncompressedBytes);
                    break;

                default:
                    blocksInfoStream = null;
                    break;
                }
                if (bundleHeader6.GetCompressionType() != 0)
                {
                    using (memReader = new AssetsFileReader(blocksInfoStream))
                    {
                        memReader.Position = 0;
                        bundleInf6.Read(0, memReader);
                    }
                }
                AssetBundleHeader06 newBundleHeader6 = new AssetBundleHeader06()
                {
                    signature         = bundleHeader6.signature,
                    fileVersion       = bundleHeader6.fileVersion,
                    minPlayerVersion  = bundleHeader6.minPlayerVersion,
                    fileEngineVersion = bundleHeader6.fileEngineVersion,
                    totalFileSize     = 0,
                    compressedSize    = bundleHeader6.decompressedSize,
                    decompressedSize  = bundleHeader6.decompressedSize,
                    flags             = bundleHeader6.flags & 0x40 //set compression and block position to 0
                };
                long fileSize = newBundleHeader6.GetFileDataOffset();
                for (int i = 0; i < bundleInf6.blockCount; i++)
                {
                    fileSize += bundleInf6.blockInf[i].decompressedSize;
                }
                newBundleHeader6.totalFileSize = fileSize;
                AssetBundleBlockAndDirectoryList06 newBundleInf6 = new AssetBundleBlockAndDirectoryList06()
                {
                    checksumLow    = 0, //-todo, figure out how to make real checksums, uabe sets these to 0 too
                    checksumHigh   = 0,
                    blockCount     = bundleInf6.blockCount,
                    directoryCount = bundleInf6.directoryCount
                };
                newBundleInf6.blockInf = new AssetBundleBlockInfo06[newBundleInf6.blockCount];
                for (int i = 0; i < newBundleInf6.blockCount; i++)
                {
                    newBundleInf6.blockInf[i] = new AssetBundleBlockInfo06()
                    {
                        compressedSize   = bundleInf6.blockInf[i].decompressedSize,
                        decompressedSize = bundleInf6.blockInf[i].decompressedSize,
                        flags            = (ushort)(bundleInf6.blockInf[i].flags & 0xC0) //set compression to none
                    };
                }
                newBundleInf6.dirInf = new AssetBundleDirectoryInfo06[newBundleInf6.directoryCount];
                for (int i = 0; i < newBundleInf6.directoryCount; i++)
                {
                    newBundleInf6.dirInf[i] = new AssetBundleDirectoryInfo06()
                    {
                        offset           = bundleInf6.dirInf[i].offset,
                        decompressedSize = bundleInf6.dirInf[i].decompressedSize,
                        flags            = bundleInf6.dirInf[i].flags,
                        name             = bundleInf6.dirInf[i].name
                    };
                }
                newBundleHeader6.Write(writer);
                if (newBundleHeader6.fileVersion >= 7)
                {
                    writer.Align16();
                }
                newBundleInf6.Write(writer);

                reader.Position = bundleHeader6.GetFileDataOffset();
                for (int i = 0; i < newBundleInf6.blockCount; i++)
                {
                    AssetBundleBlockInfo06 info = bundleInf6.blockInf[i];
                    switch (info.GetCompressionType())
                    {
                    case 0:
                        reader.BaseStream.CopyToCompat(writer.BaseStream, info.compressedSize);
                        break;

                    case 1:
                        SevenZipHelper.StreamDecompress(reader.BaseStream, writer.BaseStream, info.compressedSize, info.decompressedSize);
                        break;

                    case 2:
                    case 3:
                        using (MemoryStream tempMs = new MemoryStream())
                        {
                            reader.BaseStream.CopyToCompat(tempMs, info.compressedSize);
                            tempMs.Position = 0;

                            using (Lz4DecoderStream decoder = new Lz4DecoderStream(tempMs))
                            {
                                decoder.CopyToCompat(writer.BaseStream, info.decompressedSize);
                            }
                        }
                        break;
                    }
                }
                return(true);
            }
            return(false);
        }
Exemplo n.º 23
0
        private ContentReader GetContentReaderFromXnb(string originalAssetName, ref Stream stream, BinaryReader xnbReader, Action <IDisposable> recordDisposableObject)
        {
            // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file
            byte x        = xnbReader.ReadByte();
            byte n        = xnbReader.ReadByte();
            byte b        = xnbReader.ReadByte();
            byte platform = xnbReader.ReadByte();

            if (x != 'X' || n != 'N' || b != 'B' ||
                !(targetPlatformIdentifiers.Contains((char)platform)))
            {
                throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
            }

            byte version = xnbReader.ReadByte();
            byte flags   = xnbReader.ReadByte();

            bool compressedLzx = (flags & ContentCompressedLzx) != 0;
            bool compressedLz4 = (flags & ContentCompressedLz4) != 0;

            if (version != 5 && version != 4)
            {
                throw new ContentLoadException("Invalid XNB version");
            }

            // The next int32 is the length of the XNB file
            int xnbLength = xnbReader.ReadInt32();

            ContentReader reader;

            if (compressedLzx || compressedLz4)
            {
                // Decompress the xnb
                int          decompressedSize   = xnbReader.ReadInt32();
                MemoryStream decompressedStream = null;

                if (compressedLzx)
                {
                    //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
                    // default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
                    LzxDecoder dec = new LzxDecoder(16);
                    decompressedStream = new MemoryStream(decompressedSize);
                    int  compressedSize = xnbLength - 14;
                    long startPos       = stream.Position;
                    long pos            = startPos;

                    while (pos - startPos < compressedSize)
                    {
                        // the compressed stream is seperated into blocks that will decompress
                        // into 32Kb or some other size if specified.
                        // normal, 32Kb output blocks will have a short indicating the size
                        // of the block before the block starts
                        // blocks that have a defined output will be preceded by a byte of value
                        // 0xFF (255), then a short indicating the output size and another
                        // for the block size
                        // all shorts for these cases are encoded in big endian order
                        int hi         = stream.ReadByte();
                        int lo         = stream.ReadByte();
                        int block_size = (hi << 8) | lo;
                        int frame_size = 0x8000; // frame size is 32Kb by default
                        // does this block define a frame size?
                        if (hi == 0xFF)
                        {
                            hi         = lo;
                            lo         = (byte)stream.ReadByte();
                            frame_size = (hi << 8) | lo;
                            hi         = (byte)stream.ReadByte();
                            lo         = (byte)stream.ReadByte();
                            block_size = (hi << 8) | lo;
                            pos       += 5;
                        }
                        else
                        {
                            pos += 2;
                        }

                        // either says there is nothing to decode
                        if (block_size == 0 || frame_size == 0)
                        {
                            break;
                        }

                        dec.Decompress(stream, block_size, decompressedStream, frame_size);
                        pos += block_size;

                        // reset the position of the input just incase the bit buffer
                        // read in some unused bytes
                        stream.Seek(pos, SeekOrigin.Begin);
                    }

                    if (decompressedStream.Position != decompressedSize)
                    {
                        throw new ContentLoadException("Decompression of " + originalAssetName + " failed. ");
                    }

                    decompressedStream.Seek(0, SeekOrigin.Begin);
                }
                else if (compressedLz4)
                {
                    // Decompress to a byte[] because Windows 8 doesn't support MemoryStream.GetBuffer()
                    var buffer = new byte[decompressedSize];
                    using (var decoderStream = new Lz4DecoderStream(stream))
                    {
                        if (decoderStream.Read(buffer, 0, buffer.Length) != decompressedSize)
                        {
                            throw new ContentLoadException("Decompression of " + originalAssetName + " failed. ");
                        }
                    }
                    // Creating the MemoryStream with a byte[] shares the buffer so it doesn't allocate any more memory
                    decompressedStream = new MemoryStream(buffer);
                }

                reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice,
                                           originalAssetName, version, recordDisposableObject);
            }
            else
            {
                reader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice,
                                           originalAssetName, version, recordDisposableObject);
            }
            return(reader);
        }
Exemplo n.º 24
0
        private void ReadFormat6(EndianBinaryReader bundleReader, bool padding = false)
        {
            var bundleSize       = bundleReader.ReadInt64();
            int compressedSize   = bundleReader.ReadInt32();
            int uncompressedSize = bundleReader.ReadInt32();
            int flag             = bundleReader.ReadInt32();

            if (padding)
            {
                bundleReader.ReadByte();
            }
            byte[] blocksInfoBytes;
            if ((flag & 0x80) != 0)//at end of file
            {
                var position = bundleReader.Position;
                bundleReader.Position = bundleReader.BaseStream.Length - compressedSize;
                blocksInfoBytes       = bundleReader.ReadBytes(compressedSize);
                bundleReader.Position = position;
            }
            else
            {
                blocksInfoBytes = bundleReader.ReadBytes(compressedSize);
            }
            var          blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
            MemoryStream blocksInfoDecompressedStream;

            switch (flag & 0x3F)
            {
            default:    //None
            {
                blocksInfoDecompressedStream = blocksInfoCompressedStream;
                break;
            }

            case 1:    //LZMA
            {
                blocksInfoDecompressedStream = SevenZipHelper.StreamDecompress(blocksInfoCompressedStream);
                blocksInfoCompressedStream.Close();
                break;
            }

            case 2:    //LZ4
            case 3:    //LZ4HC
            {
                byte[] uncompressedBytes = new byte[uncompressedSize];
                using (var decoder = new Lz4DecoderStream(blocksInfoCompressedStream))
                {
                    decoder.Read(uncompressedBytes, 0, uncompressedSize);
                }
                blocksInfoDecompressedStream = new MemoryStream(uncompressedBytes);
                break;
            }
                //case 4:LZHAM?
            }
            using (var blocksInfoReader = new EndianBinaryReader(blocksInfoDecompressedStream))
            {
                blocksInfoReader.Position = 0x10;
                int blockcount = blocksInfoReader.ReadInt32();
                var blockInfos = new BlockInfo[blockcount];
                for (int i = 0; i < blockcount; i++)
                {
                    blockInfos[i] = new BlockInfo
                    {
                        uncompressedSize = blocksInfoReader.ReadUInt32(),
                        compressedSize   = blocksInfoReader.ReadUInt32(),
                        flag             = blocksInfoReader.ReadInt16()
                    };
                }
                Stream dataStream;
                var    uncompressedSizeSum = blockInfos.Sum(x => x.uncompressedSize);
                if (uncompressedSizeSum > int.MaxValue)
                {
                    /*var memoryMappedFile = MemoryMappedFile.CreateNew(Path.GetFileName(path), uncompressedSizeSum);
                     * assetsDataStream = memoryMappedFile.CreateViewStream();*/
                    dataStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
                }
                else
                {
                    dataStream = new MemoryStream((int)uncompressedSizeSum);
                }
                foreach (var blockInfo in blockInfos)
                {
                    switch (blockInfo.flag & 0x3F)
                    {
                    default:    //None
                    {
                        bundleReader.BaseStream.CopyTo(dataStream, blockInfo.compressedSize);
                        break;
                    }

                    case 1:    //LZMA
                    {
                        SevenZipHelper.StreamDecompress(bundleReader.BaseStream, dataStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
                        break;
                    }

                    case 2:    //LZ4
                    case 3:    //LZ4HC
                    {
                        var lz4Stream = new Lz4DecoderStream(bundleReader.BaseStream, blockInfo.compressedSize);
                        lz4Stream.CopyTo(dataStream, blockInfo.uncompressedSize);
                        break;
                    }
                        //case 4:LZHAM?
                    }
                }
                dataStream.Position = 0;
                using (dataStream)
                {
                    var entryinfo_count = blocksInfoReader.ReadInt32();
                    for (int i = 0; i < entryinfo_count; i++)
                    {
                        var file             = new StreamFile();
                        var entryinfo_offset = blocksInfoReader.ReadInt64();
                        var entryinfo_size   = blocksInfoReader.ReadInt64();
                        flag          = blocksInfoReader.ReadInt32();
                        file.fileName = Path.GetFileName(blocksInfoReader.ReadStringToNull());
                        if (entryinfo_size > int.MaxValue)
                        {
                            /*var memoryMappedFile = MemoryMappedFile.CreateNew(file.fileName, entryinfo_size);
                             * file.stream = memoryMappedFile.CreateViewStream();*/
                            var extractPath = path + "_unpacked\\";
                            Directory.CreateDirectory(extractPath);
                            file.stream = File.Create(extractPath + file.fileName);
                        }
                        else
                        {
                            file.stream = new MemoryStream((int)entryinfo_size);
                        }
                        dataStream.Position = entryinfo_offset;
                        dataStream.CopyTo(file.stream, entryinfo_size);
                        file.stream.Position = 0;
                        fileList.Add(file);
                    }
                }
            }
        }
Exemplo n.º 25
0
        public bool Read(AssetsFileReader reader)
        {
            header = new ClassDatabasePackageHeader();
            header.Read(reader);
            files = new List <ClassDatabaseFile>();
            long             firstFile = reader.Position;
            AssetsFileReader newReader = reader;

            if ((header.compressionType & 0x80) == 0) //multiple compressed blocks
            {
                //untested!
                //the compression is handled by the cldbs themselves
                for (int i = 0; i < header.fileCount; i++)
                {
                    newReader.Position = firstFile + header.files[i].offset;
                    byte[] data = newReader.ReadBytes((int)header.files[i].length);
                    using (MemoryStream ms = new MemoryStream(data))
                        using (AssetsFileReader r = new AssetsFileReader(ms))
                        {
                            ClassDatabaseFile file = new ClassDatabaseFile();
                            file.Read(r);
                            files.Add(file);
                        }
                }
            }
            else //one compressed block
            {
                if ((header.compressionType & 0x20) == 0) //file block compressed
                {
                    firstFile = 0;
                    int          compressedSize   = (int)(header.stringTableOffset - newReader.Position);
                    int          uncompressedSize = (int)header.fileBlockSize;
                    MemoryStream ms;
                    if ((header.compressionType & 0x1f) == 1) //lz4
                    {
                        byte[] uncompressedBytes = new byte[uncompressedSize];
                        using (MemoryStream tempMs = new MemoryStream(newReader.ReadBytes(compressedSize)))
                        {
                            Lz4DecoderStream decoder = new Lz4DecoderStream(tempMs);
                            decoder.Read(uncompressedBytes, 0, uncompressedSize);
                            decoder.Dispose();
                        }
                        ms = new MemoryStream(uncompressedBytes);
                    }
                    else if ((header.compressionType & 0x1f) == 2) //lzma
                    {
                        byte[] dbg = newReader.ReadBytes(compressedSize);
                        using (MemoryStream tempMs = new MemoryStream(dbg))
                        {
                            ms = SevenZipHelper.StreamDecompress(tempMs, uncompressedSize);
                        }
                    }
                    else
                    {
                        valid = false;
                        return(valid);
                    }

                    newReader           = new AssetsFileReader(ms);
                    newReader.bigEndian = false;
                }
                for (int i = 0; i < header.fileCount; i++)
                {
                    newReader.Position = firstFile + header.files[i].offset;
                    byte[] data = newReader.ReadBytes((int)header.files[i].length);
                    using (MemoryStream ms = new MemoryStream(data))
                        using (AssetsFileReader r = new AssetsFileReader(ms))
                        {
                            ClassDatabaseFile file = new ClassDatabaseFile();
                            file.Read(r);
                            files.Add(file);
                        }
                }
            }

            newReader          = reader;
            newReader.Position = header.stringTableOffset;
            if ((header.compressionType & 0x40) == 0) //string table is compressed
            {
                int          compressedSize   = (int)header.stringTableLenCompressed;
                int          uncompressedSize = (int)header.stringTableLenUncompressed;
                MemoryStream ms;
                if ((header.compressionType & 0x1f) == 1) //lz4
                {
                    byte[] uncompressedBytes = new byte[uncompressedSize];
                    using (MemoryStream tempMs = new MemoryStream(newReader.ReadBytes(compressedSize)))
                    {
                        Lz4DecoderStream decoder = new Lz4DecoderStream(tempMs);
                        decoder.Read(uncompressedBytes, 0, uncompressedSize);
                        decoder.Dispose();
                    }
                    ms = new MemoryStream(uncompressedBytes);
                }
                else if ((header.compressionType & 0x1f) == 2) //lzma
                {
                    using (MemoryStream tempMs = new MemoryStream(newReader.ReadBytes(compressedSize)))
                    {
                        ms = SevenZipHelper.StreamDecompress(tempMs, uncompressedSize);
                    }
                }
                else
                {
                    valid = false;
                    return(valid);
                }

                newReader           = new AssetsFileReader(ms);
                newReader.bigEndian = false;
            }
            stringTable = newReader.ReadBytes((int)header.stringTableLenUncompressed);
            for (int i = 0; i < header.fileCount; i++)
            {
                files[i].stringTable = stringTable;
            }

            valid = true;
            return(valid);
        }
Exemplo n.º 26
0
        ///public bool Write(AssetsFileReader reader, LPARAM readerPar,
        ///    AssetsFileWriter writer, LPARAM writerPar,
        ///
        ///    class BundleReplacer **pReplacers, size_t replacerCount,
        ///    AssetsFileVerifyLogger errorLogger = NULL, ClassDatabaseFile* typeMeta = NULL);
        //-todo, use a faster custom bundle decompressor. currently a copy paste of unity studio's
        public bool Unpack(AssetsFileReader reader, AssetsFileWriter writer)
        {
            if (Read(reader, true))
            {
                reader.Position = bundleHeader6.GetBundleInfoOffset();
                MemoryStream     blocksInfoStream;
                AssetsFileReader memReader;
                switch (bundleHeader6.flags & 0x3F)
                {
                case 1:
                    blocksInfoStream = SevenZipHelper.StreamDecompress(new MemoryStream(reader.ReadBytes((int)bundleHeader6.compressedSize)));
                    break;

                case 2:
                case 3:
                    byte[] uncompressedBytes = new byte[bundleHeader6.decompressedSize];
                    using (var mstream = new MemoryStream(reader.ReadBytes((int)bundleHeader6.compressedSize)))
                    {
                        var decoder = new Lz4DecoderStream(mstream);
                        decoder.Read(uncompressedBytes, 0, (int)bundleHeader6.decompressedSize);
                        decoder.Dispose();
                    }
                    blocksInfoStream = new MemoryStream(uncompressedBytes);
                    break;

                default:
                    blocksInfoStream = null;
                    break;
                }
                if ((bundleHeader6.flags & 0x3F) != 0)
                {
                    using (memReader = new AssetsFileReader(blocksInfoStream))
                    {
                        bundleInf6.Read(0, memReader);
                    }
                }
                reader.Position = bundleHeader6.GetFileDataOffset();
                byte[][] blocksData = new byte[bundleInf6.blockCount][];
                for (int i = 0; i < bundleInf6.blockCount; i++)
                {
                    AssetsBundleBlockInfo06 info = bundleInf6.blockInf[i];
                    byte[] data = reader.ReadBytes((int)info.compressedSize);
                    switch (info.flags & 0x3F)
                    {
                    case 0:
                        blocksData[i] = data;
                        break;

                    case 1:
                        blocksData[i] = new byte[info.decompressedSize];
                        using (MemoryStream mstream = new MemoryStream(data))
                        {
                            MemoryStream decoder = SevenZipHelper.StreamDecompress(mstream, info.decompressedSize);
                            decoder.Read(blocksData[i], 0, (int)info.decompressedSize);
                            decoder.Dispose();
                        }
                        break;

                    case 2:
                    case 3:
                        blocksData[i] = new byte[info.decompressedSize];
                        using (MemoryStream mstream = new MemoryStream(data))
                        {
                            var decoder = new Lz4DecoderStream(mstream);
                            decoder.Read(blocksData[i], 0, (int)info.decompressedSize);
                            decoder.Dispose();
                        }
                        break;
                    }
                }
                AssetsBundleHeader06 newBundleHeader6 = new AssetsBundleHeader06()
                {
                    signature         = bundleHeader6.signature,
                    fileVersion       = bundleHeader6.fileVersion,
                    minPlayerVersion  = bundleHeader6.minPlayerVersion,
                    fileEngineVersion = bundleHeader6.fileEngineVersion,
                    totalFileSize     = 0,
                    compressedSize    = bundleHeader6.decompressedSize,
                    decompressedSize  = bundleHeader6.decompressedSize,
                    flags             = bundleHeader6.flags & 0x40 //set compression and block position to 0
                };
                ulong fileSize = newBundleHeader6.GetFileDataOffset();
                for (int i = 0; i < bundleInf6.blockCount; i++)
                {
                    fileSize += bundleInf6.blockInf[i].decompressedSize;
                }
                newBundleHeader6.totalFileSize = fileSize;
                AssetsBundleBlockAndDirectoryList06 newBundleInf6 = new AssetsBundleBlockAndDirectoryList06()
                {
                    checksumLow    = 0, //-todo, figure out how to make real checksums, uabe sets these to 0 too
                    checksumHigh   = 0,
                    blockCount     = bundleInf6.blockCount,
                    directoryCount = bundleInf6.directoryCount
                };
                newBundleInf6.blockInf = new AssetsBundleBlockInfo06[newBundleInf6.blockCount];
                for (int i = 0; i < newBundleInf6.blockCount; i++)
                {
                    newBundleInf6.blockInf[i] = new AssetsBundleBlockInfo06();
                    newBundleInf6.blockInf[i].compressedSize   = bundleInf6.blockInf[i].decompressedSize;
                    newBundleInf6.blockInf[i].decompressedSize = bundleInf6.blockInf[i].decompressedSize;
                    newBundleInf6.blockInf[i].flags            = (ushort)(bundleInf6.blockInf[i].flags & 0xC0); //set compression to none
                }
                newBundleInf6.dirInf = new AssetsBundleDirectoryInfo06[newBundleInf6.directoryCount];
                for (int i = 0; i < newBundleInf6.directoryCount; i++)
                {
                    newBundleInf6.dirInf[i].offset           = bundleInf6.dirInf[i].offset;
                    newBundleInf6.dirInf[i].decompressedSize = bundleInf6.dirInf[i].decompressedSize;
                    newBundleInf6.dirInf[i].flags            = bundleInf6.dirInf[i].flags;
                    newBundleInf6.dirInf[i].name             = bundleInf6.dirInf[i].name;
                }
                newBundleHeader6.Write(writer, 0);
                newBundleInf6.Write(writer, writer.Position);
                for (int i = 0; i < newBundleInf6.blockCount; i++)
                {
                    writer.Write(blocksData[i]);
                }
                return(true);
            }
            return(false);
        }
Exemplo n.º 27
0
        public Shader(AssetPreloadData preloadData, bool readSwitch)
        {
            var sourceFile = preloadData.sourceFile;
            var a_Stream   = preloadData.sourceFile.a_Stream;

            a_Stream.Position = preloadData.Offset;

            if (sourceFile.platform == -2)
            {
                uint m_ObjectHideFlags    = a_Stream.ReadUInt32();
                PPtr m_PrefabParentObject = sourceFile.ReadPPtr();
                PPtr m_PrefabInternal     = sourceFile.ReadPPtr();
            }

            m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32());

            if (readSwitch)
            {
                if (true)
                {
                    //Assume as unity 5.6 or greater.
                    var str1 = preloadData.ViewStruct();
                    if (str1 == null)
                    {
                        m_Script = Encoding.UTF8.GetBytes("Serialized Shader can't be read");
                    }
                    else
                    {
                        m_Script = Encoding.UTF8.GetBytes(str1);
                    }
                    return;
                }

                /**
                 * SHORTCUT:
                 * System.Resources.MissingManifestResourceException: Could not find
                 * any resources appropriate for the specified culture or the neutral
                 * culture.  Make sure "Unity_Studio.ShaderResource.resources" was
                 * correctly embedded or linked into assembly "adebug" at compile
                 * time, or that all the satellite assemblies required are loadable
                 * and fully signed.
                 */
                if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 5 || sourceFile.version[0] > 5)//5.5.0 and up
                {
                    var str = (string)ShaderResource.ResourceManager.GetObject($"Shader{sourceFile.version[0]}{sourceFile.version[1]}");
                    if (str == null)
                    {
                        str = preloadData.ViewStruct();
                        if (str == null)
                        {
                            m_Script = Encoding.UTF8.GetBytes("Serialized Shader can't be read");
                        }
                        else
                        {
                            m_Script = Encoding.UTF8.GetBytes(str);
                        }
                    }
                    else
                    {
                        a_Stream.Position = preloadData.Offset;
                        var sb      = new StringBuilder();
                        var members = new JavaScriptSerializer().Deserialize <List <ClassMember> >(str);
                        ClassStructHelper.ReadClassStruct(sb, members, a_Stream);
                        m_Script = Encoding.UTF8.GetBytes(sb.ToString());
                        //m_Script = ReadSerializedShader(members, a_Stream);
                    }
                }
                else
                {
                    m_Script = a_Stream.ReadBytes(a_Stream.ReadInt32());
                    if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 3) //5.3 - 5.4
                    {
                        a_Stream.AlignStream(4);
                        a_Stream.ReadAlignedString(a_Stream.ReadInt32());//m_PathName
                        var decompressedSize  = a_Stream.ReadUInt32();
                        var m_SubProgramBlob  = a_Stream.ReadBytes(a_Stream.ReadInt32());
                        var decompressedBytes = new byte[decompressedSize];
                        using (var mstream = new MemoryStream(m_SubProgramBlob))
                        {
                            var decoder = new Lz4DecoderStream(mstream);
                            decoder.Read(decompressedBytes, 0, (int)decompressedSize);
                            decoder.Dispose();
                        }
                        m_Script = m_Script.Concat(decompressedBytes.ToArray()).ToArray();
                    }
                }
            }
            else
            {
                preloadData.extension = ".txt";
                preloadData.Text      = m_Name;
            }
        }
Exemplo n.º 28
0
        public Stream OpenAsset(string assetName)
        {
            MemoryStream fileStream = null;
            var          fileNode   = Array.Find(m_DirectoryInfo, node => node.path == assetName);

            if (fileNode != null)
            {
                long skipUncompressed = 0;
                foreach (var blockInfo in m_BlocksInfo)
                {
                    if (fileStream == null)
                    {
                        if (skipUncompressed + blockInfo.uncompressedSize >= fileNode.offset)
                        {
                            fileStream = new MemoryStream();
                        }
                        else
                        {
                            skipUncompressed += blockInfo.uncompressedSize;
                        }
                    }

                    if (fileStream != null)
                    {
                        reader.Position = blockInfo.offset;
                        var    compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize));
                        byte[] buffer           = new byte[blockInfo.uncompressedSize];

                        using (MemoryStream unCompressStream = new MemoryStream())
                        {
                            using (var lz4Stream = new Lz4DecoderStream(compressedStream))
                            {
                                lz4Stream.CopyTo(unCompressStream);
                            }
                            long begin = 0;
                            if (fileStream.Length == 0)
                            {
                                begin = fileNode.offset - skipUncompressed;
                                if (begin < 0)
                                {
                                    begin = 0;
                                }
                            }
                            unCompressStream.Seek(0, 0);

                            int end = (int)(blockInfo.uncompressedSize - (fileNode.size - fileStream.Position));
                            if (end < 0)
                            {
                                end = 0;
                            }

                            int size  = (int)(blockInfo.uncompressedSize - begin - end);
                            int count = unCompressStream.Read(buffer, (int)begin, size);
                            fileStream.Write(buffer, 0, count);
                            if (fileStream.Length >= fileNode.size)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            fileStream?.Seek(0, 0);
            return(fileStream);
        }
Exemplo n.º 29
0
        private static byte[] ReadSerializedShader(List <ClassMember> members, EndianStream a_Stream)
        {
            var offsets             = new List <uint>();
            var compressedLengths   = new List <uint>();
            var decompressedLengths = new List <uint>();

            for (int i = 0; i < members.Count; i++)
            {
                var member     = members[i];
                var level      = member.Level;
                var varTypeStr = member.Type;
                if (member.Name == "offsets")
                {
                    var offsets_size = a_Stream.ReadInt32();
                    for (int j = 0; j < offsets_size; j++)
                    {
                        offsets.Add(a_Stream.ReadUInt32());
                    }
                    var compressedLengths_size = a_Stream.ReadInt32();
                    for (int j = 0; j < compressedLengths_size; j++)
                    {
                        compressedLengths.Add(a_Stream.ReadUInt32());
                    }
                    var decompressedLengths_size = a_Stream.ReadInt32();
                    for (int j = 0; j < decompressedLengths_size; j++)
                    {
                        decompressedLengths.Add(a_Stream.ReadUInt32());
                    }
                    var compressedBlob     = a_Stream.ReadBytes(a_Stream.ReadInt32());
                    var decompressedStream = new MemoryStream();
                    for (int j = 0; j < offsets.Count; j++)
                    {
                        var compressedBytes = new byte[compressedLengths[j]];
                        Array.Copy(compressedBlob, offsets[j], compressedBytes, 0, compressedLengths[j]);
                        var decompressedBytes = new byte[decompressedLengths[j]];
                        using (var mstream = new MemoryStream(compressedBytes))
                        {
                            var decoder = new Lz4DecoderStream(mstream);
                            decoder.Read(decompressedBytes, 0, (int)decompressedLengths[j]);
                            decoder.Dispose();
                        }
                        decompressedStream.Write(decompressedBytes, 0, decompressedBytes.Length);
                    }
                    var decompressedBlob = decompressedStream.ToArray();
                    return(decompressedBlob);
                }
                var align = (member.Flag & 0x4000) != 0;
                if (varTypeStr == "SInt8")//sbyte
                {
                    a_Stream.ReadSByte();
                }
                else if (varTypeStr == "UInt8")//byte
                {
                    a_Stream.ReadByte();
                }
                else if (varTypeStr == "short" || varTypeStr == "SInt16")//Int16
                {
                    a_Stream.ReadInt16();
                }
                else if (varTypeStr == "UInt16" || varTypeStr == "unsigned short")//UInt16
                {
                    a_Stream.ReadUInt16();
                }
                else if (varTypeStr == "int" || varTypeStr == "SInt32")//Int32
                {
                    a_Stream.ReadInt32();
                }
                else if (varTypeStr == "UInt32" || varTypeStr == "unsigned int")//UInt32
                {
                    a_Stream.ReadUInt32();
                }
                else if (varTypeStr == "long long" || varTypeStr == "SInt64")//Int64
                {
                    a_Stream.ReadInt64();
                }
                else if (varTypeStr == "UInt64" || varTypeStr == "unsigned long long")//UInt64
                {
                    a_Stream.ReadUInt64();
                }
                else if (varTypeStr == "float")//float
                {
                    a_Stream.ReadSingle();
                }
                else if (varTypeStr == "double")//double
                {
                    a_Stream.ReadDouble();
                }
                else if (varTypeStr == "bool")//bool
                {
                    a_Stream.ReadBoolean();
                }
                else if (varTypeStr == "string")//string
                {
                    a_Stream.ReadAlignedString(a_Stream.ReadInt32());
                    i += 3;                     //skip
                }
                else if (varTypeStr == "Array") //Array
                {
                    if ((members[i - 1].Flag & 0x4000) != 0)
                    {
                        align = true;
                    }
                    var size  = a_Stream.ReadInt32();
                    var array = AssetPreloadData.ReadArray(members, level, i);
                    for (int j = 0; j < size; j++)
                    {
                        ReadSerializedShader(array, a_Stream);
                    }
                    i += array.Count + 1;//skip
                }
                else
                {
                    align = false;
                }
                if (align)
                {
                    a_Stream.AlignStream(4);
                }
            }
            return(null);
        }
Exemplo n.º 30
0
        private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader)
        {
            byte[] blocksInfoBytes;
            if (m_Header.version >= 7)
            {
                reader.AlignStream(16);
            }
            if ((m_Header.flags & 0x80) != 0) //kArchiveBlocksInfoAtTheEnd
            {
                var position = reader.Position;
                reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
                reader.Position = position;
            }
            else //0x40 kArchiveBlocksAndDirectoryInfoCombined
            {
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
            }
            var          blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
            MemoryStream blocksInfoUncompresseddStream;

            switch (m_Header.flags & 0x3F) //kArchiveCompressionTypeMask
            {
            default:                       //None
            {
                blocksInfoUncompresseddStream = blocksInfoCompressedStream;
                break;
            }

            case 2:     //LZ4
            case 3:     //LZ4HC
            {
                var uncompressedBytes = new byte[m_Header.uncompressedBlocksInfoSize];
                using (var decoder = new Lz4DecoderStream(blocksInfoCompressedStream))
                {
                    decoder.Read(uncompressedBytes, 0, uncompressedBytes.Length);
                }
                blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
                break;
            }
            }
            using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
            {
                var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
                var blocksInfoCount      = blocksInfoReader.ReadInt32();
                m_BlocksInfo = new StorageBlock[blocksInfoCount];
                uint offset = 0;
                for (int i = 0; i < blocksInfoCount; i++)
                {
                    m_BlocksInfo[i] = new StorageBlock
                    {
                        offset           = offset,
                        uncompressedSize = blocksInfoReader.ReadUInt32(),
                        compressedSize   = blocksInfoReader.ReadUInt32(),
                        flags            = blocksInfoReader.ReadUInt16()
                    };
                    offset += m_BlocksInfo[i].compressedSize;
                }

                var nodesCount = blocksInfoReader.ReadInt32();
                m_DirectoryInfo = new Node[nodesCount];
                for (int i = 0; i < nodesCount; i++)
                {
                    m_DirectoryInfo[i] = new Node
                    {
                        offset = blocksInfoReader.ReadInt64(),
                        size   = blocksInfoReader.ReadInt64(),
                        flags  = blocksInfoReader.ReadUInt32(),
                        path   = blocksInfoReader.ReadStringToNull(),
                    };
                }
            }
        }