9 Commits

Author SHA1 Message Date
VaDiM
6b66ec7467 Fix rendering of some packed sprites. Close #104 2025-10-15 22:23:42 +03:00
VaDiM
0021cf221e Some minor improvements 2025-10-11 14:28:05 +03:00
VaDiM
c07dc59f51 Improve support for Unity 6000.2+ assets 2025-10-10 04:11:27 +03:00
VaDiM
d1bf0c5a37 Add option to extract raw byte array from MonoBehaviour assets 2025-10-07 01:07:48 +03:00
VaDiM
6d5b633d55 Some minor fixes 2025-10-07 01:07:14 +03:00
VaDiM
6c3ff89dbf Improve lzma progress report 2025-09-12 19:57:36 +03:00
VaDiM
763f188afb Fix memory allocation for uncompressed bundles inside a multiBundle 2025-09-08 03:06:03 +03:00
VaDiM
553f0d94f3 Some fixes for Live2D export
- [CLI] Replaced "--l2d-force-bezier" with "--l2d-smooth-motions"
2025-09-06 03:50:55 +03:00
VaDiM
80e6a1d074 Update README.md 2025-09-04 23:10:34 +03:00
21 changed files with 283 additions and 84 deletions

View File

@@ -249,7 +249,7 @@ namespace SevenZip.Compression.LZMA
nowPos64++;
}
Progress.Reset();
Progress.Reset(index: 1);
while (nowPos64 < outSize64)
{
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
@@ -342,7 +342,7 @@ namespace SevenZip.Compression.LZMA
m_OutWindow.CopyBlock(rep0, len);
nowPos64 += len;
Progress.Report((int)(nowPos64 * 100f / outSize64), 100);
Progress.Report((int)(nowPos64 * 100f / outSize64), 100, index: 1);
}
}
}

View File

@@ -87,9 +87,7 @@ namespace AssetStudio
m_Header.signature = reader.ReadStringToNull();
m_Header.version = reader.ReadUInt32();
m_Header.unityVersion = reader.ReadStringToNull();
var revStr = reader.ReadStringToNull();
if (!UnityVersion.TryParse(revStr, out m_Header.unityRevision))
m_Header.unityRevision = new UnityVersion();
m_Header.unityRevision = UnityVersion.TryParse(reader.ReadStringToNull(), out var ver) ? ver : new UnityVersion();
switch (m_Header.signature)
{
@@ -432,7 +430,7 @@ namespace AssetStudio
byte[] sharedCompressedBuff = null;
byte[] sharedUncompressedBuff = null;
if (blocksCompression != CompressionType.Lzma && blocksCompression != CompressionType.Lzham)
if (blocksCompression > CompressionType.Lzma && blocksCompression != CompressionType.Lzham)
{
sharedCompressedBuff = BigArrayPool<byte>.Shared.Rent(blockSize);
sharedUncompressedBuff = BigArrayPool<byte>.Shared.Rent(blockSize);
@@ -440,14 +438,16 @@ namespace AssetStudio
try
{
foreach (var blockInfo in m_BlocksInfo)
for (var i = 0; i < m_BlocksInfo.Length; i++)
{
var blockInfo = m_BlocksInfo[i];
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
if (customBlockCompression != CompressionType.Auto && compressionType > 0)
{
compressionType = customBlockCompression;
}
var debugMsg = $"[{i:D2}] Compression: {compressionType} | UncompressedSize: {blockInfo.uncompressedSize} | CompressedSize: {blockInfo.compressedSize} ";
long numWrite;
var errorMsg = string.Empty;
@@ -458,7 +458,6 @@ namespace AssetStudio
numWrite = blockInfo.compressedSize;
break;
case CompressionType.Lzma:
Logger.Info("Decompressing LZMA stream...");
numWrite = BundleDecompressionHelper.DecompressLzmaStream(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize, ref errorMsg);
break;
case CompressionType.Lz4:
@@ -471,7 +470,8 @@ namespace AssetStudio
sharedCompressedBuff.AsSpan().Clear();
sharedUncompressedBuff.AsSpan().Clear();
_ = reader.Read(sharedCompressedBuff, 0, compressedSize);
var read = reader.Read(sharedCompressedBuff, 0, compressedSize);
debugMsg += $"(read: {read.ToString().ColorIf(read != compressedSize, ColorConsole.BrightRed)})";
var compressedSpan = new ReadOnlySpan<byte>(sharedCompressedBuff, 0, compressedSize);
var uncompressedSpan = new Span<byte>(sharedUncompressedBuff, 0, uncompressedSize);
@@ -479,7 +479,6 @@ namespace AssetStudio
if (numWrite == uncompressedSize)
{
blocksStream.Write(sharedUncompressedBuff, 0, uncompressedSize);
continue;
}
break;
case CompressionType.Lzham:
@@ -487,6 +486,7 @@ namespace AssetStudio
default:
throw new IOException($"Unknown block compression type: {compressionType}.\nYou may try to specify the compression type manually.\n");
}
Logger.Debug(debugMsg);
if (numWrite != blockInfo.uncompressedSize)
{

View File

@@ -510,6 +510,7 @@ namespace AssetStudio
public Vector3[] m_PositionValues;
public Vector4[] m_QuaternionValues;
public Vector3[] m_ScaleValues;
public int[] m_EntityIdValues;
public ValueArray(ObjectReader reader)
{
@@ -557,6 +558,10 @@ namespace AssetStudio
m_IntValues = reader.ReadInt32Array();
m_BoolValues = reader.ReadBooleanArray();
reader.AlignStream();
if (version >= (6000, 2)) //6000.2 and up
{
m_EntityIdValues = reader.ReadInt32Array();
}
}
}
}

View File

@@ -811,6 +811,8 @@ namespace AssetStudio
m_HasVirtualGeometryMesh = reader.ReadBoolean();
}
//m_MeshLodInfo = new MeshLodInfo(reader) //6000.2 and up
if (!assetsFile.assetsManager.MeshLazyLoad)
ProcessData();
}

View File

@@ -79,6 +79,12 @@ namespace AssetStudio
var m_SmallMeshCulling = reader.ReadByte();
}
reader.AlignStream();
if (version >= (6000, 2)) //6000.2 and up
{
var m_ForceMeshLod = reader.ReadInt16();
reader.AlignStream();
var m_MeshLodSelectionBias = reader.ReadSingle();
}
}
else
{
@@ -174,6 +180,11 @@ namespace AssetStudio
var m_SortingOrder = reader.ReadInt16();
reader.AlignStream();
if (version >= (6000, 3)) //6000.3 and up
{
var m_MaskInteraction = reader.ReadInt32();
}
}
}
}

View File

@@ -10,9 +10,9 @@ namespace AssetStudio
Black = "\u001b[30m",
Red = "\u001b[31m",
Green = "\u001b[32m",
Yellow = "\u001b[33m", //remapped to ~BrightWhite in Windows PowerShell 6
Yellow = "\u001b[33m", //remapped to ~BrightWhite in Windows PowerShell 6
Blue = "\u001b[34m",
Magenta = "\u001b[35m", //remapped to ~Blue in Windows PowerShell 6
Magenta = "\u001b[35m", //remapped to ~Blue in Windows PowerShell 6
Cyan = "\u001b[36m",
White = "\u001b[37m",
BrightBlack = "\u001b[30;1m",
@@ -28,13 +28,22 @@ namespace AssetStudio
public static string Color(this string str, string ansiColor)
{
if (!ColorConsoleHelper.isAnsiCodesSupported)
{
return str;
}
return $"{ansiColor}{str}{Reset}";
}
public static string ColorIf(this string str, bool isTrue, string ansiColor, string defaultAnsiColor = null)
{
if (isTrue)
return str.Color(ansiColor);
if (defaultAnsiColor != null)
return str.Color(defaultAnsiColor);
return str;
}
public static void AnsiCodesTest()
{
Console.WriteLine("ANSI escape codes test");
@@ -45,5 +54,4 @@ namespace AssetStudio
Console.WriteLine("\u001b[34;1m E \u001b[35;1m F \u001b[36;1m G \u001b[37;1m H \u001b[0m");
}
}
}

View File

@@ -116,6 +116,8 @@ namespace AssetStudio
{1152, "FileSize"},
{1161, "Hash128"},
{1169, "RenderingLayerMask"},
{1188, "fixed_array"},
{1200, "EntityId"},
};
}
}

View File

@@ -4,28 +4,58 @@ namespace AssetStudio
{
public static class Progress
{
public static IProgress<int> Default = new Progress<int>();
private static int preValue;
private static readonly int InstanceCount = 2;
private static readonly IProgress<int>[] Instances;
private static readonly int[] PreValues;
public static void Reset()
static Progress()
{
preValue = 0;
Default.Report(0);
Instances = new IProgress<int>[InstanceCount];
for (var i = 0; i < InstanceCount; i++)
{
Instances[i] = new Progress<int>();
}
PreValues = new int[InstanceCount];
}
public static void Report(int current, int total)
public static int MaxCount => InstanceCount;
public static IProgress<int> Default //alias
{
get => Instances[0];
set => SetInstance(0, value);
}
public static void Reset(int index = 0)
{
PreValues[index] = 0;
Instances[index].Report(0);
}
public static void Report(int current, int total, int index = 0)
{
var value = (int)(current * 100f / total);
Report(value);
_Report(value, index);
}
private static void Report(int value)
private static void _Report(int value, int index)
{
if (value > preValue)
if (value > PreValues[index])
{
preValue = value;
Default.Report(value);
PreValues[index] = value;
Instances[index].Report(value);
}
}
public static void SetInstance(int index, IProgress<int> progress)
{
if (progress == null)
throw new ArgumentNullException(nameof(progress));
if (index < 0 || index >= MaxCount)
throw new ArgumentOutOfRangeException(nameof(index));
Instances[index] = progress;
}
}
}

View File

@@ -315,6 +315,31 @@ namespace AssetStudioCLI
m_VideoClip.m_VideoData.WriteData(exportFullPath.Replace(".dat", "_data.dat"));
}
break;
case MonoBehaviour m_MonoBehaviour when CLIOptions.f_rawByteArrayFromMono.Value:
var reader = m_MonoBehaviour.reader;
reader.Reset();
var assetData = reader.ReadBytes(28); //PPtr<GameObject> m_GameObject, m_Enabled, PPtr<MonoScript>
var assetNameLen = reader.ReadInt32();
reader.Position -= 4;
var assetNameBytes = reader.ReadBytes(assetNameLen + 4);
if (assetNameLen > 0)
reader.AlignStream();
var arrayLen = reader.ReadInt32();
if (arrayLen <= 0 || arrayLen > reader.Remaining)
break;
using (var outStream = new FileStream(exportFullPath.Replace(".dat", "_extracted.dat"), FileMode.Create))
{
reader.BaseStream.CopyTo(outStream, size: arrayLen);
}
using (var outStream = new FileStream(exportFullPath, FileMode.Create))
{
outStream.Write(assetData, 0, assetData.Length);
outStream.Write(assetNameBytes, 0, assetNameBytes.Length);
if (reader.Remaining > 0)
reader.BaseStream.CopyTo(outStream, size: reader.Remaining);
}
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
return true;
}
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());

View File

@@ -128,6 +128,7 @@ namespace AssetStudioCLI.Options
public static Option<bool> f_decompressToDisk;
public static Option<bool> f_notRestoreExtensionName;
public static Option<bool> f_avoidLoadingViaTypetree;
public static Option<bool> f_rawByteArrayFromMono;
public static Option<bool> f_loadAllAssets;
static CLIOptions()
@@ -360,7 +361,7 @@ namespace AssetStudioCLI.Options
f_l2dForceBezier = new GroupedOption<bool>
(
optionDefaultValue: false,
optionName: "--l2d-force-bezier",
optionName: "--l2d-smooth-motions",
optionDescription: "(Flag) If specified, Linear motion segments will be calculated as Bezier segments\n" +
"(May help if the exported motions look jerky/not smooth enough)",
optionExample: "",
@@ -557,6 +558,15 @@ namespace AssetStudioCLI.Options
optionHelpGroup: HelpGroups.Advanced,
isFlag: true
);
f_rawByteArrayFromMono = new GroupedOption<bool>
(
optionDefaultValue: false,
optionName: "--raw-array",
optionDescription: "(Flag) If specified, Studio will try to extract raw byte array from MonoBehaviour assets\n(Only for ExportRaw mode)\n",
optionExample: "",
optionHelpGroup: HelpGroups.Advanced,
isFlag: true
);
f_loadAllAssets = new GroupedOption<bool>
(
optionDefaultValue: false,
@@ -705,7 +715,7 @@ namespace AssetStudioCLI.Options
f_l2dAssetSearchByFilename.Value = true;
flagIndexes.Add(i);
break;
case "--l2d-force-bezier":
case "--l2d-smooth-motions":
if (o_workMode.Value != WorkMode.Live2D)
{
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{flag.Color(brightYellow)}] flag. This flag is not suitable for the current working mode [{o_workMode.Value}].\n");
@@ -741,6 +751,16 @@ namespace AssetStudioCLI.Options
f_avoidLoadingViaTypetree.Value = true;
flagIndexes.Add(i);
break;
case "--raw-array":
if (o_workMode.Value != WorkMode.ExportRaw)
{
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{flag.Color(brightYellow)}] flag. This flag is not suitable for the current working mode [{o_workMode.Value}].\n");
ShowOptionDescription(f_rawByteArrayFromMono, isFlag: true);
return;
}
f_rawByteArrayFromMono.Value = true;
flagIndexes.Add(i);
break;
case "--load-all":
switch (o_workMode.Value)
{
@@ -1252,7 +1272,7 @@ namespace AssetStudioCLI.Options
}
catch (Exception ex)
{
Console.WriteLine("Unknown Error.".Color(ColorConsole.Red));
Console.WriteLine("Unknown Error.".Color(ColorConsole.BrightRed));
Console.WriteLine(ex);
return;
}
@@ -1431,6 +1451,10 @@ namespace AssetStudioCLI.Options
sb.AppendLine($"# Restore TextAsset Extension: {!f_notRestoreExtensionName.Value}");
sb.AppendLine($"# Max Parallel Export Tasks: {o_maxParallelExportTasks}");
}
if (o_workMode.Value == WorkMode.ExportRaw)
{
sb.AppendLine($"# Extract Raw Byte Array From MonoBehaviour: {f_rawByteArrayFromMono}");
}
sb.AppendLine(ShowCurrentFilter());
sb.AppendLine($"# Filter With Regex: {f_filterWithRegex}");
sb.AppendLine($"# Assembly Path: \"{o_assemblyPath}\"");

View File

@@ -30,6 +30,7 @@ namespace AssetStudioCLI
{
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
Progress.Default = new Progress<int>(ShowCurProgressValue);
Progress.SetInstance(1, new Progress<int>(ShowCurProgressValue));
assetsManager.LoadViaTypeTree = !CLIOptions.f_avoidLoadingViaTypetree.Value;
assetsManager.Options.CustomUnityVersion = CLIOptions.o_unityVersion.Value;
assetsManager.Options.BundleOptions.CustomBlockInfoCompression = CLIOptions.o_bundleBlockInfoCompression.Value;
@@ -519,11 +520,11 @@ namespace AssetStudioCLI
info += $"\n#\n# Total: {parsedAssetsList.Count} assets";
}
info += $"\n\n# Exportable Live2D Models: {l2dModelDict.Count}";
info += $"\n\n[Cubism Live2D]\n# Exportable Models: {l2dModelDict.Count}";
}
else
{
info += "No exportable assets found.";
info += "\n\nNo exportable assets found.";
}
if (CLIOptions.o_logLevel.Value > LoggerEvent.Info)
@@ -793,13 +794,10 @@ namespace AssetStudioCLI
{
Logger.Default.Log(LoggerEvent.Info, "Nothing exported.", ignoreLevel: true);
}
else if (toExportCount > exportedCount)
{
Logger.Default.Log(LoggerEvent.Info, $"Finished exporting {exportedCount} asset(s) to \"{CLIOptions.o_outputFolder.Value.Color(Ansi.BrightYellow)}\".", ignoreLevel: true);
}
else
{
Logger.Default.Log(LoggerEvent.Info, $"Finished exporting {exportedCount} asset(s) to \"{CLIOptions.o_outputFolder.Value.Color(Ansi.BrightGreen)}\".", ignoreLevel: true);
var outPath = CLIOptions.o_outputFolder.Value.ColorIf(toExportCount > exportedCount, Ansi.BrightYellow, Ansi.BrightGreen);
Logger.Default.Log(LoggerEvent.Info, $"Finished exporting {exportedCount} asset(s) to \"{outPath}\".", ignoreLevel: true);
}
if (toExportCount > exportedCount)

View File

@@ -48,7 +48,7 @@
this.useDumpTreeViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.buildTreeStructureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.importOptionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.specifyUnityVersionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.customUnityVersionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.specifyUnityVersionTextBox = new System.Windows.Forms.ToolStripTextBox();
this.bundleDecompressionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.alwaysDecompressToDiskToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -377,7 +377,7 @@
// importOptionsToolStripMenuItem
//
this.importOptionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.specifyUnityVersionToolStripMenuItem,
this.customUnityVersionToolStripMenuItem,
this.specifyUnityVersionTextBox,
this.bundleDecompressionToolStripMenuItem,
this.alwaysDecompressToDiskToolStripMenuItem,
@@ -393,17 +393,17 @@
this.importOptionsToolStripMenuItem.DropDownClosed += new System.EventHandler(this.importOptions_DropDownClose);
this.importOptionsToolStripMenuItem.DropDownOpened += new System.EventHandler(this.importOptions_DropDownOpened);
//
// specifyUnityVersionToolStripMenuItem
// customUnityVersionToolStripMenuItem
//
this.specifyUnityVersionToolStripMenuItem.Enabled = false;
this.specifyUnityVersionToolStripMenuItem.Name = "specifyUnityVersionToolStripMenuItem";
this.specifyUnityVersionToolStripMenuItem.ShowShortcutKeys = false;
this.specifyUnityVersionToolStripMenuItem.Size = new System.Drawing.Size(217, 22);
this.specifyUnityVersionToolStripMenuItem.Text = "Specify Unity version";
this.specifyUnityVersionToolStripMenuItem.ToolTipText = "Specify full Unity version, including letters at the end\r\nExample: 2017.4.39f1";
this.customUnityVersionToolStripMenuItem.Enabled = false;
this.customUnityVersionToolStripMenuItem.Name = "customUnityVersionToolStripMenuItem";
this.customUnityVersionToolStripMenuItem.ShowShortcutKeys = false;
this.customUnityVersionToolStripMenuItem.Size = new System.Drawing.Size(217, 22);
this.customUnityVersionToolStripMenuItem.Text = "Custom Unity version";
//
// specifyUnityVersionTextBox
//
this.specifyUnityVersionTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.specifyUnityVersionTextBox.Font = new System.Drawing.Font("Segoe UI", 9F);
this.specifyUnityVersionTextBox.Name = "specifyUnityVersionTextBox";
this.specifyUnityVersionTextBox.Size = new System.Drawing.Size(100, 23);
@@ -1860,7 +1860,7 @@
private System.Windows.Forms.ToolStripMenuItem autoPlayAudioAssetsToolStripMenuItem;
private System.Windows.Forms.CheckBox sceneExactSearchCheckBox;
private System.Windows.Forms.ToolStripMenuItem importOptionsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem specifyUnityVersionToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem customUnityVersionToolStripMenuItem;
private System.Windows.Forms.ToolStripTextBox specifyUnityVersionTextBox;
private System.Windows.Forms.ToolStripMenuItem bundleDecompressionToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem alwaysDecompressToDiskToolStripMenuItem;

View File

@@ -89,10 +89,10 @@ namespace AssetStudioGUI
private int sortColumn = -1;
private bool reverseSort;
#if NET6_0_OR_GREATER
private AlphanumComparatorFastNet alphanumComparator = new AlphanumComparatorFastNet();
#else
#if NETFRAMEWORK
private AlphanumComparatorFast alphanumComparator = new AlphanumComparatorFast();
#else
private AlphanumComparatorFastNet alphanumComparator = new AlphanumComparatorFastNet();
#endif
//asset list selection
@@ -118,6 +118,9 @@ namespace AssetStudioGUI
private GUILogger logger;
private TaskbarManager taskbar = TaskbarManager.Instance;
private System.Drawing.Font progressBarTextFont;
private Brush progressBarTextBrush;
private StringFormat progressBarTextFormat;
[DllImport("gdi32.dll")]
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts);
@@ -157,7 +160,16 @@ namespace AssetStudioGUI
Logger.Default = logger;
writeLogToFileToolStripMenuItem.Checked = Properties.Settings.Default.useFileLogger;
progressBarTextFont = new System.Drawing.Font(FontFamily.GenericSansSerif, 8);
progressBarTextBrush = new SolidBrush(SystemColors.ControlText);
progressBarTextFormat = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center,
};
Progress.Default = new Progress<int>(SetProgressBarValue);
Progress.SetInstance(index: 1, new Progress<int>(SetProgressBarStringValue));
Studio.StatusStripUpdate = StatusStripUpdate;
}
@@ -1530,6 +1542,33 @@ namespace AssetStudioGUI
}));
}
private void SetProgressBarStringValue(int value)
{
var str = $"Decompressing LZMA: {value}%";
if (InvokeRequired)
{
BeginInvoke(new Action(() =>
{
using (var graphics = progressBar1.CreateGraphics())
{
progressBar1.Refresh();
var rect = new Rectangle(0, 0, progressBar1.Width, progressBar1.Height);
graphics.DrawString(str, progressBarTextFont, progressBarTextBrush, rect, progressBarTextFormat);
}
}));
}
else
{
using (var graphics = progressBar1.CreateGraphics())
{
progressBar1.Refresh();
var rect = new Rectangle(0, 0, progressBar1.Width, progressBar1.Height);
graphics.DrawString(str, progressBarTextFont, progressBarTextBrush, rect, progressBarTextFormat);
}
}
}
private void StatusStripUpdate(string statusText)
{
if (InvokeRequired)

View File

@@ -32,6 +32,8 @@
this.OKbutton = new System.Windows.Forms.Button();
this.Cancel = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.rawByteArrayFromMono = new System.Windows.Forms.CheckBox();
this.overwriteExistingFiles = new System.Windows.Forms.CheckBox();
this.parallelExportMaxLabel = new System.Windows.Forms.Label();
this.parallelExportCheckBox = new System.Windows.Forms.CheckBox();
this.parallelExportUpDown = new System.Windows.Forms.NumericUpDown();
@@ -82,7 +84,6 @@
this.exportAllNodes = new System.Windows.Forms.CheckBox();
this.eulerFilter = new System.Windows.Forms.CheckBox();
this.optionTooltip = new System.Windows.Forms.ToolTip(this.components);
this.overwriteExistingFiles = new System.Windows.Forms.CheckBox();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.parallelExportUpDown)).BeginInit();
this.panel1.SuspendLayout();
@@ -97,7 +98,7 @@
// OKbutton
//
this.OKbutton.BackColor = System.Drawing.SystemColors.ButtonFace;
this.OKbutton.Location = new System.Drawing.Point(460, 448);
this.OKbutton.Location = new System.Drawing.Point(460, 459);
this.OKbutton.Name = "OKbutton";
this.OKbutton.Size = new System.Drawing.Size(75, 23);
this.OKbutton.TabIndex = 4;
@@ -109,7 +110,7 @@
//
this.Cancel.BackColor = System.Drawing.SystemColors.ButtonFace;
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.Cancel.Location = new System.Drawing.Point(541, 448);
this.Cancel.Location = new System.Drawing.Point(541, 459);
this.Cancel.Name = "Cancel";
this.Cancel.Size = new System.Drawing.Size(75, 23);
this.Cancel.TabIndex = 5;
@@ -121,6 +122,7 @@
//
this.groupBox1.AutoSize = true;
this.groupBox1.BackColor = System.Drawing.SystemColors.Menu;
this.groupBox1.Controls.Add(this.rawByteArrayFromMono);
this.groupBox1.Controls.Add(this.overwriteExistingFiles);
this.groupBox1.Controls.Add(this.parallelExportMaxLabel);
this.groupBox1.Controls.Add(this.parallelExportCheckBox);
@@ -137,11 +139,31 @@
this.groupBox1.Controls.Add(this.converttexture);
this.groupBox1.Location = new System.Drawing.Point(12, 13);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(316, 280);
this.groupBox1.Size = new System.Drawing.Size(316, 303);
this.groupBox1.TabIndex = 1;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Export";
//
// rawByteArrayFromMono
//
this.rawByteArrayFromMono.AutoSize = true;
this.rawByteArrayFromMono.Location = new System.Drawing.Point(6, 267);
this.rawByteArrayFromMono.Name = "rawByteArrayFromMono";
this.rawByteArrayFromMono.Size = new System.Drawing.Size(290, 17);
this.rawByteArrayFromMono.TabIndex = 15;
this.rawByteArrayFromMono.Text = "Raw: Extract raw byte array from MonoBehaviour assets";
this.rawByteArrayFromMono.UseVisualStyleBackColor = true;
//
// overwriteExistingFiles
//
this.overwriteExistingFiles.AutoSize = true;
this.overwriteExistingFiles.Location = new System.Drawing.Point(6, 63);
this.overwriteExistingFiles.Name = "overwriteExistingFiles";
this.overwriteExistingFiles.Size = new System.Drawing.Size(130, 17);
this.overwriteExistingFiles.TabIndex = 5;
this.overwriteExistingFiles.Text = "Overwrite existing files";
this.overwriteExistingFiles.UseVisualStyleBackColor = true;
//
// parallelExportMaxLabel
//
this.parallelExportMaxLabel.AutoSize = true;
@@ -149,7 +171,7 @@
this.parallelExportMaxLabel.Location = new System.Drawing.Point(260, 244);
this.parallelExportMaxLabel.Name = "parallelExportMaxLabel";
this.parallelExportMaxLabel.Size = new System.Drawing.Size(33, 13);
this.parallelExportMaxLabel.TabIndex = 13;
this.parallelExportMaxLabel.TabIndex = 14;
this.parallelExportMaxLabel.Text = "Max: ";
this.optionTooltip.SetToolTip(this.parallelExportMaxLabel, "*The maximum number matches the number of CPU cores");
//
@@ -161,7 +183,7 @@
this.parallelExportCheckBox.Location = new System.Drawing.Point(6, 242);
this.parallelExportCheckBox.Name = "parallelExportCheckBox";
this.parallelExportCheckBox.Size = new System.Drawing.Size(203, 17);
this.parallelExportCheckBox.TabIndex = 11;
this.parallelExportCheckBox.TabIndex = 12;
this.parallelExportCheckBox.Text = "Export in parallel with number of tasks";
this.optionTooltip.SetToolTip(this.parallelExportCheckBox, "*Requires slightly more RAM than in single-task mode");
this.parallelExportCheckBox.UseVisualStyleBackColor = true;
@@ -182,7 +204,7 @@
0});
this.parallelExportUpDown.Name = "parallelExportUpDown";
this.parallelExportUpDown.Size = new System.Drawing.Size(42, 20);
this.parallelExportUpDown.TabIndex = 12;
this.parallelExportUpDown.TabIndex = 13;
this.parallelExportUpDown.Value = new decimal(new int[] {
1,
0,
@@ -219,7 +241,7 @@
this.exportSpriteWithAlphaMask.Location = new System.Drawing.Point(6, 173);
this.exportSpriteWithAlphaMask.Name = "exportSpriteWithAlphaMask";
this.exportSpriteWithAlphaMask.Size = new System.Drawing.Size(205, 17);
this.exportSpriteWithAlphaMask.TabIndex = 8;
this.exportSpriteWithAlphaMask.TabIndex = 9;
this.exportSpriteWithAlphaMask.Text = "Export sprites with alpha mask applied";
this.exportSpriteWithAlphaMask.UseVisualStyleBackColor = true;
//
@@ -231,7 +253,7 @@
this.openAfterExport.Location = new System.Drawing.Point(6, 219);
this.openAfterExport.Name = "openAfterExport";
this.openAfterExport.Size = new System.Drawing.Size(137, 17);
this.openAfterExport.TabIndex = 10;
this.openAfterExport.TabIndex = 11;
this.openAfterExport.Text = "Open folder after export";
this.openAfterExport.UseVisualStyleBackColor = true;
//
@@ -243,7 +265,7 @@
this.restoreExtensionName.Location = new System.Drawing.Point(6, 86);
this.restoreExtensionName.Name = "restoreExtensionName";
this.restoreExtensionName.Size = new System.Drawing.Size(275, 17);
this.restoreExtensionName.TabIndex = 5;
this.restoreExtensionName.TabIndex = 6;
this.restoreExtensionName.Text = "Try to restore/Use original TextAsset extension name";
this.optionTooltip.SetToolTip(this.restoreExtensionName, "If not checked, AssetStudio will export all TextAssets with the \".txt\" extension");
this.restoreExtensionName.UseVisualStyleBackColor = true;
@@ -281,7 +303,7 @@
this.convertAudio.Location = new System.Drawing.Point(6, 196);
this.convertAudio.Name = "convertAudio";
this.convertAudio.Size = new System.Drawing.Size(213, 17);
this.convertAudio.TabIndex = 9;
this.convertAudio.TabIndex = 10;
this.convertAudio.Text = "Convert FMOD AudioClip to WAV(PCM)";
this.convertAudio.UseVisualStyleBackColor = true;
//
@@ -295,7 +317,7 @@
this.panel1.Location = new System.Drawing.Point(18, 134);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(279, 33);
this.panel1.TabIndex = 7;
this.panel1.TabIndex = 8;
//
// towebp
//
@@ -357,7 +379,7 @@
this.converttexture.Location = new System.Drawing.Point(6, 110);
this.converttexture.Name = "converttexture";
this.converttexture.Size = new System.Drawing.Size(116, 17);
this.converttexture.TabIndex = 6;
this.converttexture.TabIndex = 7;
this.converttexture.Text = "Convert Texture2D";
this.converttexture.UseVisualStyleBackColor = true;
//
@@ -370,7 +392,7 @@
this.l2dGroupBox.Controls.Add(this.l2dMotionExportMethodPanel);
this.l2dGroupBox.Controls.Add(this.l2dMotionExportMethodLabel);
this.l2dGroupBox.Controls.Add(this.l2dForceBezierCheckBox);
this.l2dGroupBox.Location = new System.Drawing.Point(12, 291);
this.l2dGroupBox.Location = new System.Drawing.Point(12, 304);
this.l2dGroupBox.Name = "l2dGroupBox";
this.l2dGroupBox.Size = new System.Drawing.Size(316, 149);
this.l2dGroupBox.TabIndex = 2;
@@ -459,9 +481,9 @@
this.l2dForceBezierCheckBox.AutoSize = true;
this.l2dForceBezierCheckBox.Location = new System.Drawing.Point(6, 122);
this.l2dForceBezierCheckBox.Name = "l2dForceBezierCheckBox";
this.l2dForceBezierCheckBox.Size = new System.Drawing.Size(278, 17);
this.l2dForceBezierCheckBox.Size = new System.Drawing.Size(304, 17);
this.l2dForceBezierCheckBox.TabIndex = 6;
this.l2dForceBezierCheckBox.Text = "Calculate Linear motion segments as Bezier segments";
this.l2dForceBezierCheckBox.Text = "Smooth motions (calc Linear segments as Bezier segments)";
this.optionTooltip.SetToolTip(this.l2dForceBezierCheckBox, "May help if the exported motions look jerky/not smooth enough");
this.l2dForceBezierCheckBox.UseVisualStyleBackColor = true;
//
@@ -492,7 +514,7 @@
this.groupBox2.Controls.Add(this.eulerFilter);
this.groupBox2.Location = new System.Drawing.Point(328, 13);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(289, 427);
this.groupBox2.Size = new System.Drawing.Size(289, 440);
this.groupBox2.TabIndex = 3;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Fbx";
@@ -500,7 +522,7 @@
// fbxResetButton
//
this.fbxResetButton.BackColor = System.Drawing.SystemColors.ButtonFace;
this.fbxResetButton.Location = new System.Drawing.Point(208, 384);
this.fbxResetButton.Location = new System.Drawing.Point(208, 398);
this.fbxResetButton.Name = "fbxResetButton";
this.fbxResetButton.Size = new System.Drawing.Size(75, 23);
this.fbxResetButton.TabIndex = 21;
@@ -765,16 +787,6 @@
this.eulerFilter.Text = "EulerFilter";
this.eulerFilter.UseVisualStyleBackColor = true;
//
// overwriteExistingFiles
//
this.overwriteExistingFiles.AutoSize = true;
this.overwriteExistingFiles.Location = new System.Drawing.Point(6, 63);
this.overwriteExistingFiles.Name = "overwriteExistingFiles";
this.overwriteExistingFiles.Size = new System.Drawing.Size(130, 17);
this.overwriteExistingFiles.TabIndex = 14;
this.overwriteExistingFiles.Text = "Overwrite existing files";
this.overwriteExistingFiles.UseVisualStyleBackColor = true;
//
// ExportOptions
//
this.AcceptButton = this.OKbutton;
@@ -782,7 +794,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Menu;
this.CancelButton = this.Cancel;
this.ClientSize = new System.Drawing.Size(628, 483);
this.ClientSize = new System.Drawing.Size(628, 494);
this.Controls.Add(this.l2dGroupBox);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
@@ -869,5 +881,6 @@
private System.Windows.Forms.Label uvBindingsLabel;
private System.Windows.Forms.Button fbxResetButton;
private System.Windows.Forms.CheckBox overwriteExistingFiles;
private System.Windows.Forms.CheckBox rawByteArrayFromMono;
}
}

View File

@@ -29,7 +29,8 @@ namespace AssetStudioGUI
parallelExportUpDown.Value = taskCount <= 0 ? maxParallelTasks : Math.Min(taskCount, maxParallelTasks);
parallelExportMaxLabel.Text += maxParallelTasks;
parallelExportCheckBox.Checked = Properties.Settings.Default.parallelExport;
rawByteArrayFromMono.Checked = Properties.Settings.Default.rawByteArrayFromMono;
l2dModelGroupComboBox.SelectedIndex = (int)Properties.Settings.Default.l2dModelGroupOption;
l2dAssetSearchByFilenameCheckBox.Checked = Properties.Settings.Default.l2dAssetSearchByFilename;
var defaultMotionMode = Properties.Settings.Default.l2dMotionMode.ToString();
@@ -53,6 +54,7 @@ namespace AssetStudioGUI
Properties.Settings.Default.openAfterExport = openAfterExport.Checked;
Properties.Settings.Default.parallelExport = parallelExportCheckBox.Checked;
Properties.Settings.Default.parallelExportCount = (int)parallelExportUpDown.Value;
Properties.Settings.Default.rawByteArrayFromMono = rawByteArrayFromMono.Checked;
Properties.Settings.Default.l2dModelGroupOption = (CubismLive2DExtractor.Live2DModelGroupOption)l2dModelGroupComboBox.SelectedIndex;
Properties.Settings.Default.l2dAssetSearchByFilename = l2dAssetSearchByFilenameCheckBox.Checked;

View File

@@ -276,6 +276,30 @@ namespace AssetStudioGUI
m_VideoClip.m_VideoData.WriteData(exportFullPath.Replace(".dat", "_data.dat"));
}
break;
case MonoBehaviour m_MonoBehaviour when Properties.Settings.Default.rawByteArrayFromMono:
var reader = m_MonoBehaviour.reader;
reader.Reset();
var assetData = reader.ReadBytes(28); //PPtr<GameObject> m_GameObject, m_Enabled, PPtr<MonoScript>
var assetNameLen = reader.ReadInt32();
reader.Position -= 4;
var assetNameBytes = reader.ReadBytes(assetNameLen + 4);
if (assetNameLen > 0)
reader.AlignStream();
var arrayLen = reader.ReadInt32();
if (arrayLen <= 0 || arrayLen > reader.Remaining)
break;
using (var outStream = new FileStream(exportFullPath.Replace(".dat", "_extracted.dat"), FileMode.Create))
{
reader.BaseStream.CopyTo(outStream, size: arrayLen);
}
using (var outStream = new FileStream(exportFullPath, FileMode.Create))
{
outStream.Write(assetData, 0, assetData.Length);
outStream.Write(assetNameBytes, 0, assetNameBytes.Length);
if (reader.Remaining > 0)
reader.BaseStream.CopyTo(outStream, size: reader.Remaining);
}
return true;
}
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
return true;

View File

@@ -358,5 +358,17 @@ namespace AssetStudioGUI.Properties {
this["meshLazyLoad"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool rawByteArrayFromMono {
get {
return ((bool)(this["rawByteArrayFromMono"]));
}
set {
this["rawByteArrayFromMono"] = value;
}
}
}
}

View File

@@ -86,5 +86,8 @@
<Setting Name="meshLazyLoad" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="rawByteArrayFromMono" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@@ -86,7 +86,8 @@ namespace CubismLive2DExtractor
var renderList = Model.RenderTextureList;
foreach (var renderMono in renderList)
{
if (!TryGetRenderTexture(renderMono, out var tex))
isRenderReadable = TryGetRenderTexture(renderMono, out var tex);
if (!isRenderReadable)
break;
renderTextureSet.Add(tex);
}

View File

@@ -135,7 +135,7 @@ namespace AssetStudio
var matrix = Matrix3x2.CreateScale(m_Sprite.m_PixelsToUnits);
matrix *= Matrix3x2.CreateTranslation(m_Sprite.m_Rect.width * m_Sprite.m_Pivot.X - textureRectOffset.X, m_Sprite.m_Rect.height * m_Sprite.m_Pivot.Y - textureRectOffset.Y);
var triangles = GetTriangles(m_Sprite.m_RD);
var points = triangles.Select(x => x.Select(y => new PointF(y.X, y.Y)).ToArray());
var points = triangles.Select(x => x.Select(y => new PointF(y.X, y.Y)));
var pathBuilder = new PathBuilder(matrix);
foreach (var p in points)
{
@@ -156,7 +156,7 @@ namespace AssetStudio
var rectP = new RectangularPolygon(0, 0, rect.Width, rect.Height);
try
{
spriteImage.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, rectP.Clip(path)));
spriteImage.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, rectP.Clip(path.Clip())));
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
return spriteImage;
}

View File

@@ -1,6 +1,6 @@
# AssetStudioMod
[![Release](https://img.shields.io/github/v/release/aelurum/AssetStudio)](https://github.com/aelurum/AssetStudio/releases/latest) [![Downloads](https://img.shields.io/github/downloads/aelurum/AssetStudio/total?color=blue)](https://github.com/aelurum/AssetStudio/releases/latest) [![Download latest release](https://img.shields.io/badge/Download_latest_release-blue)](https://github.com/aelurum/AssetStudio/releases/latest)
[![Release](https://img.shields.io/github/v/release/aelurum/AssetStudio?color=blue)](https://github.com/aelurum/AssetStudio/releases/latest) [![Downloads](https://img.shields.io/github/downloads/aelurum/AssetStudio/total?color=blue)](https://github.com/aelurum/AssetStudio/releases/latest) [![Download latest release](https://img.shields.io/badge/Download_latest_release-blue)](https://github.com/aelurum/AssetStudio/releases/latest)
[![Build status](https://ci.appveyor.com/api/projects/status/5qyai0hqs0ktyara/branch/AssetStudioMod?svg=true)](https://ci.appveyor.com/project/aelurum/assetstudiomod/branch/AssetStudioMod) [![Download latest build](https://img.shields.io/badge/Download_latest_build-brightgreen)](https://ci.appveyor.com/project/aelurum/assetstudiomod/branch/AssetStudioMod/artifacts)
@@ -40,7 +40,7 @@
- Support of swizzled Switch textures
- Ported from nesrak1's [AssetStudio fork](https://github.com/nesrak1/AssetStudio/tree/switch-tex-deswizzle)
- Detecting bundles with UnityCN encryption
- Detection only. If you want to open them, please use Razmoth's [Studio](https://github.com/RazTools/Studio)
- Detection only. If you want to open them, please use Razmoth's [Studio](https://github.com/RazTools/Studio) or Escartem's [AnimeStudio](https://github.com/Escartem/AnimeStudio)
- Some UI optimizations and bug fixes (See [CHANGELOG](https://github.com/aelurum/AssetStudio/blob/AssetStudioMod/CHANGELOG.md) for details)
## Requirements