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(); } } }
private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream) { foreach (var blockInfo in m_BlocksInfo) { switch (blockInfo.flags & 0x3F) //kStorageBlockCompressionTypeMask { default: //None { reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize); break; } case 1: //LZMA { SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize); break; } case 2: //LZ4 case 3: //LZ4HC { var compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize)); using (var lz4Stream = new Lz4DecoderStream(compressedStream)) { lz4Stream.CopyTo(blocksStream, blockInfo.uncompressedSize); } break; } } } blocksStream.Position = 0; }
private void ReadBlocks(EndianBinaryReader varReader, Stream varBlocksStream) { foreach (var blockInfo in BlocksInfo) { switch (blockInfo.GetCompressionType()) { default: //None { varReader.BaseStream.CopyTo(varBlocksStream, blockInfo.compressedSize); break; } case Compression.CompressionType.kCompressionLzma: //LZMA { SevenZipHelper.StreamDecompress(varReader.BaseStream, varBlocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize); break; } case Compression.CompressionType.kCompressionLz4: //LZ4 case Compression.CompressionType.kCompressionLz4HC: //LZ4HC { var compressedStream = new MemoryStream(varReader.ReadBytes((int)blockInfo.compressedSize)); using (var lz4Stream = new Lz4DecoderStream(compressedStream)) { lz4Stream.CopyTo(varBlocksStream, blockInfo.uncompressedSize); } break; } } } varBlocksStream.Position = 0; }
public bool Read(AssetsFileReader reader) { header = new ClassDatabaseFileHeader(); header.Read(reader); if (header.header != "cldb" || header.fileVersion > 4 || header.fileVersion < 1) { valid = false; return(valid); } classes = new List <ClassDatabaseType>(); long classTablePos = reader.Position; AssetsFileReader newReader = reader; if (header.compressionType != 0) { classTablePos = 0; MemoryStream ms; if (header.compressionType == 1) //lz4 { byte[] uncompressedBytes = new byte[header.uncompressedSize]; using (MemoryStream tempMs = new MemoryStream(reader.ReadBytes((int)header.compressedSize))) { Lz4DecoderStream decoder = new Lz4DecoderStream(tempMs); decoder.Read(uncompressedBytes, 0, (int)header.uncompressedSize); decoder.Dispose(); } ms = new MemoryStream(uncompressedBytes); } else if (header.compressionType == 2) //lzma { using (MemoryStream tempMs = new MemoryStream(reader.ReadBytes((int)header.compressedSize))) { ms = SevenZipHelper.StreamDecompress(tempMs); } } else { valid = false; return(valid); } newReader = new AssetsFileReader(ms); newReader.bigEndian = false; } newReader.Position = header.stringTablePos; stringTable = newReader.ReadBytes((int)header.stringTableLen); newReader.Position = classTablePos; uint size = newReader.ReadUInt32(); for (int i = 0; i < size; i++) { ClassDatabaseType cdt = new ClassDatabaseType(); cdt.Read(newReader, header.fileVersion, header.flags); classes.Add(cdt); } valid = true; return(valid); }
public static byte[] DecompressFromLZ4(Stream stream, int rawLength) { using (stream) { #if NETSTANDARD2_0 var inputLength = rawLength; var inputBuffer = new byte[inputLength]; stream.Read(inputBuffer, 0, rawLength); var guessedOutputLength = inputLength * 10; var outputBuffer = new byte[guessedOutputLength]; var actualOutputLength = LZ4Codec.Decode( inputBuffer, 0, inputLength, outputBuffer, 0, guessedOutputLength); if (actualOutputLength < guessedOutputLength) { return(outputBuffer.Take(actualOutputLength).ToArray()); } else { return(outputBuffer); } #else using (Lz4DecoderStream streamInner = new Lz4DecoderStream(stream)) { byte[] output = new byte[rawLength]; streamInner.Read(output, 0, rawLength); return(output); } #endif } }
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); }
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); } } }
private ContentReader GetContentReaderFromXnb(string originalAssetName, Stream stream, BinaryReader xnbReader, Action <IDisposable> recordDisposableObject) { // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file byte x = xnbReader.ReadByte(); byte n = xnbReader.ReadByte(); byte b = xnbReader.ReadByte(); byte platform = xnbReader.ReadByte(); if (x != 'X' || n != 'N' || b != 'B' || !(targetPlatformIdentifiers.Contains((char)platform))) { throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); } byte version = xnbReader.ReadByte(); byte flags = xnbReader.ReadByte(); bool compressedLzx = (flags & ContentCompressedLzx) != 0; bool compressedLz4 = (flags & ContentCompressedLz4) != 0; if (version != 5 && version != 4) { throw new ContentLoadException("Invalid XNB version"); } // The next int32 is the length of the XNB file int xnbLength = xnbReader.ReadInt32(); Stream decompressedStream = null; #if WEB decompressedStream = stream; #else if (compressedLzx || compressedLz4) { // Decompress the xnb int decompressedSize = xnbReader.ReadInt32(); if (compressedLzx) { int compressedSize = xnbLength - 14; decompressedStream = new LzxDecoderStream(stream, decompressedSize, compressedSize); } else if (compressedLz4) { decompressedStream = new Lz4DecoderStream(stream); } } else { decompressedStream = stream; } #endif var reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice, originalAssetName, version, recordDisposableObject); return(reader); }
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() }); } }
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; } }
public static ContentReaderShim GetContentReaderFromXnb(string originalAssetName, Stream stream, BinaryReader xnbReader) { // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file byte x = xnbReader.ReadByte(); byte n = xnbReader.ReadByte(); byte b = xnbReader.ReadByte(); byte platform = xnbReader.ReadByte(); if (x != 'X' || n != 'N' || b != 'B' || !(targetPlatformIdentifiers.Contains((char)platform))) { throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); } byte version = xnbReader.ReadByte(); byte flags = xnbReader.ReadByte(); bool compressedLzx = (flags & ContentCompressedLzx) != 0; bool compressedLz4 = (flags & ContentCompressedLz4) != 0; if (version != 6 && version != 5) { throw new ContentLoadException("Invalid XNB version"); } // The next int32 is the length of the XNB file int xnbLength = xnbReader.ReadInt32(); Stream decompressedStream = null; if (compressedLzx || compressedLz4) { // Decompress the xnb int decompressedSize = xnbReader.ReadInt32(); if (compressedLzx) { int compressedSize = xnbLength - 14; decompressedStream = new LzxDecoderStream(stream, decompressedSize, compressedSize); } else if (compressedLz4) { decompressedStream = new Lz4DecoderStream(stream); } } else { decompressedStream = stream; } var reader = new ContentReaderShim(decompressedStream, version); return(reader); }
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 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)); }
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); } } }
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; } } }
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); } } } }
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); } } }
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)); }
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)); }
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)); }
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); } } } }
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); }
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 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); } } } }
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); }
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; } }
public Stream OpenAsset(string assetName) { MemoryStream fileStream = null; var fileNode = Array.Find(m_DirectoryInfo, node => node.path == assetName); if (fileNode != null) { long skipUncompressed = 0; foreach (var blockInfo in m_BlocksInfo) { if (fileStream == null) { if (skipUncompressed + blockInfo.uncompressedSize >= fileNode.offset) { fileStream = new MemoryStream(); } else { skipUncompressed += blockInfo.uncompressedSize; } } if (fileStream != null) { reader.Position = blockInfo.offset; var compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize)); byte[] buffer = new byte[blockInfo.uncompressedSize]; using (MemoryStream unCompressStream = new MemoryStream()) { using (var lz4Stream = new Lz4DecoderStream(compressedStream)) { lz4Stream.CopyTo(unCompressStream); } long begin = 0; if (fileStream.Length == 0) { begin = fileNode.offset - skipUncompressed; if (begin < 0) { begin = 0; } } unCompressStream.Seek(0, 0); int end = (int)(blockInfo.uncompressedSize - (fileNode.size - fileStream.Position)); if (end < 0) { end = 0; } int size = (int)(blockInfo.uncompressedSize - begin - end); int count = unCompressStream.Read(buffer, (int)begin, size); fileStream.Write(buffer, 0, count); if (fileStream.Length >= fileNode.size) { break; } } } } } fileStream?.Seek(0, 0); return(fileStream); }
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); }
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(), }; } } }