diff --git a/AssetStudio.PInvoke/DllLoader.cs b/AssetStudio.PInvoke/DllLoader.cs
index 347ea0a..5ae21b3 100644
--- a/AssetStudio.PInvoke/DllLoader.cs
+++ b/AssetStudio.PInvoke/DllLoader.cs
@@ -11,7 +11,7 @@ namespace AssetStudio.PInvoke
{
public static void PreloadDll(string dllName)
{
- var localPath = Process.GetCurrentProcess().MainModule.FileName;
+ var localPath = Process.GetCurrentProcess().MainModule?.FileName;
var localDir = Path.GetDirectoryName(localPath);
// Not using OperatingSystem.Platform.
@@ -35,7 +35,6 @@ namespace AssetStudio.PInvoke
private static class Win32
{
-
internal static void LoadDll(string dllDir, string dllName)
{
var dllFileName = $"{dllName}.dll";
diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj
index eded92c..e63d987 100644
--- a/AssetStudio/AssetStudio.csproj
+++ b/AssetStudio/AssetStudio.csproj
@@ -16,6 +16,8 @@
+
+
diff --git a/AssetStudio/AssetsManager.cs b/AssetStudio/AssetsManager.cs
index f871877..2082c44 100644
--- a/AssetStudio/AssetsManager.cs
+++ b/AssetStudio/AssetsManager.cs
@@ -13,8 +13,9 @@ namespace AssetStudio
{
public class AssetsManager
{
- public bool ZstdEnabled = true;
public bool LoadingViaTypeTreeEnabled = true;
+ public CompressionType CustomBlockCompression = CompressionType.Auto;
+ public CompressionType CustomBlockInfoCompression = CompressionType.Auto;
public List assetsFileList = new List();
internal Dictionary assetsFileIndexCache = new Dictionary(StringComparer.OrdinalIgnoreCase);
@@ -177,7 +178,10 @@ namespace AssetStudio
private bool LoadFile(FileReader reader)
{
- switch (reader?.FileType)
+ if (reader == null)
+ return false;
+
+ switch (reader.FileType)
{
case FileType.AssetsFile:
return LoadAssetsFile(reader);
@@ -306,7 +310,7 @@ namespace AssetStudio
try
{
- var bundleFile = new BundleFile(bundleReader, ZstdEnabled, specifiedUnityVersion);
+ var bundleFile = new BundleFile(bundleReader, CustomBlockInfoCompression, CustomBlockCompression, specifiedUnityVersion);
var isLoaded = LoadBundleFiles(bundleReader, bundleFile, originalPath);
if (!isLoaded)
return false;
@@ -322,7 +326,7 @@ namespace AssetStudio
bundleReader.FileName = $"{reader.FileName}_0x{bundleStream.Offset:X}";
}
Logger.Info($"[MultiBundle] Loading \"{reader.FileName}\" from offset: 0x{bundleStream.Offset:X}");
- bundleFile = new BundleFile(bundleReader, ZstdEnabled, specifiedUnityVersion);
+ bundleFile = new BundleFile(bundleReader, CustomBlockInfoCompression, CustomBlockCompression, specifiedUnityVersion);
isLoaded = LoadBundleFiles(bundleReader, bundleFile, originalPath ?? reader.FullPath);
}
return isLoaded;
diff --git a/AssetStudio/BundleCompression/Oodle/Oodle.cs b/AssetStudio/BundleCompression/Oodle/Oodle.cs
new file mode 100644
index 0000000..b074a69
--- /dev/null
+++ b/AssetStudio/BundleCompression/Oodle/Oodle.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Runtime.InteropServices;
+#if NETFRAMEWORK
+using AssetStudio.PInvoke;
+#endif
+
+namespace BundleCompression.Oodle
+{
+ public static class OodleLZ
+ {
+ private const string LibName = "ooz";
+
+#if NETFRAMEWORK
+ static OodleLZ()
+ {
+ DllLoader.PreloadDll(LibName);
+ }
+#endif
+
+ [DllImport(LibName)]
+ private static extern int Ooz_Decompress(
+ in byte srcBuffer,
+ UIntPtr srcLen,
+ ref byte dstBuffer,
+ UIntPtr dstLen,
+ int fuzzSafetyFlag,
+ int crcCheckFlag,
+ int logVerbosityFlag,
+ UIntPtr rawBuffer,
+ UIntPtr rawBufferSize,
+ UIntPtr chunkDecodeCallback,
+ UIntPtr chunkDecodeContext,
+ UIntPtr scratchBuf,
+ UIntPtr scratchBufSize,
+ int threadPhase);
+
+ public static int Decompress(ReadOnlySpan srcSpanBuffer, Span dstSpanBuffer)
+ {
+ return Ooz_Decompress(in srcSpanBuffer[0], (UIntPtr)srcSpanBuffer.Length, ref dstSpanBuffer[0], (UIntPtr)dstSpanBuffer.Length,
+ 0, 0, 0, UIntPtr.Zero, UIntPtr.Zero, UIntPtr.Zero, UIntPtr.Zero, UIntPtr.Zero, UIntPtr.Zero, 0);
+ }
+ }
+}
diff --git a/AssetStudio/7zip/Common/CRC.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Common/CRC.cs
similarity index 100%
rename from AssetStudio/7zip/Common/CRC.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Common/CRC.cs
diff --git a/AssetStudio/7zip/Common/CommandLineParser.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Common/CommandLineParser.cs
similarity index 100%
rename from AssetStudio/7zip/Common/CommandLineParser.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Common/CommandLineParser.cs
diff --git a/AssetStudio/7zip/Common/InBuffer.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Common/InBuffer.cs
similarity index 100%
rename from AssetStudio/7zip/Common/InBuffer.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Common/InBuffer.cs
diff --git a/AssetStudio/7zip/Common/OutBuffer.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Common/OutBuffer.cs
similarity index 100%
rename from AssetStudio/7zip/Common/OutBuffer.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Common/OutBuffer.cs
diff --git a/AssetStudio/7zip/Compress/LZ/IMatchFinder.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZ/IMatchFinder.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/LZ/IMatchFinder.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZ/IMatchFinder.cs
diff --git a/AssetStudio/7zip/Compress/LZ/LzBinTree.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZ/LzBinTree.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/LZ/LzBinTree.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZ/LzBinTree.cs
diff --git a/AssetStudio/7zip/Compress/LZ/LzInWindow.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZ/LzInWindow.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/LZ/LzInWindow.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZ/LzInWindow.cs
diff --git a/AssetStudio/7zip/Compress/LZ/LzOutWindow.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZ/LzOutWindow.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/LZ/LzOutWindow.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZ/LzOutWindow.cs
diff --git a/AssetStudio/7zip/Compress/LZMA/LzmaBase.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZMA/LzmaBase.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/LZMA/LzmaBase.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZMA/LzmaBase.cs
diff --git a/AssetStudio/7zip/Compress/LZMA/LzmaDecoder.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZMA/LzmaDecoder.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/LZMA/LzmaDecoder.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZMA/LzmaDecoder.cs
diff --git a/AssetStudio/7zip/Compress/LZMA/LzmaEncoder.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZMA/LzmaEncoder.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/LZMA/LzmaEncoder.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/LZMA/LzmaEncoder.cs
diff --git a/AssetStudio/7zip/Compress/RangeCoder/RangeCoder.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/RangeCoder/RangeCoder.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/RangeCoder/RangeCoder.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/RangeCoder/RangeCoder.cs
diff --git a/AssetStudio/7zip/Compress/RangeCoder/RangeCoderBit.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/RangeCoder/RangeCoderBit.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/RangeCoder/RangeCoderBit.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/RangeCoder/RangeCoderBit.cs
diff --git a/AssetStudio/7zip/Compress/RangeCoder/RangeCoderBitTree.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
similarity index 100%
rename from AssetStudio/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
diff --git a/AssetStudio/7zip/ICoder.cs b/AssetStudio/BundleCompression/SevenZipLzma/7zip/ICoder.cs
similarity index 100%
rename from AssetStudio/7zip/ICoder.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/7zip/ICoder.cs
diff --git a/AssetStudio/SevenZipHelper.cs b/AssetStudio/BundleCompression/SevenZipLzma/SevenZipLzma.cs
similarity index 86%
rename from AssetStudio/SevenZipHelper.cs
rename to AssetStudio/BundleCompression/SevenZipLzma/SevenZipLzma.cs
index b06edd3..03adabc 100644
--- a/AssetStudio/SevenZipHelper.cs
+++ b/AssetStudio/BundleCompression/SevenZipLzma/SevenZipLzma.cs
@@ -2,12 +2,11 @@ using System;
using System.IO;
using SevenZip.Compression.LZMA;
-
-namespace AssetStudio
+namespace BundleCompression.Lzma
{
- public static class SevenZipHelper
+ public static class SevenZipLzma
{
- public static MemoryStream StreamDecompress(MemoryStream inStream)
+ public static MemoryStream DecompressStream(MemoryStream inStream)
{
var decoder = new Decoder();
@@ -34,7 +33,7 @@ namespace AssetStudio
return newOutStream;
}
- public static void StreamDecompress(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize)
+ public static long DecompressStream(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize)
{
var basePosition = compressedStream.Position;
var decoder = new Decoder();
@@ -44,6 +43,7 @@ namespace AssetStudio
decoder.SetDecoderProperties(properties);
decoder.Code(compressedStream, decompressedStream, compressedSize - 5, decompressedSize, null);
compressedStream.Position = basePosition + compressedSize;
+ return decompressedStream.Position;
}
}
}
diff --git a/AssetStudio/BundleDecompressionHelper.cs b/AssetStudio/BundleDecompressionHelper.cs
new file mode 100644
index 0000000..f5409b1
--- /dev/null
+++ b/AssetStudio/BundleDecompressionHelper.cs
@@ -0,0 +1,65 @@
+using BundleCompression.Lzma;
+using BundleCompression.Oodle;
+using System;
+using System.IO;
+using System.Text.RegularExpressions;
+using K4os.Compression.LZ4;
+using ZstdSharp;
+
+namespace AssetStudio
+{
+ public static class BundleDecompressionHelper
+ {
+ private static readonly Decompressor ZstdDecompressor = new Decompressor();
+ private static readonly string MsgPattern = @"\. ";
+
+ public static MemoryStream DecompressLzmaStream(MemoryStream inStream)
+ {
+ return SevenZipLzma.DecompressStream(inStream);
+ }
+
+ public static long DecompressLzmaStream(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize, ref string errorMsg)
+ {
+ var numWrite = -1L;
+ try
+ {
+ numWrite = SevenZipLzma.DecompressStream(compressedStream, decompressedStream, compressedSize, decompressedSize);
+ }
+ catch (Exception e)
+ {
+ Logger.Debug(e.ToString());
+ errorMsg = $"({Regex.Split(e.Message, MsgPattern, RegexOptions.CultureInvariant)[0]})";
+ }
+ return numWrite;
+ }
+
+ public static int DecompressBlock(CompressionType type, ReadOnlySpan srcBuffer, Span dstBuffer, ref string errorMsg)
+ {
+ var numWrite = -1;
+ try
+ {
+ switch (type)
+ {
+ case CompressionType.Lz4:
+ case CompressionType.Lz4HC:
+ numWrite = LZ4Codec.Decode(srcBuffer, dstBuffer);
+ break;
+ case CompressionType.Zstd:
+ numWrite = ZstdDecompressor.Unwrap(srcBuffer, dstBuffer);
+ break;
+ case CompressionType.Oodle:
+ numWrite = OodleLZ.Decompress(srcBuffer, dstBuffer);
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.Debug(e.ToString());
+ errorMsg = $"({Regex.Split(e.Message, MsgPattern, RegexOptions.CultureInvariant)[0]})";
+ }
+ return numWrite;
+ }
+ }
+}
diff --git a/AssetStudio/BundleFile.cs b/AssetStudio/BundleFile.cs
index 70a3074..db06be2 100644
--- a/AssetStudio/BundleFile.cs
+++ b/AssetStudio/BundleFile.cs
@@ -1,6 +1,4 @@
-using K4os.Compression.LZ4;
-using ZstdSharp;
-using System;
+using System;
using System.IO;
using System.Linq;
@@ -32,12 +30,14 @@ namespace AssetStudio
public enum CompressionType
{
+ Auto = -1,
None,
Lzma,
Lz4,
Lz4HC,
Lzham,
- Custom,
+ Zstd, //custom
+ Oodle, //custom
}
public class BundleFile
@@ -77,7 +77,7 @@ namespace AssetStudio
public StreamFile[] fileList;
- public BundleFile(FileReader reader, bool useZstd, UnityVersion specUnityVer = null)
+ public BundleFile(FileReader reader, CompressionType customBlockInfoCompression, CompressionType customBlockCompression, UnityVersion specUnityVer = null)
{
m_Header = new Header();
m_Header.signature = reader.ReadStringToNull();
@@ -152,10 +152,10 @@ namespace AssetStudio
throw new NotSupportedException(msg);
}
- ReadBlocksInfoAndDirectory(reader, unityVer);
+ ReadBlocksInfoAndDirectory(reader, customBlockInfoCompression, unityVer);
using (var blocksStream = CreateBlocksStream(reader.FullPath))
{
- ReadBlocks(reader, blocksStream, useZstd);
+ ReadBlocks(reader, customBlockCompression, blocksStream);
ReadFiles(blocksStream, reader.FullPath);
}
break;
@@ -224,7 +224,7 @@ namespace AssetStudio
{
using (var memoryStream = new MemoryStream(uncompressedBytes))
{
- using (var decompressStream = SevenZipHelper.StreamDecompress(memoryStream))
+ using (var decompressStream = BundleDecompressionHelper.DecompressLzmaStream(memoryStream))
{
uncompressedBytes = decompressStream.ToArray();
}
@@ -287,7 +287,7 @@ namespace AssetStudio
}
}
- private void ReadBlocksInfoAndDirectory(FileReader reader, UnityVersion unityVer)
+ private void ReadBlocksInfoAndDirectory(FileReader reader, CompressionType customBlockInfoCompression, UnityVersion unityVer, bool silent = false)
{
byte[] blocksInfoBytes;
@@ -308,52 +308,82 @@ namespace AssetStudio
}
}
+ var compressedSize = (int)m_Header.compressedBlocksInfoSize;
+ var uncompressedSize = (int)m_Header.uncompressedBlocksInfoSize;
if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
{
var position = reader.Position;
- reader.Position = m_Header.size - m_Header.compressedBlocksInfoSize;
- blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
+ reader.Position = m_Header.size - compressedSize;
+ blocksInfoBytes = reader.ReadBytes(compressedSize);
reader.Position = position;
}
else //0x40 BlocksAndDirectoryInfoCombined
{
- blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
+ blocksInfoBytes = reader.ReadBytes(compressedSize);
}
- MemoryStream blocksInfoUncompressedStream;
- var uncompressedSize = m_Header.uncompressedBlocksInfoSize;
+
var compressionType = (CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask);
+ if (customBlockInfoCompression == CompressionType.Auto)
+ {
+ if (!silent && compressionType > CompressionType.Lzham && Enum.IsDefined(typeof(CompressionType), compressionType))
+ {
+ Logger.Warning($"Non-standard blockInfo compression type: {(int)compressionType}. Trying to decompress as {compressionType} archive..");
+ }
+ }
+ else if (compressionType != CompressionType.None)
+ {
+ compressionType = customBlockInfoCompression;
+ if (!silent)
+ {
+ Logger.Info($"Custom blockInfo compression type: {customBlockInfoCompression}");
+ }
+ }
+ Logger.Debug($"BlockInfo compression: {compressionType}");
+
+ int numWrite;
+ var errorMsg = string.Empty;
+ MemoryStream blocksInfoUncompressedStream;
switch (compressionType)
{
case CompressionType.None:
{
blocksInfoUncompressedStream = new MemoryStream(blocksInfoBytes);
+ numWrite = compressedSize;
break;
}
case CompressionType.Lzma:
{
- blocksInfoUncompressedStream = new MemoryStream((int) (uncompressedSize));
+ blocksInfoUncompressedStream = new MemoryStream(uncompressedSize);
using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
{
- SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompressedStream,
- m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
+ numWrite = (int)BundleDecompressionHelper.DecompressLzmaStream(blocksInfoCompressedStream, blocksInfoUncompressedStream, compressedSize, uncompressedSize, ref errorMsg);
}
blocksInfoUncompressedStream.Position = 0;
break;
}
case CompressionType.Lz4:
case CompressionType.Lz4HC:
+ case CompressionType.Zstd:
+ case CompressionType.Oodle:
{
var uncompressedBytes = new byte[uncompressedSize];
- var numWrite = LZ4Codec.Decode(blocksInfoBytes, uncompressedBytes);
- if (numWrite != uncompressedSize)
- {
- throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
- }
+ numWrite = BundleDecompressionHelper.DecompressBlock(compressionType, blocksInfoBytes, uncompressedBytes, ref errorMsg);
blocksInfoUncompressedStream = new MemoryStream(uncompressedBytes);
break;
}
+ case CompressionType.Lzham:
+ throw new IOException($"Unsupported blockInfo compression type: {compressionType}.\n");
default:
- throw new IOException($"Unsupported block info compression type {compressionType}");
+ throw new IOException($"Unknown blockInfo compression type: {compressionType}.\nYou may try to specify the compression type manually.\n");
+ }
+
+ if (numWrite != uncompressedSize)
+ {
+ var msg = $"{compressionType} blockInfo decompression error. {errorMsg}\nWrite {numWrite} bytes but expected {uncompressedSize} bytes.";
+ var exMsg = compressionType > CompressionType.Lz4HC
+ ? "Wrong compression type or blockInfo data might be encrypted."
+ : "BlockInfo data might be encrypted.";
+ throw new IOException($"{msg}\n{exMsg}\n");
}
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompressedStream))
@@ -390,62 +420,65 @@ namespace AssetStudio
}
}
- private void ReadBlocks(FileReader reader, Stream blocksStream, bool useZstd)
+ private void ReadBlocks(FileReader reader, CompressionType customBlockCompression, Stream blocksStream)
{
- var zstdCodec = new Decompressor();
- var i = 0;
+ var showCustomTypeWarning = true;
foreach (var blockInfo in m_BlocksInfo)
{
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
+ if (customBlockCompression == CompressionType.Auto)
+ {
+ if (showCustomTypeWarning && compressionType > CompressionType.Lzham && Enum.IsDefined(typeof(CompressionType), compressionType))
+ {
+ Logger.Warning($"Non-standard block compression type: {(int)compressionType}. Trying to decompress as {compressionType} archive..");
+ showCustomTypeWarning = false;
+ }
+ }
+ else if (compressionType != CompressionType.None)
+ {
+ compressionType = customBlockCompression;
+ if (showCustomTypeWarning)
+ {
+ Logger.Info($"Custom block compression type: {customBlockCompression}");
+ showCustomTypeWarning = false;
+ }
+ }
+ Logger.Debug($"Block compression: {compressionType}");
+
+ long numWrite;
+ var errorMsg = string.Empty;
switch (compressionType)
{
case CompressionType.None:
{
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
+ numWrite = blockInfo.compressedSize;
break;
}
case CompressionType.Lzma:
{
- SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
+ numWrite = BundleDecompressionHelper.DecompressLzmaStream(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize, ref errorMsg);
break;
}
case CompressionType.Lz4:
case CompressionType.Lz4HC:
- case CompressionType.Custom:
+ case CompressionType.Zstd:
+ case CompressionType.Oodle:
{
var compressedSize = (int)blockInfo.compressedSize;
- var compressedBytes = BigArrayPool.Shared.Rent(compressedSize);
- _ = reader.Read(compressedBytes, 0, compressedSize);
var uncompressedSize = (int)blockInfo.uncompressedSize;
+
+ var compressedBytes = BigArrayPool.Shared.Rent(compressedSize);
var uncompressedBytes = BigArrayPool.Shared.Rent(uncompressedSize);
try
{
- var compTypeStr = compressionType.ToString();
- if (compressionType == CompressionType.Custom)
- {
- compTypeStr = useZstd ? "Zstd" : "Lz4";
- if (i == 0)
- {
- Logger.Debug($"Custom block compression type was detected. Trying to decompress as {compTypeStr} archive..");
- i++;
- }
- }
+ _ = reader.Read(compressedBytes, 0, compressedSize);
+ var compressedSpan = new ReadOnlySpan(compressedBytes, 0, compressedSize);
+ var uncompressedSpan = new Span(uncompressedBytes, 0, uncompressedSize);
- int numWrite;
- if (compressionType == CompressionType.Custom && useZstd)
- {
- numWrite = zstdCodec.Unwrap(compressedBytes, 0, compressedSize, uncompressedBytes, 0, uncompressedSize);
- }
- else
- {
- numWrite = LZ4Codec.Decode(compressedBytes, 0, compressedSize, uncompressedBytes, 0, uncompressedSize);
- }
-
- if (numWrite != uncompressedSize)
- {
- throw new IOException($"{compTypeStr} block decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
- }
- blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
+ numWrite = BundleDecompressionHelper.DecompressBlock(compressionType, compressedSpan, uncompressedSpan, ref errorMsg);
+ if (numWrite == uncompressedSize)
+ blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
}
finally
{
@@ -454,8 +487,19 @@ namespace AssetStudio
}
break;
}
+ case CompressionType.Lzham:
+ throw new IOException($"Unsupported block compression type: {compressionType}.\n");
default:
- throw new IOException($"Unsupported block compression type {compressionType}");
+ throw new IOException($"Unknown block compression type: {compressionType}.\nYou may try to specify the compression type manually.\n");
+ }
+
+ if (numWrite != blockInfo.uncompressedSize)
+ {
+ var msg = $"{compressionType} block decompression error. {errorMsg}\nWrite {numWrite} bytes but expected {blockInfo.uncompressedSize} bytes.";
+ var exMsg = compressionType > CompressionType.Lz4HC
+ ? "Wrong compression type or block data might be encrypted."
+ : "Block data might be encrypted.";
+ throw new IOException($"{msg}\n{exMsg}\n");
}
}
blocksStream.Position = 0;
diff --git a/AssetStudioCLI/AssetStudioCLI.csproj b/AssetStudioCLI/AssetStudioCLI.csproj
index d8d274c..58fb8c4 100644
--- a/AssetStudioCLI/AssetStudioCLI.csproj
+++ b/AssetStudioCLI/AssetStudioCLI.csproj
@@ -30,6 +30,8 @@
+
+
@@ -37,12 +39,20 @@
+
+
+
+
+
+
+
+
@@ -56,6 +66,8 @@
+
+
@@ -63,12 +75,20 @@
+
+
+
+
+
+
+
+
@@ -77,6 +97,7 @@
+
@@ -84,6 +105,7 @@
+
@@ -91,6 +113,7 @@
+
@@ -107,36 +130,42 @@
+
+
+
+
+
+
diff --git a/AssetStudioCLI/Libraries/linux-arm64/libooz.so b/AssetStudioCLI/Libraries/linux-arm64/libooz.so
new file mode 100644
index 0000000..dbbe0d6
Binary files /dev/null and b/AssetStudioCLI/Libraries/linux-arm64/libooz.so differ
diff --git a/AssetStudioCLI/Libraries/linux-x64/libooz.so b/AssetStudioCLI/Libraries/linux-x64/libooz.so
new file mode 100644
index 0000000..b9b2f0e
Binary files /dev/null and b/AssetStudioCLI/Libraries/linux-x64/libooz.so differ
diff --git a/AssetStudioCLI/Libraries/linux-x86/libooz.so b/AssetStudioCLI/Libraries/linux-x86/libooz.so
new file mode 100644
index 0000000..45920ad
Binary files /dev/null and b/AssetStudioCLI/Libraries/linux-x86/libooz.so differ
diff --git a/AssetStudioCLI/Libraries/osx-arm64/libooz.dylib b/AssetStudioCLI/Libraries/osx-arm64/libooz.dylib
new file mode 100644
index 0000000..cb813b2
Binary files /dev/null and b/AssetStudioCLI/Libraries/osx-arm64/libooz.dylib differ
diff --git a/AssetStudioCLI/Libraries/osx-x64/libooz.dylib b/AssetStudioCLI/Libraries/osx-x64/libooz.dylib
new file mode 100644
index 0000000..f013314
Binary files /dev/null and b/AssetStudioCLI/Libraries/osx-x64/libooz.dylib differ
diff --git a/AssetStudioCLI/Libraries/win-x64/ooz.dll b/AssetStudioCLI/Libraries/win-x64/ooz.dll
new file mode 100644
index 0000000..fe0dc09
Binary files /dev/null and b/AssetStudioCLI/Libraries/win-x64/ooz.dll differ
diff --git a/AssetStudioCLI/Libraries/win-x86/ooz.dll b/AssetStudioCLI/Libraries/win-x86/ooz.dll
new file mode 100644
index 0000000..0629ec4
Binary files /dev/null and b/AssetStudioCLI/Libraries/win-x86/ooz.dll differ
diff --git a/AssetStudioCLI/Options/CLIOptions.cs b/AssetStudioCLI/Options/CLIOptions.cs
index 95216af..70bfec7 100644
--- a/AssetStudioCLI/Options/CLIOptions.cs
+++ b/AssetStudioCLI/Options/CLIOptions.cs
@@ -68,12 +68,6 @@ namespace AssetStudioCLI.Options
NameAndContainer,
}
- internal enum CustomCompressionType
- {
- Zstd,
- Lz4,
- }
-
internal static class CLIOptions
{
public static bool isParsed;
@@ -115,7 +109,8 @@ namespace AssetStudioCLI.Options
public static Option> o_filterByPathID;
public static Option> o_filterByText;
//advanced
- public static Option o_customCompressionType;
+ public static Option o_bundleBlockInfoCompression;
+ public static Option o_bundleBlockCompression;
public static Option o_maxParallelExportTasks;
public static Option o_exportAssetList;
public static Option o_assemblyPath;
@@ -425,15 +420,33 @@ namespace AssetStudioCLI.Options
#endregion
#region Init Advanced Options
- o_customCompressionType = new GroupedOption
+ o_bundleBlockInfoCompression = new GroupedOption
(
- optionDefaultValue: CustomCompressionType.Zstd,
- optionName: "--custom-compression ",
- optionDescription: "Specify the compression type for assets that use custom compression\n" +
- "\n" +
+ optionDefaultValue: CompressionType.Auto,
+ optionName: "--blockinfo-comp ",
+ optionDescription: "Specify the compression type of bundle's blockInfo data\n" +
+ "\n" +
+ "Auto - Use compression type specified in an asset bundle\n" +
"Zstd - Try to decompress as zstd archive\n" +
- "Lz4 - Try to decompress as lz4 archive\n",
- optionExample: "Example: \"--custom-compression lz4\"\n",
+ "Oodle - Try to decompress as oodle archive\n" +
+ "Lz4 - Try to decompress as lz4/lz4hc archive\n" +
+ "Lzma - Try to decompress as lzma archive\n",
+ optionExample: "Example: \"--blockinfo-comp lz4\"\n",
+ optionHelpGroup: HelpGroups.Advanced
+ );
+
+ o_bundleBlockCompression = new GroupedOption
+ (
+ optionDefaultValue: CompressionType.Auto,
+ optionName: "--block-comp ",
+ optionDescription: "Specify the compression type of bundle's block data\n" +
+ "\n" +
+ "Auto - Use compression type specified in an asset bundle\n" +
+ "Zstd - Try to decompress as zstd archive\n" +
+ "Oodle - Try to decompress as oodle archive\n" +
+ "Lz4 - Try to decompress as lz4/lz4hc archive\n" +
+ "Lzma - Try to decompress as lzma archive\n",
+ optionExample: "Example: \"--block-comp zstd\"\n",
optionHelpGroup: HelpGroups.Advanced
);
@@ -975,19 +988,53 @@ namespace AssetStudioCLI.Options
}
break;
}
- case "--custom-compression":
+ case "--blockinfo-comp":
switch (value.ToLower())
{
+ case "auto":
+ o_bundleBlockInfoCompression.Value = CompressionType.Zstd;
+ break;
case "zstd":
- o_customCompressionType.Value = CustomCompressionType.Zstd;
+ o_bundleBlockInfoCompression.Value = CompressionType.Zstd;
+ break;
+ case "oodle":
+ o_bundleBlockInfoCompression.Value = CompressionType.Oodle;
break;
case "lz4":
case "lz4hc":
- o_customCompressionType.Value = CustomCompressionType.Lz4;
+ o_bundleBlockInfoCompression.Value = CompressionType.Lz4HC;
+ break;
+ case "lzma":
+ o_bundleBlockInfoCompression.Value = CompressionType.Lzma;
break;
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option.Color(brightYellow)}] option. Unsupported compression type: [{value.Color(brightRed)}].\n");
- ShowOptionDescription(o_customCompressionType);
+ ShowOptionDescription(o_bundleBlockInfoCompression);
+ return;
+ }
+ break;
+ case "--block-comp":
+ switch (value.ToLower())
+ {
+ case "auto":
+ o_bundleBlockCompression.Value = CompressionType.Zstd;
+ break;
+ case "zstd":
+ o_bundleBlockCompression.Value = CompressionType.Zstd;
+ break;
+ case "oodle":
+ o_bundleBlockCompression.Value = CompressionType.Oodle;
+ break;
+ case "lz4":
+ case "lz4hc":
+ o_bundleBlockCompression.Value = CompressionType.Lz4HC;
+ break;
+ case "lzma":
+ o_bundleBlockCompression.Value = CompressionType.Lzma;
+ break;
+ default:
+ Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option.Color(brightYellow)}] option. Unsupported compression type: [{value.Color(brightRed)}].\n");
+ ShowOptionDescription(o_bundleBlockCompression);
return;
}
break;
@@ -1235,10 +1282,6 @@ namespace AssetStudioCLI.Options
var sb = new StringBuilder();
sb.AppendLine("[Current Options]");
sb.AppendLine($"# Working Mode: {o_workMode}");
- if (o_customCompressionType.Value != o_customCompressionType.DefaultValue)
- {
- sb.AppendLine($"# Custom Compression Type: {o_customCompressionType}");
- }
if (o_workMode.Value != WorkMode.Extract)
{
sb.AppendLine($"# Parse Assets Using TypeTree: {!f_avoidLoadingViaTypetree.Value}");
@@ -1248,6 +1291,8 @@ namespace AssetStudioCLI.Options
{
sb.AppendLine($"# Output Path: \"{o_outputFolder}\"");
}
+ sb.AppendLine($"Bundle BlockInfo Compression Type: {o_bundleBlockInfoCompression}");
+ sb.AppendLine($"Bundle Block Compression Type: {o_bundleBlockCompression}");
switch (o_workMode.Value)
{
case WorkMode.Export:
diff --git a/AssetStudioCLI/Studio.cs b/AssetStudioCLI/Studio.cs
index b3fb587..9ee08c2 100644
--- a/AssetStudioCLI/Studio.cs
+++ b/AssetStudioCLI/Studio.cs
@@ -92,7 +92,7 @@ namespace AssetStudioCLI
var count = 0;
var bundleStream = new OffsetStream(reader);
var bundleReader = new FileReader(reader.FullPath, bundleStream);
- var bundleFile = new BundleFile(bundleReader, assetsManager.ZstdEnabled, assetsManager.SpecifyUnityVersion);
+ var bundleFile = new BundleFile(bundleReader, assetsManager.CustomBlockInfoCompression, assetsManager.CustomBlockCompression, assetsManager.SpecifyUnityVersion);
var extractPath = Path.Combine(savePath, reader.FileName + "_unpacked");
if (bundleFile.fileList.Length > 0)
{
@@ -109,7 +109,7 @@ namespace AssetStudioCLI
bundleReader.FileName = $"{reader.FileName}_0x{bundleStream.Offset:X}";
}
Logger.Info($"[MultiBundle] Decompressing \"{reader.FileName}\" from offset: 0x{bundleStream.Offset:X}..");
- bundleFile = new BundleFile(bundleReader, assetsManager.ZstdEnabled, assetsManager.SpecifyUnityVersion);
+ bundleFile = new BundleFile(bundleReader, assetsManager.CustomBlockInfoCompression, assetsManager.CustomBlockCompression, assetsManager.SpecifyUnityVersion);
if (bundleFile.fileList.Length > 0)
{
count += ExtractStreamFile(extractPath, bundleFile.fileList);
@@ -160,7 +160,8 @@ namespace AssetStudioCLI
{
var isLoaded = false;
assetsManager.SpecifyUnityVersion = CLIOptions.o_unityVersion.Value;
- assetsManager.ZstdEnabled = CLIOptions.o_customCompressionType.Value == CustomCompressionType.Zstd;
+ assetsManager.CustomBlockInfoCompression = CLIOptions.o_bundleBlockInfoCompression.Value;
+ assetsManager.CustomBlockCompression = CLIOptions.o_bundleBlockCompression.Value;
assetsManager.LoadingViaTypeTreeEnabled = !CLIOptions.f_avoidLoadingViaTypetree.Value;
if (!CLIOptions.f_loadAllAssets.Value)
{
diff --git a/AssetStudioGUI/AssetStudioGUI.csproj b/AssetStudioGUI/AssetStudioGUI.csproj
index 5daf55b..f59d08c 100644
--- a/AssetStudioGUI/AssetStudioGUI.csproj
+++ b/AssetStudioGUI/AssetStudioGUI.csproj
@@ -82,6 +82,8 @@
+
+
@@ -107,6 +111,7 @@
+
@@ -114,6 +119,7 @@
+
@@ -121,6 +127,7 @@
+
diff --git a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs
index 4123ce2..f2a28d6 100644
--- a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs
+++ b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs
@@ -47,8 +47,10 @@
this.useDumpTreeViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.buildTreeStructureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.customCompressionTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.customCompressionZstdToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.customCompressionLZ4ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.blockInfoCompressionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem = new System.Windows.Forms.ToolStripComboBox();
+ this.blockCompressionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.customBlockCompressionComboBoxToolStripMenuItem = new System.Windows.Forms.ToolStripComboBox();
this.toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
this.specifyUnityVersion = new System.Windows.Forms.ToolStripTextBox();
this.showExpOpt = new System.Windows.Forms.ToolStripMenuItem();
@@ -359,33 +361,59 @@
// customCompressionTypeToolStripMenuItem
//
this.customCompressionTypeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.customCompressionZstdToolStripMenuItem,
- this.customCompressionLZ4ToolStripMenuItem});
+ this.blockInfoCompressionToolStripMenuItem,
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem,
+ this.blockCompressionToolStripMenuItem,
+ this.customBlockCompressionComboBoxToolStripMenuItem});
this.customCompressionTypeToolStripMenuItem.Name = "customCompressionTypeToolStripMenuItem";
this.customCompressionTypeToolStripMenuItem.Size = new System.Drawing.Size(241, 22);
- this.customCompressionTypeToolStripMenuItem.Text = "Custom compression type";
+ this.customCompressionTypeToolStripMenuItem.Text = "Bundle compression type";
//
- // customCompressionZstdToolStripMenuItem
+ // blockInfoCompressionToolStripMenuItem
//
- this.customCompressionZstdToolStripMenuItem.Checked = true;
- this.customCompressionZstdToolStripMenuItem.CheckOnClick = true;
- this.customCompressionZstdToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
- this.customCompressionZstdToolStripMenuItem.Name = "customCompressionZstdToolStripMenuItem";
- this.customCompressionZstdToolStripMenuItem.Size = new System.Drawing.Size(130, 22);
- this.customCompressionZstdToolStripMenuItem.Text = "Zstd";
- this.customCompressionZstdToolStripMenuItem.ToolTipText = "If selected, Zstd-decompression will be used for assets with custom compression t" +
- "ype";
- this.customCompressionZstdToolStripMenuItem.CheckedChanged += new System.EventHandler(this.customCompressionZstd_CheckedChanged);
+ this.blockInfoCompressionToolStripMenuItem.Enabled = false;
+ this.blockInfoCompressionToolStripMenuItem.Name = "blockInfoCompressionToolStripMenuItem";
+ this.blockInfoCompressionToolStripMenuItem.Size = new System.Drawing.Size(197, 22);
+ this.blockInfoCompressionToolStripMenuItem.Text = "BlockInfo Compression";
//
- // customCompressionLZ4ToolStripMenuItem
+ // customBlockInfoCompressionComboBoxToolStripMenuItem
//
- this.customCompressionLZ4ToolStripMenuItem.CheckOnClick = true;
- this.customCompressionLZ4ToolStripMenuItem.Name = "customCompressionLZ4ToolStripMenuItem";
- this.customCompressionLZ4ToolStripMenuItem.Size = new System.Drawing.Size(130, 22);
- this.customCompressionLZ4ToolStripMenuItem.Text = "Lz4/Lz4HC";
- this.customCompressionLZ4ToolStripMenuItem.ToolTipText = "If selected, Lz4-decompression will be used for assets with custom compression ty" +
- "pe";
- this.customCompressionLZ4ToolStripMenuItem.CheckedChanged += new System.EventHandler(this.customCompressionLZ4_CheckedChanged);
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem.DropDownHeight = 80;
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem.IntegralHeight = false;
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem.Items.AddRange(new object[] {
+ "Auto",
+ "Zstd",
+ "Oodle",
+ "Lz4/Lz4HC",
+ "Lzma"});
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem.Name = "customBlockInfoCompressionComboBoxToolStripMenuItem";
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem.Size = new System.Drawing.Size(100, 23);
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem.ToolTipText = "Selected compression type will override detected type from asset bundle";
+ this.customBlockInfoCompressionComboBoxToolStripMenuItem.SelectedIndexChanged += new System.EventHandler(this.customBlockInfoCompressionComboBoxToolStripMenuItem_SelectedIndexChanged);
+ //
+ // blockCompressionToolStripMenuItem
+ //
+ this.blockCompressionToolStripMenuItem.Enabled = false;
+ this.blockCompressionToolStripMenuItem.Name = "blockCompressionToolStripMenuItem";
+ this.blockCompressionToolStripMenuItem.Size = new System.Drawing.Size(197, 22);
+ this.blockCompressionToolStripMenuItem.Text = "Block Compression";
+ //
+ // customBlockCompressionComboBoxToolStripMenuItem
+ //
+ this.customBlockCompressionComboBoxToolStripMenuItem.DropDownHeight = 80;
+ this.customBlockCompressionComboBoxToolStripMenuItem.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.customBlockCompressionComboBoxToolStripMenuItem.IntegralHeight = false;
+ this.customBlockCompressionComboBoxToolStripMenuItem.Items.AddRange(new object[] {
+ "Auto",
+ "Zstd",
+ "Oodle",
+ "Lz4/Lz4HC",
+ "Lzma"});
+ this.customBlockCompressionComboBoxToolStripMenuItem.Name = "customBlockCompressionComboBoxToolStripMenuItem";
+ this.customBlockCompressionComboBoxToolStripMenuItem.Size = new System.Drawing.Size(100, 23);
+ this.customBlockCompressionComboBoxToolStripMenuItem.ToolTipText = "Selected compression type will override detected type from asset bundle";
+ this.customBlockCompressionComboBoxToolStripMenuItem.SelectedIndexChanged += new System.EventHandler(this.customBlockCompressionComboBoxToolStripMenuItem_SelectedIndexChanged);
//
// toolStripMenuItem14
//
@@ -1746,8 +1774,6 @@
private System.Windows.Forms.ToolStripMenuItem l2DModelWithFadeListToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exportL2DWithFadeLstToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem customCompressionTypeToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem customCompressionZstdToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem customCompressionLZ4ToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem useAssetLoadingViaTypetreeToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator assetLoadingToolStripSeparator;
private System.Windows.Forms.TreeView dumpTreeView;
@@ -1763,6 +1789,10 @@
private System.Windows.Forms.ToolStripMenuItem colorThemeDarkToolStripMenuItem;
private System.Windows.Forms.Label FMODaudioChannelsLabel;
private System.Windows.Forms.ToolStripMenuItem autoPlayAudioAssetsToolStripMenuItem;
+ private System.Windows.Forms.ToolStripComboBox customBlockCompressionComboBoxToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem blockCompressionToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem blockInfoCompressionToolStripMenuItem;
+ private System.Windows.Forms.ToolStripComboBox customBlockInfoCompressionComboBoxToolStripMenuItem;
}
}
diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs
index 9fafa10..41a54b1 100644
--- a/AssetStudioGUI/AssetStudioGUIForm.cs
+++ b/AssetStudioGUI/AssetStudioGUIForm.cs
@@ -145,6 +145,8 @@ namespace AssetStudioGUI
useAssetLoadingViaTypetreeToolStripMenuItem.Checked = Properties.Settings.Default.useTypetreeLoading;
useDumpTreeViewToolStripMenuItem.Checked = Properties.Settings.Default.useDumpTreeView;
autoPlayAudioAssetsToolStripMenuItem.Checked = Properties.Settings.Default.autoplayAudio;
+ customBlockCompressionComboBoxToolStripMenuItem.SelectedIndex = 0;
+ customBlockInfoCompressionComboBoxToolStripMenuItem.SelectedIndex = 0;
FMODinit();
listSearchFilterMode.SelectedIndex = 0;
if (string.IsNullOrEmpty(Properties.Settings.Default.fbxSettings))
@@ -2422,16 +2424,50 @@ namespace AssetStudioGUI
}
}
- private void customCompressionZstd_CheckedChanged(object sender, EventArgs e)
+ private void customBlockCompressionComboBoxToolStripMenuItem_SelectedIndexChanged(object sender, EventArgs e)
{
- customCompressionLZ4ToolStripMenuItem.Checked = !customCompressionZstdToolStripMenuItem.Checked;
- assetsManager.ZstdEnabled = customCompressionZstdToolStripMenuItem.Checked;
+ var selectedTypeIndex = customBlockCompressionComboBoxToolStripMenuItem.SelectedIndex;
+ switch (selectedTypeIndex)
+ {
+ case 0:
+ assetsManager.CustomBlockCompression = CompressionType.Auto;
+ break;
+ case 1:
+ assetsManager.CustomBlockCompression = CompressionType.Zstd;
+ break;
+ case 2:
+ assetsManager.CustomBlockCompression = CompressionType.Oodle;
+ break;
+ case 3:
+ assetsManager.CustomBlockCompression = CompressionType.Lz4HC;
+ break;
+ case 4:
+ assetsManager.CustomBlockCompression = CompressionType.Lzma;
+ break;
+ }
}
- private void customCompressionLZ4_CheckedChanged(object sender, EventArgs e)
+ private void customBlockInfoCompressionComboBoxToolStripMenuItem_SelectedIndexChanged(object sender, EventArgs e)
{
- customCompressionZstdToolStripMenuItem.Checked = !customCompressionLZ4ToolStripMenuItem.Checked;
- assetsManager.ZstdEnabled = customCompressionZstdToolStripMenuItem.Checked;
+ var selectedTypeIndex = customBlockInfoCompressionComboBoxToolStripMenuItem.SelectedIndex;
+ switch (selectedTypeIndex)
+ {
+ case 0:
+ assetsManager.CustomBlockInfoCompression = CompressionType.Auto;
+ break;
+ case 1:
+ assetsManager.CustomBlockInfoCompression = CompressionType.Zstd;
+ break;
+ case 2:
+ assetsManager.CustomBlockInfoCompression = CompressionType.Oodle;
+ break;
+ case 3:
+ assetsManager.CustomBlockInfoCompression = CompressionType.Lz4HC;
+ break;
+ case 4:
+ assetsManager.CustomBlockInfoCompression = CompressionType.Lzma;
+ break;
+ }
}
private void useAssetLoadingViaTypetreeToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
diff --git a/AssetStudioGUI/Studio.cs b/AssetStudioGUI/Studio.cs
index e26140d..eba18b9 100644
--- a/AssetStudioGUI/Studio.cs
+++ b/AssetStudioGUI/Studio.cs
@@ -140,7 +140,7 @@ namespace AssetStudioGUI
var count = 0;
var bundleStream = new OffsetStream(reader);
var bundleReader = new FileReader(reader.FullPath, bundleStream);
- var bundleFile = new BundleFile(bundleReader, assetsManager.ZstdEnabled, assetsManager.SpecifyUnityVersion);
+ var bundleFile = new BundleFile(bundleReader, assetsManager.CustomBlockInfoCompression, assetsManager.CustomBlockCompression, assetsManager.SpecifyUnityVersion);
var extractPath = Path.Combine(savePath, reader.FileName + "_unpacked");
if (bundleFile.fileList.Length > 0)
{
@@ -157,7 +157,7 @@ namespace AssetStudioGUI
bundleReader.FileName = $"{reader.FileName}_0x{bundleStream.Offset:X}";
}
Logger.Info($"[MultiBundle] Decompressing \"{reader.FileName}\" from offset: 0x{bundleStream.Offset:X}..");
- bundleFile = new BundleFile(bundleReader, assetsManager.ZstdEnabled, assetsManager.SpecifyUnityVersion);
+ bundleFile = new BundleFile(bundleReader, assetsManager.CustomBlockInfoCompression, assetsManager.CustomBlockCompression, assetsManager.SpecifyUnityVersion);
if (bundleFile.fileList.Length > 0)
{
count += ExtractStreamFile(extractPath, bundleFile.fileList);