public static void Serialize(BundleOptions options, Stream stream) { using (var writer = new EndianBinaryWriter(stream, UnityEndianHelper.UnityDefaultEndian)) { // bundle signature writer.WriteAsciiStringAndNull(BundleFileSignature.Raw); // bundle format writer.Write(3); writer.WriteAsciiStringAndNull(PlayerVersion); writer.WriteAsciiStringAndNull(EngineVersion); const int bundleHeaderSize = 0x70; const int assetHeaderSize = 0x10; int assetDataOffset; var singleAssetFile = GetAssetFileIndependentData(options, out assetDataOffset); assetDataOffset += bundleHeaderSize + assetHeaderSize; var totalBundleSize = bundleHeaderSize + assetHeaderSize + singleAssetFile.Length; writer.Write(totalBundleSize); writer.Write((ushort)0); // base offset; Raw file, no LZMA compression, so it is fixed. writer.Write((ushort)0x3c); // Dummy int writer.Write(1); // LZMA chunks writer.Write(1); // LZMA compressed size writer.Write(totalBundleSize - 0x3c); // LZMA stream size writer.Write(totalBundleSize - 0x3c); // some 'dummy' value (?) writer.Write(totalBundleSize); writer.AlignStream(4); // Dunno writer.Write(new byte[] { 0x00, 0x00, 0x34, 0x00 }); // Now we should be at 0x3c // Asset file count writer.Write(1); // Asset file name var cabName = GenerateFakeHexHash(32); writer.WriteAsciiStringAndNull("CAB-" + cabName); // Asset file offset writer.Write(0x34); // first asset file offset = 0x70 = base offset + asset offset writer.Write(assetHeaderSize + singleAssetFile.Length); writer.AlignStream(4); // Now we should be at 0x70 // Write asset header // table size writer.Write(0x08ba); // data end writer.Write(assetHeaderSize + singleAssetFile.Length); // format signature; 0xf for 5.1.2 writer.Write(0xf); // data offset writer.Write(assetDataOffset - bundleHeaderSize); writer.Write(singleAssetFile); } }