mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-07-14 02:54:16 -04:00
Code moved out of UnityStudioForm and into new class UnityStudio.cs (#17)
This commit is contained in:
257
Unity Studio/Unity Studio Classes/BundleFile.cs
Normal file
257
Unity Studio/Unity Studio Classes/BundleFile.cs
Normal file
@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Lz4;
|
||||
|
||||
namespace Unity_Studio
|
||||
{
|
||||
public class BundleFile
|
||||
{
|
||||
public int format;
|
||||
public string versionPlayer;
|
||||
public string versionEngine;
|
||||
public List<MemoryAssetsFile> MemoryAssetsFileList = new List<MemoryAssetsFile>();
|
||||
|
||||
public class MemoryAssetsFile
|
||||
{
|
||||
public string fileName;
|
||||
public MemoryStream memStream;
|
||||
}
|
||||
|
||||
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];
|
||||
decoder.Read(filebuffer, 0, uncompressedSize);
|
||||
decoder.Dispose();
|
||||
}
|
||||
}
|
||||
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 void readBundle(EndianStream b_Stream)
|
||||
{
|
||||
var signature = b_Stream.ReadStringToNull();
|
||||
|
||||
if (signature == "UnityWeb" || signature == "UnityRaw" || signature == "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA")
|
||||
{
|
||||
format = b_Stream.ReadInt32();
|
||||
versionPlayer = b_Stream.ReadStringToNull();
|
||||
versionEngine = b_Stream.ReadStringToNull();
|
||||
if (format < 6)
|
||||
{
|
||||
int bundleSize = b_Stream.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
long bundleSize = b_Stream.ReadInt64();
|
||||
return;
|
||||
}
|
||||
short dummy2 = b_Stream.ReadInt16();
|
||||
int offset = b_Stream.ReadInt16();
|
||||
int dummy3 = b_Stream.ReadInt32();
|
||||
int lzmaChunks = b_Stream.ReadInt32();
|
||||
|
||||
int lzmaSize = 0;
|
||||
long streamSize = 0;
|
||||
|
||||
for (int i = 0; i < lzmaChunks; i++)
|
||||
{
|
||||
lzmaSize = b_Stream.ReadInt32();
|
||||
streamSize = b_Stream.ReadInt32();
|
||||
}
|
||||
|
||||
b_Stream.Position = offset;
|
||||
switch (signature)
|
||||
{
|
||||
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA": //.bytes
|
||||
case "UnityWeb":
|
||||
{
|
||||
byte[] lzmaBuffer = new byte[lzmaSize];
|
||||
b_Stream.Read(lzmaBuffer, 0, lzmaSize);
|
||||
|
||||
using (var lzmaStream = new EndianStream(SevenZip.Compression.LZMA.SevenZipHelper.StreamDecompress(new MemoryStream(lzmaBuffer)), EndianType.BigEndian))
|
||||
{
|
||||
getFiles(lzmaStream, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "UnityRaw":
|
||||
{
|
||||
getFiles(b_Stream, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (signature == "UnityFS")
|
||||
{
|
||||
format = b_Stream.ReadInt32();
|
||||
versionPlayer = b_Stream.ReadStringToNull();
|
||||
versionEngine = b_Stream.ReadStringToNull();
|
||||
if (format == 6)
|
||||
{
|
||||
var bundleSize = b_Stream.ReadInt64();
|
||||
int compressedSize = b_Stream.ReadInt32();
|
||||
int uncompressedSize = b_Stream.ReadInt32();
|
||||
int flag = b_Stream.ReadInt32();
|
||||
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:
|
||||
case 0://None
|
||||
{
|
||||
blocksInfo = new EndianStream(new MemoryStream(blocksInfoBytes), EndianType.BigEndian);
|
||||
break;
|
||||
}
|
||||
case 1://LZMA
|
||||
{
|
||||
blocksInfo = new EndianStream(SevenZip.Compression.LZMA.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:
|
||||
case 0://None
|
||||
{
|
||||
assetsDataStream.Write(compressedBytes, 0, compressedSize);
|
||||
break;
|
||||
}
|
||||
case 1://LZMA
|
||||
{
|
||||
var uncompressedBytes = new byte[uncompressedSize];
|
||||
using (var mstream = new MemoryStream(compressedBytes))
|
||||
{
|
||||
var decoder = SevenZip.Compression.LZMA.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getFiles(EndianStream f_Stream, int offset)
|
||||
{
|
||||
int fileCount = f_Stream.ReadInt32();
|
||||
for (int i = 0; i < fileCount; i++)
|
||||
{
|
||||
MemoryAssetsFile memFile = new MemoryAssetsFile();
|
||||
memFile.fileName = f_Stream.ReadStringToNull();
|
||||
int fileOffset = f_Stream.ReadInt32();
|
||||
fileOffset += offset;
|
||||
int fileSize = f_Stream.ReadInt32();
|
||||
long nextFile = f_Stream.Position;
|
||||
f_Stream.Position = fileOffset;
|
||||
|
||||
byte[] buffer = new byte[fileSize];
|
||||
f_Stream.Read(buffer, 0, fileSize);
|
||||
memFile.memStream = new MemoryStream(buffer);
|
||||
MemoryAssetsFileList.Add(memFile);
|
||||
f_Stream.Position = nextFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user