mirror of
https://github.com/aelurum/AssetStudio.git
synced 2026-11-14 11:18:47 -05:00
[GUI] Rework some import options
- Added feature to load and export import options to a file (import options include unity version). - Added option to always decompress bundles to disk. (Related issue: #58 )
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
|
||||
namespace AssetStudio.CustomOptions.Asmo
|
||||
{
|
||||
public class OptionsFile
|
||||
{
|
||||
private static readonly byte[] OptionsFileSign = new byte[] { 0x41, 0x53, 0x4D, 0x4F }; //ASMO
|
||||
public static readonly string Extension = ".asmo";
|
||||
|
||||
public byte[] Signature { get; private set; } = OptionsFileSign;
|
||||
public short Version { get; private set; } = 1;
|
||||
public short Reserved { get; set; }
|
||||
public uint DataCrc { get; set; }
|
||||
public int DataSize { get; set; }
|
||||
public byte[] Data { get; set; }
|
||||
|
||||
public OptionsFile() { }
|
||||
|
||||
public OptionsFile(EndianBinaryReader reader)
|
||||
{
|
||||
Signature = reader.ReadBytes(4);
|
||||
Version = reader.ReadInt16();
|
||||
Reserved = reader.ReadInt16();
|
||||
DataCrc = reader.ReadUInt32();
|
||||
DataSize = reader.ReadInt32();
|
||||
CheckHeader(reader.BaseStream.Length);
|
||||
Data = reader.ReadBytes(DataSize);
|
||||
}
|
||||
|
||||
public void CheckHeader(long fileLength)
|
||||
{
|
||||
if (!Signature.AsSpan().SequenceEqual(OptionsFileSign))
|
||||
throw new NotSupportedException("Incorrect options file signature.");
|
||||
|
||||
if (Version != 1)
|
||||
throw new NotSupportedException("Incorrect options file version.");
|
||||
|
||||
if (DataSize <= 0 || DataSize > fileLength)
|
||||
throw new NotSupportedException("Incorrect data size.");
|
||||
}
|
||||
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
var buffer = new byte[16 + DataSize];
|
||||
OptionsFileSign.AsSpan().CopyTo(buffer);
|
||||
BinaryPrimitives.WriteInt16BigEndian(buffer.AsSpan(4), Version);
|
||||
BinaryPrimitives.WriteInt16BigEndian(buffer.AsSpan(6), Reserved);
|
||||
BinaryPrimitives.WriteUInt32BigEndian(buffer.AsSpan(8), DataCrc);
|
||||
BinaryPrimitives.WriteInt32BigEndian(buffer.AsSpan(12), DataSize);
|
||||
Data.AsSpan().CopyTo(buffer.AsSpan(16));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
namespace AssetStudio.CustomOptions
|
||||
{
|
||||
public class CustomBundleOptions
|
||||
{
|
||||
private CompressionType _customBlockCompression = CompressionType.Auto;
|
||||
private CompressionType _customBlockInfoCompression = CompressionType.Auto;
|
||||
private bool _decompressToDisk;
|
||||
|
||||
public ImportOptions Options;
|
||||
|
||||
public CompressionType CustomBlockCompression
|
||||
{
|
||||
get => _customBlockCompression;
|
||||
set => _customBlockCompression = SetOption(nameof(CustomBlockCompression), value);
|
||||
}
|
||||
public CompressionType CustomBlockInfoCompression
|
||||
{
|
||||
get => _customBlockInfoCompression;
|
||||
set => _customBlockInfoCompression = SetOption(nameof(CustomBlockInfoCompression), value);
|
||||
}
|
||||
public bool DecompressToDisk
|
||||
{
|
||||
get => _decompressToDisk;
|
||||
set => _decompressToDisk = SetOption(nameof(DecompressToDisk), value);
|
||||
}
|
||||
|
||||
public CustomBundleOptions() { }
|
||||
|
||||
public CustomBundleOptions(ImportOptions importOptions)
|
||||
{
|
||||
Options = importOptions;
|
||||
}
|
||||
|
||||
private static T SetOption<T>(string option, T value)
|
||||
{
|
||||
Logger.Info($"- {option}: {value}");
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using AssetStudio.CustomOptions.Asmo;
|
||||
using SevenZip;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio.CustomOptions
|
||||
{
|
||||
public class ImportOptions
|
||||
{
|
||||
private static JsonSerializerOptions jsonOptions;
|
||||
private static string fileName = "ImportOptions";
|
||||
private UnityVersion _customUnityVer;
|
||||
|
||||
public CustomBundleOptions BundleOptions { get; set; }
|
||||
public UnityVersion CustomUnityVersion { get => _customUnityVer; set => SetUnityVersion(value); }
|
||||
|
||||
static ImportOptions()
|
||||
{
|
||||
jsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
ReferenceHandler = ReferenceHandler.Preserve,
|
||||
IncludeFields = true,
|
||||
};
|
||||
}
|
||||
|
||||
public ImportOptions()
|
||||
{
|
||||
BundleOptions = new CustomBundleOptions(this);
|
||||
CustomUnityVersion = null;
|
||||
}
|
||||
|
||||
public static ImportOptions FromOptionsFile(OptionsFile optionsFile)
|
||||
{
|
||||
if (optionsFile.Reserved != 0)
|
||||
{
|
||||
Logger.Debug("Skipped. Not an import options file.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var utf8Bytes = Convert.FromBase64String(Encoding.ASCII.GetString(optionsFile.Data));
|
||||
var dataCrc = CRC.CalculateDigest(utf8Bytes, 0, (uint)utf8Bytes.Length);
|
||||
if (optionsFile.DataCrc != dataCrc)
|
||||
throw new IOException("Options file data is corrupted.");
|
||||
|
||||
return JsonSerializer.Deserialize<ImportOptions>(utf8Bytes, jsonOptions);
|
||||
}
|
||||
|
||||
public void SaveToFile(string outputFolder)
|
||||
{
|
||||
var utf8Bytes = JsonSerializer.SerializeToUtf8Bytes(this, jsonOptions);
|
||||
var dataCrc = CRC.CalculateDigest(utf8Bytes, 0, (uint)utf8Bytes.Length);
|
||||
var base64String = Convert.ToBase64String(utf8Bytes);
|
||||
|
||||
var optionsFile = new OptionsFile
|
||||
{
|
||||
DataCrc = dataCrc,
|
||||
DataSize = base64String.Length,
|
||||
Data = Encoding.ASCII.GetBytes(base64String),
|
||||
};
|
||||
|
||||
var unityVer = _customUnityVer != null
|
||||
? $"_{_customUnityVer}"
|
||||
: "";
|
||||
var path = Path.Combine(outputFolder, $"{fileName}{unityVer}{OptionsFile.Extension}");
|
||||
File.WriteAllBytes(path, optionsFile.ToByteArray());
|
||||
|
||||
Logger.Info($"Options file saved to \"{path}\"");
|
||||
}
|
||||
|
||||
private void SetUnityVersion(UnityVersion value)
|
||||
{
|
||||
if (_customUnityVer == value)
|
||||
return;
|
||||
if (value == null)
|
||||
{
|
||||
_customUnityVer = null;
|
||||
Logger.Info("- Specified Unity version: None");
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(value.BuildType))
|
||||
{
|
||||
throw new NotSupportedException("Specified Unity version is not in a correct format.\n" +
|
||||
"Specify full Unity version, including letters at the end.\n" +
|
||||
"Example: 2017.4.39f1");
|
||||
}
|
||||
_customUnityVer = value;
|
||||
|
||||
Logger.Info($"- Specified Unity version: {_customUnityVer}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user