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);
        }
Beispiel #2
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();
                }
            }
        }
Beispiel #3
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);
        }
Beispiel #4
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);
                }
            }
        }
        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
            }
        }
Beispiel #6
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() });
            }
        }
Beispiel #7
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;
            }
        }
Beispiel #8
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));
        }
Beispiel #9
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);
        }
 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);
         }
     }
 }
Beispiel #11
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);
                    }
                }
            }
        }
Beispiel #12
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;
                }
            }
        }
Beispiel #13
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);
                }
            }
        }
Beispiel #14
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));
        }
Beispiel #15
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));
        }
Beispiel #16
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));
        }
Beispiel #17
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);
        }
        private long ReadBlocksInfoAndDirectory(EndianBinaryReader varReader)
        {
            byte[] blocksInfoBytes;
            if (HeaderInfo.version >= 7)
            {
                varReader.AlignStream(16);
            }
            if ((HeaderInfo.flags & (int)ArchiveFlags.kArchiveBlocksInfoAtTheEnd) != 0)
            {
                var tempPosition = varReader.Position;
                {
                    varReader.Position = varReader.BaseStream.Length - HeaderInfo.compressedBlocksInfoSize;
                    blocksInfoBytes    = varReader.ReadBytes((int)HeaderInfo.compressedBlocksInfoSize);
                }
                varReader.Position = tempPosition;
            }
            else //0x40 kArchiveBlocksAndDirectoryInfoCombined
            {
                blocksInfoBytes = varReader.ReadBytes((int)HeaderInfo.compressedBlocksInfoSize);
            }
            var          blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
            MemoryStream blocksInfoUncompresseddStream;

            switch (HeaderInfo.GetBlocksInfoCompressionType())
            {
            default:     //None
            {
                blocksInfoUncompresseddStream = blocksInfoCompressedStream;
                break;
            }

            case Compression.CompressionType.kCompressionLzma:
            {
                blocksInfoUncompresseddStream = new MemoryStream((int)(HeaderInfo.uncompressedBlocksInfoSize));
                SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompresseddStream, HeaderInfo.compressedBlocksInfoSize, HeaderInfo.uncompressedBlocksInfoSize);
                blocksInfoUncompresseddStream.Position = 0;
                blocksInfoCompressedStream.Close();
                break;
            }

            case Compression.CompressionType.kCompressionLz4:
            case Compression.CompressionType.kCompressionLz4HC:
            {
                var uncompressedBytes = new byte[HeaderInfo.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();
                BlocksInfo = new List <StorageBlock>(blocksInfoCount);
                for (int i = 0; i < blocksInfoCount; i++)
                {
                    var tempBlock = new StorageBlock().Parse(blocksInfoReader);
                    BlocksInfo.Add(tempBlock);
                }

                var nodesCount = blocksInfoReader.ReadInt32();
                DirectoryInfo = new List <Node>(nodesCount);
                for (int i = 0; i < nodesCount; i++)
                {
                    var tempDirInfo = new Node().Parse(blocksInfoReader);
                    DirectoryInfo.Add(tempDirInfo);
                }
            }

            return(varReader.Position);
        }
Beispiel #19
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);
                    }
                }
            }
        }
Beispiel #20
0
        unsafe void ReFillrbr(ReaderBE rbr, int uncompsize, uint flags)
        {
            byte[] buf;
            switch (flags & 0x3F)
            {
            default:                     //None

                break;

            case 1:
                buf = new byte[uncompsize];
                break;

            case 2:                     //LZ4
            case 3:                     //LZ4HC
                buf = new byte[uncompsize];
                using (var decoder = new Lz4DecoderStream(new MemoryStream(rbr.Bas, rbr.seek, rbr.Bas.Length - rbr.seek)))
                    decoder.Read(buf, 0, uncompsize);

                rbr.Reload(buf);

                break;
            }

            rbr.seek += 0x10;             //uncompressedDataHash
            int blocksInfoCount  = rbr.ri4c();
            CompressedBlocks cb0 = *(CompressedBlocks *)rbr.ReadTc(0);

            if (blocksInfoCount == 1 && cb0.compressedSize == cb0.uncompressedSize)
            {
            }
            else
            {
                compressedblocks = new CompressedBlocks[blocksInfoCount];
                fixed(byte *srcbb = &rbr.Bas[rbr.seek])
                {
                    for (int i = 0; i < blocksInfoCount; i++)
                    {
                        compressedblocks[i] = *(CompressedBlocks *)(srcbb + 0xA * i);
                    }
                }
            }

            rbr.seek += blocksInfoCount * 0xA;

            blocksInfoCount = rbr.ri4c();

            Files = new PackedFiles[blocksInfoCount];
            for (int i = 0; i < blocksInfoCount; i++)
            {
                Files[i] = new PackedFiles
                {
                    Offset = rbr.ru8c(),
                    Size   = rbr.ru8c(),
                    flags  = rbr.ru4c(),
                    Name   = rbr.rStr()
                };
            }

            rbr.Clear();
        }
Beispiel #21
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);
        }
Beispiel #22
0
        public Mhy0File(EndianBinaryReader reader)
        {
            var originalPos = reader.Position;
            var magic       = reader.ReadUInt32();

            if (magic != 0x3079686D)
            {
                throw new Exception("not a mhy0");
            }
            var headerSize = reader.ReadInt32();
            var headerData = reader.ReadBytes(headerSize);

            Scramble(headerData, 0, 0x39, 0x1C);
            //File.WriteAllBytes("decrypted.bin", data);

            var decompressed = DecompressHeader(headerData);
            //File.WriteAllBytes("decompressed.bin", decompressed);

            var cabCount   = ReadScrambledInt2(decompressed, 0); // not the best name
            var entryCount = ReadScrambledInt2(decompressed, cabCount * 0x113 + 6);

            var name = Encoding.UTF8.GetString(decompressed.Skip(6).TakeWhile(b => !b.Equals(0)).ToArray());

            if (name.StartsWith("CAB-"))
            {
                //var id1 = Convert.ToUInt64(name.Substring(4, 16), 16);
                //var id2 = Convert.ToUInt64(name.Substring(20, 16), 16);
                //_id = id1 ^ id2;
                //Console.WriteLine(name.Substring(4));
                _id = new Guid(name.Substring(4));
                //Console.WriteLine(_id);
            }

            var compressedEntrySizes   = new List <int>(entryCount);
            var decompressedEntrySizes = new List <int>(entryCount);

            for (int i = 0; i < entryCount; i++)
            {
                var offset = i * 13 + cabCount * 0x113 + 6;
                compressedEntrySizes.Add(ReadScrambledInt2(decompressed, offset + 6));
                decompressedEntrySizes.Add(ReadScrambledInt1(decompressed, offset + 0xC));
            }

            reader.Position = originalPos + headerSize + 8;
            var finalData    = new byte[decompressedEntrySizes.Sum()];
            var finalDataPos = 0;

            for (int i = 0; i < entryCount; i++)
            {
                var compressedEntry = reader.ReadBytes(compressedEntrySizes[i]);
                if (compressedEntry.Length >= 0x21)
                {
                    Scramble(compressedEntry, 0, 0x21, 8);
                }

                var lz4 = new Lz4DecoderStream(new MemoryStream(compressedEntry, 0xC, compressedEntry.Length - 0xC));
                lz4.Read(finalData, finalDataPos, decompressedEntrySizes[i]);
                finalDataPos += decompressedEntrySizes[i];
            }

            _data = finalData;
        }
Beispiel #23
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(),
                    };
                }
            }
        }
        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);
                    }
                }
            }
        }
Beispiel #25
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;
            }
        }
Beispiel #26
0
        public PIGmodel(string PIGfile)
        {
            using (BinaryReader binStream = new BinaryReader(File.OpenRead(PIGfile)))
            {
                int   marker    = binStream.ReadInt32(); //0x64
                short nodeCount = binStream.ReadInt16();

                for (int n = 0; n < nodeCount; n++)
                {
                    PIGnode newnode = new PIGnode();

                    marker       = binStream.ReadInt32();
                    newnode.name = ReadStr(binStream);
                    byte nbyte = binStream.ReadByte();
                    newnode.parentID = binStream.ReadInt16();

                    newnode.position[0] = binStream.ReadSingle();
                    newnode.position[1] = binStream.ReadSingle();
                    newnode.position[2] = binStream.ReadSingle();
                    newnode.rotation[0] = binStream.ReadSingle();
                    newnode.rotation[1] = binStream.ReadSingle();
                    newnode.rotation[2] = binStream.ReadSingle();
                    newnode.rotation[3] = binStream.ReadSingle();
                    newnode.scale[0]    = binStream.ReadSingle();
                    newnode.scale[1]    = binStream.ReadSingle();
                    newnode.scale[2]    = binStream.ReadSingle();

                    float afloat = binStream.ReadSingle();
                    short ashort = binStream.ReadInt16();

                    nodeList.Add(newnode);
                }


                byte  abyte       = binStream.ReadByte();
                short objectCount = binStream.ReadInt16();

                for (int o = 0; o < objectCount; o++)
                {
                    PIGobject newobject = new PIGobject();

                    marker           = binStream.ReadInt32(); //0x64
                    newobject.nodeID = binStream.ReadInt32();
                    int LODcount = binStream.ReadInt16();

                    for (int l = 0; l < LODcount; l++)
                    {
                        byte LODnum = binStream.ReadByte();
                        marker = binStream.ReadInt32();      //0x64
                        short edata = binStream.ReadInt16();
                        binStream.BaseStream.Position += 24; //bounding box
                        short meshCount = binStream.ReadInt16();
                        geomCount += meshCount;

                        for (int m = 0; m < meshCount; m++)
                        {
                            PIGmesh newmesh = new PIGmesh();
                            newmesh.LODnum = LODnum;

                            marker = binStream.ReadInt32(); //0x64
                            BitArray bitflags = new BitArray(new int[1] {
                                binStream.ReadInt32()
                            });
                            int FVFcode = binStream.ReadInt32();
                            binStream.BaseStream.Position += 12; //mpivot

                            if (bitflags[0])
                            {
                                newmesh.position[0] = binStream.ReadSingle();
                                newmesh.position[1] = binStream.ReadSingle();
                                newmesh.position[2] = binStream.ReadSingle();
                                newmesh.scale[0]    = binStream.ReadSingle();
                                newmesh.scale[1]    = binStream.ReadSingle();
                                newmesh.scale[2]    = binStream.ReadSingle();
                            }

                            ushort vertexCount = binStream.ReadUInt16();
                            newmesh.vertexCount = vertexCount;
                            int    indexCount   = binStream.ReadInt32();
                            string materialName = ReadStr(binStream);
                            newmesh.materialName = materialName;
                            newmesh.materialID   = matList.Count;

                            PIGmaterial pmat = new PIGmaterial();
                            pmat.name = materialName;

                            short texureCount = binStream.ReadInt16();
                            for (int t = 0; t < texureCount; t++)
                            {
                                string textureName = ReadStr(binStream);

                                if (textureName.Length > 0)
                                {
                                    PIGtexture ptex = new PIGtexture();
                                    ptex.name = textureName;
                                    int ptexID           = texList.Count;
                                    var existingTexIndex = texList.BinarySearch(ptex, tc);
                                    if (existingTexIndex >= 0)
                                    {
                                        ptexID = existingTexIndex;
                                    }
                                    else
                                    {
                                        //get filename
                                        string[] texFiles = Directory.GetFiles(Path.GetDirectoryName(PIGfile) + "\\..\\", Path.GetFileNameWithoutExtension(textureName) + ".pvr", SearchOption.AllDirectories);
                                        if (texFiles.Length == 0)
                                        {
                                            texFiles = Directory.GetFiles(Path.GetDirectoryName(PIGfile) + "\\..\\", textureName, SearchOption.AllDirectories);
                                            if (texFiles.Length > 0)
                                            {
                                                var pvrfile = DecompressPVR(texFiles[0]);
                                                ptex.filename = pvrfile;
                                            }
                                        }
                                        else
                                        {
                                            ptex.filename = Path.GetFullPath(texFiles[0]);
                                        }

                                        texList.Add(ptex);
                                    }

                                    switch (t)
                                    {
                                    case 0:     //diffuse
                                        pmat.diffuseID = ptexID;
                                        usedTexCount  += 1;
                                        break;

                                    case 2:     //normal
                                        pmat.normalID = ptexID;
                                        usedTexCount += 1;
                                        break;
                                    }
                                }
                            }

                            //add material only if it wasn't added before
                            var existingMatIndex = matList.BinarySearch(pmat, mc);
                            if (existingMatIndex >= 0)
                            {
                                newmesh.materialID = existingMatIndex;
                            }
                            else
                            {
                                matList.Add(pmat);
                            }


                            abyte = binStream.ReadByte();
                            int    bufferSize = binStream.ReadInt32();
                            byte[] geobuffer  = new byte[bufferSize];

                            if (bufferSize == 0) //lz4 compression
                            {
                                int compressedSize   = binStream.ReadInt32();
                                int uncompressedSize = binStream.ReadInt32();

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

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

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

                                /*using (BinaryWriter debugStream = new BinaryWriter(File.Open((Path.GetDirectoryName(fileName) + "\\" + Path.GetFileNameWithoutExtension(fileName) + "_" + o + "_" + l + "_" + m), FileMode.Create)))
                                 * {
                                 *  debugStream.Write(geobuffer);
                                 *  debugStream.Close();
                                 * }*/
                            }
                            else
                            {
                                binStream.Read(geobuffer, 0, bufferSize);
                            }

                            newmesh.indices = new ushort[indexCount];

                            using (BinaryReader geostream = new BinaryReader(new MemoryStream(geobuffer)))
                            {
                                geostream.BaseStream.Position = 0; //is this needed?

                                #region positions
                                if ((FVFcode | 1) == FVFcode) //positions
                                {
                                    newmesh.vertices = new float[vertexCount * 3];
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;

                                    //test if components are 16bit shorts or 32bit floats
                                    int predictedAlign = 16 - ((vertexCount * 8) % 16) - 2;
                                    geostream.BaseStream.Position += vertexCount * 8;
                                    align = geostream.ReadInt16();
                                    geostream.BaseStream.Position -= vertexCount * 8 + 2;

                                    if (align != predictedAlign)
                                    {
                                        for (int v = 0; v < vertexCount * 3; v++)
                                        {
                                            newmesh.vertices[v] = geostream.ReadSingle();
                                        }
                                    }
                                    else
                                    {
                                        for (int v = 0; v < vertexCount; v++)
                                        {
                                            newmesh.vertices[v * 3]        = (float)geostream.ReadInt16() / 32767;
                                            newmesh.vertices[v * 3 + 1]    = (float)geostream.ReadInt16() / 32767;
                                            newmesh.vertices[v * 3 + 2]    = (float)geostream.ReadInt16() / 32767;
                                            geostream.BaseStream.Position += 2; //w component
                                        }
                                    }
                                }
                                #endregion

                                #region normals
                                if ((FVFcode | 2) == FVFcode) //normals
                                {
                                    newmesh.normals = new float[vertexCount * 3];
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;

                                    for (int v = 0; v < vertexCount; v++)
                                    {
                                        newmesh.normals[v * 3]         = (float)geostream.ReadSByte() / 127;
                                        newmesh.normals[v * 3 + 1]     = (float)geostream.ReadSByte() / 127;
                                        newmesh.normals[v * 3 + 2]     = (float)geostream.ReadSByte() / 127;
                                        geostream.BaseStream.Position += 1;
                                    }
                                }
                                #endregion

                                #region misc
                                if ((FVFcode | 4) == FVFcode) //tangents
                                {
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;
                                    geostream.BaseStream.Position += vertexCount * 4;
                                }

                                if ((FVFcode | 8) == FVFcode) //??
                                {
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;
                                    geostream.BaseStream.Position += vertexCount * 4;
                                }

                                if ((FVFcode | 16) == FVFcode) //??
                                {
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;
                                    geostream.BaseStream.Position += vertexCount * 4;
                                }

                                if ((FVFcode | 32) == FVFcode) //??
                                {
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;
                                    geostream.BaseStream.Position += vertexCount * 4;
                                }

                                if ((FVFcode | 64) == FVFcode) //not colors
                                {
                                    //newmesh.colors = new float[vertexCount * 4];
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;
                                    geostream.BaseStream.Position += vertexCount * 4;

                                    /*for (int v = 0; v < vertexCount * 4; v++)
                                     * {
                                     *  newmesh.colors[v] = (float)geostream.ReadByte() / 255;
                                     * }*/
                                }
                                #endregion

                                #region texture coords
                                if ((FVFcode | 128) == FVFcode) //texture0
                                {
                                    newmesh.texture0 = new float[vertexCount * 2];
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;

                                    //test if components are 16bit shorts or 32bit floats
                                    int predictedAlign = 16 - ((vertexCount * 4) % 16) - 2;
                                    geostream.BaseStream.Position += vertexCount * 4;
                                    align = geostream.ReadInt16();
                                    geostream.BaseStream.Position -= vertexCount * 4 + 2;

                                    if (align != predictedAlign)
                                    {
                                        for (int v = 0; v < vertexCount; v++)
                                        {
                                            newmesh.texture0[v * 2]     = geostream.ReadSingle();
                                            newmesh.texture0[v * 2 + 1] = 1f - geostream.ReadSingle();
                                        }
                                    }
                                    else
                                    {
                                        for (int v = 0; v < vertexCount; v++)
                                        {
                                            newmesh.texture0[v * 2]     = (float)geostream.ReadInt16() / 32767;
                                            newmesh.texture0[v * 2 + 1] = 1f - (float)geostream.ReadInt16() / 32767;
                                        }
                                    }
                                }

                                if ((FVFcode | 256) == FVFcode) //texture1
                                {
                                    newmesh.texture1 = new float[vertexCount * 2];
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;

                                    //test if components are 16bit shorts or 32bit floats
                                    int predictedAlign = 16 - ((vertexCount * 4) % 16) - 2;
                                    geostream.BaseStream.Position += vertexCount * 4;
                                    align = geostream.ReadInt16();
                                    geostream.BaseStream.Position -= vertexCount * 4 + 2;

                                    if (align != predictedAlign)
                                    {
                                        for (int v = 0; v < vertexCount; v++)
                                        {
                                            newmesh.texture1[v * 2] = geostream.ReadSingle();
                                            newmesh.texture1[v * 2] = 1f - geostream.ReadSingle();
                                        }
                                    }
                                    else
                                    {
                                        for (int v = 0; v < vertexCount; v++)
                                        {
                                            newmesh.texture1[v * 2] = (float)geostream.ReadInt16() / 32767;
                                            newmesh.texture1[v * 2] = 1f - (float)geostream.ReadInt16() / 32767;
                                        }
                                    }
                                }
                                #endregion

                                #region misc2
                                if ((FVFcode | 512) == FVFcode) //??
                                {
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;

                                    int predictedAlign = 16 - ((vertexCount * 4) % 16) - 2;
                                    geostream.BaseStream.Position += vertexCount * 4;
                                    align = geostream.ReadInt16();
                                    geostream.BaseStream.Position -= 2;
                                    if (align != predictedAlign)
                                    {
                                        geostream.BaseStream.Position += vertexCount * 4;
                                    }                                                                                  //happened in car_ford_mustang_2015_rfx.pig
                                }

                                if ((FVFcode | 1024) == FVFcode) //??
                                {
                                    short align = geostream.ReadInt16();
                                    geostream.BaseStream.Position += align;
                                    geostream.BaseStream.Position += vertexCount * 8;
                                }
                                #endregion

                                geostream.BaseStream.Position = geostream.BaseStream.Length - (indexCount * 2); //failsafe in case vertex properties are misread
                                //note that IB alignment is skipped
                                for (int i = 0; i < indexCount; i++)
                                {
                                    newmesh.indices[i] = geostream.ReadUInt16();
                                }
                            }


                            for (int e = 0; e < edata; e++)
                            {
                                short short1    = binStream.ReadInt16();
                                short short2    = binStream.ReadInt16();
                                int   extraSize = binStream.ReadInt32();
                                if (extraSize == 0)
                                {
                                    int compressedSize   = binStream.ReadInt32();
                                    int uncompressedSize = binStream.ReadInt32();
                                    binStream.BaseStream.Position += compressedSize;
                                }
                                else
                                {
                                    binStream.BaseStream.Position += extraSize;
                                }
                            }

                            newobject.meshList.Add(newmesh);
                        }
                    }

                    objectList.Add(newobject);
                }
            }
        }
        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);
        }
Beispiel #28
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);
        }
        ///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);
        }
Beispiel #30
0
        public string DecompressPVR(string tgaFile)
        {
            string outFile    = Path.GetDirectoryName(tgaFile) + "\\" + Path.GetFileNameWithoutExtension(tgaFile);
            bool   compressed = false;

            using (BinaryReader tgaStream = new BinaryReader(File.OpenRead(tgaFile)))
            {
                int head = tgaStream.ReadInt32();

                switch (head)
                {
                case 1481919403:
                {
                    outFile += ".ktx";
                    break;
                }

                case 55727696:
                {
                    outFile += ".pvr";
                    int imageSize = 52;
                    tgaStream.BaseStream.Position = 44;
                    int mipCount = tgaStream.ReadInt32();
                    int metaSize = tgaStream.ReadInt32();
                    if (metaSize > 0)
                    {
                        int JETtest = tgaStream.ReadInt32();
                        int LZ4test = tgaStream.ReadInt32();
                        if (JETtest == 1413827072 && LZ4test == 878332928)         //lz4
                        {
                            compressed = true;
                            List <lz4mip> lz4mipData = new List <lz4mip>();

                            int dataSize = tgaStream.ReadInt32();
                            for (int i = 0; i < mipCount; i++)
                            {        //assume no surfaces or faces
                                lz4mip amip = new lz4mip();
                                amip.offset           = tgaStream.ReadInt32();
                                amip.compressedSize   = tgaStream.ReadInt32();
                                amip.uncompressedSize = tgaStream.ReadInt32();
                                imageSize            += amip.uncompressedSize;
                                lz4mipData.Add(amip);
                            }

                            byte[] imageBuffer = new byte[imageSize];
                            tgaStream.BaseStream.Position = 0;
                            tgaStream.Read(imageBuffer, 0, 48);         //excluding meta data size which will be 0
                            int imageOffset = 52;

                            foreach (var amip in lz4mipData)
                            {
                                tgaStream.BaseStream.Position = 52 + metaSize + amip.offset;
                                byte[] lz4buffer = new byte[amip.compressedSize];
                                tgaStream.Read(lz4buffer, 0, amip.compressedSize);

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

                                    byte[] mipBuffer = new byte[amip.uncompressedSize];
                                    for (; ;)
                                    {
                                        int nRead = decoder.Read(mipBuffer, 0, amip.uncompressedSize);
                                        if (nRead == 0)
                                        {
                                            break;
                                        }
                                    }

                                    Buffer.BlockCopy(mipBuffer, 0, imageBuffer, imageOffset, amip.uncompressedSize);
                                    imageOffset += amip.uncompressedSize;
                                }
                            }

                            using (BinaryWriter pvrStream = new BinaryWriter(File.Open(outFile, FileMode.Create)))
                            {
                                pvrStream.Write(imageBuffer);
                                pvrStream.Close();
                            }

                            return(outFile);
                        }
                    }
                    break;
                }
                }
            }

            if (!compressed)
            {
                System.IO.File.Move(tgaFile, outFile);
                return(outFile);
            }
            else
            {
                return(tgaFile);
            }
        }