Add oodle compression support (unofficial)

This commit is contained in:
VaDiM 2025-05-09 02:28:03 +03:00
parent 66229e564a
commit 876bafdda1
36 changed files with 430 additions and 125 deletions

View File

@ -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";

View File

@ -16,6 +16,8 @@
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="Microsoft.Bcl.Numerics" Version="9.0.1" />
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
</ItemGroup>
</Project>

View File

@ -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<SerializedFile> assetsFileList = new List<SerializedFile>();
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(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;

View File

@ -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<byte> srcSpanBuffer, Span<byte> 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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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<byte> srcBuffer, Span<byte> 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;
}
}
}

View File

@ -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<byte>.Shared.Rent(compressedSize);
_ = reader.Read(compressedBytes, 0, compressedSize);
var uncompressedSize = (int)blockInfo.uncompressedSize;
var compressedBytes = BigArrayPool<byte>.Shared.Rent(compressedSize);
var uncompressedBytes = BigArrayPool<byte>.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<byte>(compressedBytes, 0, compressedSize);
var uncompressedSpan = new Span<byte>(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;

View File

@ -30,6 +30,8 @@
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\x64\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\win-x86\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\win-x64\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\win-x86\ooz.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\win-x64\ooz.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
</Target>
<Target Name="CopyExtraFilesPortableNet" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == '' AND '$(TargetFramework)' != 'net472' ">
@ -37,12 +39,20 @@
<Copy SourceFiles="$(ProjectDir)Libraries\linux-x64\libAssetStudioFBXNative.so" DestinationFolder="$(TargetDir)runtimes\linux-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\osx-x64\libAssetStudioFBXNative.dylib" DestinationFolder="$(TargetDir)runtimes\osx-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\osx-arm64\libAssetStudioFBXNative.dylib" DestinationFolder="$(TargetDir)runtimes\osx-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-x86\libfmod.so" DestinationFolder="$(TargetDir)runtimes\linux-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-x64\libfmod.so" DestinationFolder="$(TargetDir)runtimes\linux-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-arm64\libfmod.so" DestinationFolder="$(TargetDir)runtimes\linux-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\osx-x64\libfmod.dylib" DestinationFolder="$(TargetDir)runtimes\osx-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\osx-arm64\libfmod.dylib" DestinationFolder="$(TargetDir)runtimes\osx-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\win-arm64\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-x86\libooz.so" DestinationFolder="$(TargetDir)runtimes\linux-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-x64\libooz.so" DestinationFolder="$(TargetDir)runtimes\linux-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-arm64\libooz.so" DestinationFolder="$(TargetDir)runtimes\linux-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\osx-x64\libooz.dylib" DestinationFolder="$(TargetDir)runtimes\osx-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\osx-arm64\libooz.dylib" DestinationFolder="$(TargetDir)runtimes\osx-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-arm64\libTexture2DDecoderNative.so" DestinationFolder="$(TargetDir)runtimes\linux-arm64\native" ContinueOnError="false" />
</Target>
@ -56,6 +66,8 @@
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x86\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x86\native\ooz.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\ooz.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
</Target>
<Target Name="PublishExtraFilesPortableNet" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == '' AND '$(TargetFramework)' != 'net472' ">
@ -63,12 +75,20 @@
<Copy SourceFiles="$(TargetDir)runtimes\linux-x64\native\libAssetStudioFBXNative.so" DestinationFolder="$(PublishDir)runtimes\linux-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\osx-x64\native\libAssetStudioFBXNative.dylib" DestinationFolder="$(PublishDir)runtimes\osx-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\osx-arm64\native\libAssetStudioFBXNative.dylib" DestinationFolder="$(PublishDir)runtimes\osx-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\linux-x86\native\libfmod.so" DestinationFolder="$(PublishDir)runtimes\linux-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\linux-x64\native\libfmod.so" DestinationFolder="$(PublishDir)runtimes\linux-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\linux-arm64\native\libfmod.so" DestinationFolder="$(PublishDir)runtimes\linux-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\osx-x64\native\libfmod.dylib" DestinationFolder="$(PublishDir)runtimes\osx-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\osx-arm64\native\libfmod.dylib" DestinationFolder="$(PublishDir)runtimes\osx-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-arm64\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\linux-x86\native\libooz.so" DestinationFolder="$(PublishDir)runtimes\linux-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\linux-x64\native\libooz.so" DestinationFolder="$(PublishDir)runtimes\linux-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\linux-arm64\native\libooz.so" DestinationFolder="$(PublishDir)runtimes\linux-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\osx-x64\native\libooz.dylib" DestinationFolder="$(PublishDir)runtimes\osx-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\osx-arm64\native\libooz.dylib" DestinationFolder="$(PublishDir)runtimes\osx-arm64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\linux-arm64\native\libTexture2DDecoderNative.so" DestinationFolder="$(PublishDir)runtimes\linux-arm64\native" ContinueOnError="false" />
</Target>
@ -77,6 +97,7 @@
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\Win32\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\Win32\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\win-x86\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\win-x86\ooz.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target>
<Target Name="CopyExtraFilesWin64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-x64' ">
@ -84,6 +105,7 @@
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\x64\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\x64\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\win-x64\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\win-x64\ooz.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target>
<Target Name="PublishExtraFilesWin" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('win-x')) ">
@ -91,6 +113,7 @@
<Copy SourceFiles="$(TargetDir)\AssetStudioFBXNative.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\fmod.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\ooz.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
</Target>
<Target Name="CopyExtraFilesWinArm64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-arm64' ">
@ -107,36 +130,42 @@
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-x64\libAssetStudioFBXNative.so" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-x64\libfmod.so" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-x64\libooz.so" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target>
<Target Name="PublishExtraFilesLinux64" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == 'linux-x64' ">
<Message Text="Publishing extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
<Copy SourceFiles="$(TargetDir)\libAssetStudioFBXNative.so" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\libfmod.so" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\libooz.so" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
</Target>
<Target Name="CopyExtraFilesLinuxArm64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'linux-arm64' ">
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-arm64\libTexture2DDecoderNative.so" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-arm64\libfmod.so" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\linux-arm64\libooz.so" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target>
<Target Name="PublishExtraFilesLinuxArm64" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == 'linux-arm64' ">
<Message Text="Publishing extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
<Copy SourceFiles="$(TargetDir)\libTexture2DDecoderNative.so" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\libfmod.so" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\libooz.so" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
</Target>
<Target Name="CopyExtraFilesMac" AfterTargets="AfterBuild" Condition=" $(RuntimeIdentifier.Contains('osx-')) ">
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
<Copy SourceFiles="$(ProjectDir)Libraries\$(RuntimeIdentifier)\libAssetStudioFBXNative.dylib" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\$(RuntimeIdentifier)\libfmod.dylib" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\$(RuntimeIdentifier)\libooz.dylib" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target>
<Target Name="PublishExtraFilesMac" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('osx-')) ">
<Message Text="Publishing extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
<Copy SourceFiles="$(TargetDir)\libAssetStudioFBXNative.dylib" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\libfmod.dylib" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\libooz.dylib" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
</Target>
</Project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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<List<string>> o_filterByPathID;
public static Option<List<string>> o_filterByText;
//advanced
public static Option<CustomCompressionType> o_customCompressionType;
public static Option<CompressionType> o_bundleBlockInfoCompression;
public static Option<CompressionType> o_bundleBlockCompression;
public static Option<int> o_maxParallelExportTasks;
public static Option<ExportListType> o_exportAssetList;
public static Option<string> o_assemblyPath;
@ -425,15 +420,33 @@ namespace AssetStudioCLI.Options
#endregion
#region Init Advanced Options
o_customCompressionType = new GroupedOption<CustomCompressionType>
o_bundleBlockInfoCompression = new GroupedOption<CompressionType>
(
optionDefaultValue: CustomCompressionType.Zstd,
optionName: "--custom-compression <value>",
optionDescription: "Specify the compression type for assets that use custom compression\n" +
"<Value: zstd(default) | lz4>\n" +
optionDefaultValue: CompressionType.Auto,
optionName: "--blockinfo-comp <value>",
optionDescription: "Specify the compression type of bundle's blockInfo data\n" +
"<Value: auto(default) | zstd | oodle | lz4 | lzma>\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<CompressionType>
(
optionDefaultValue: CompressionType.Auto,
optionName: "--block-comp <value>",
optionDescription: "Specify the compression type of bundle's block data\n" +
"<Value: auto(default) | zstd | oodle | lz4 | lzma>\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:

View File

@ -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)
{

View File

@ -82,6 +82,8 @@
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\x64\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\x86\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\x64\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\x86\ooz.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\x64\ooz.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
</Target>
<!-- Publishing an app as framework-dependent produces a cross-platform binary as a dll file, and a platform-specific executable that targets your current platform.
@ -94,6 +96,8 @@
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x86\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x86\native\ooz.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\ooz.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
</Target>
<!-- No need to publish net472 build of AssetStudioGUI -->
@ -107,6 +111,7 @@
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\Win32\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\Win32\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\x86\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\x86\ooz.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target>
<Target Name="CopyExtraFilesWin64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-x64' AND '$(TargetFramework)' != 'net472' ">
@ -114,6 +119,7 @@
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\x64\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\x64\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\x64\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\x64\ooz.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target>
<Target Name="PublishExtraFilesWin" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('win')) AND '$(TargetFramework)' != 'net472' ">
@ -121,6 +127,7 @@
<Copy SourceFiles="$(TargetDir)\AssetStudioFBXNative.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\fmod.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\ooz.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
</Target>
</Project>

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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);