Merge branch 'AssetStudioMod' into ArknightsStudio

This commit is contained in:
VaDiM 2023-09-15 21:31:38 +03:00
commit 5c489c5f83
27 changed files with 854 additions and 332 deletions

View File

@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows</TargetFrameworks> <TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.17.2.0</Version> <Version>1.0.0</Version>
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright> <Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
</PropertyGroup> </PropertyGroup>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows</TargetFrameworks> <TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows</TargetFrameworks>
<Version>0.17.2.0</Version> <Version>1.0.0</Version>
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2023</Copyright> <Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2023</Copyright>
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
</PropertyGroup> </PropertyGroup>

View File

@ -91,7 +91,14 @@ namespace AssetStudio
} }
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{ {
var m_IgnoreMasterTextureLimit = reader.ReadBoolean(); if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
{
var m_IgnoreMipmapLimit = reader.ReadBoolean();
}
else
{
var m_IgnoreMasterTextureLimit = reader.ReadBoolean();
}
} }
if (version[0] >= 3) //3.0.0 - 5.4 if (version[0] >= 3) //3.0.0 - 5.4
{ {
@ -100,6 +107,11 @@ namespace AssetStudio
var m_ReadAllowed = reader.ReadBoolean(); var m_ReadAllowed = reader.ReadBoolean();
} }
} }
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
{
var m_MipmapLimitGroupName = reader.ReadAlignedString();
reader.AlignStream();
}
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{ {
var m_StreamingMipmaps = reader.ReadBoolean(); var m_StreamingMipmaps = reader.ReadBoolean();

View File

@ -3,9 +3,9 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFrameworks>net472;net6.0;net7.0</TargetFrameworks> <TargetFrameworks>net472;net6.0;net7.0</TargetFrameworks>
<AssemblyTitle>AssetStudioMod by aelurum</AssemblyTitle> <AssemblyTitle>ArknightsStudio by aelurum</AssemblyTitle>
<AssemblyName>AssetStudioModCLI</AssemblyName> <AssemblyName>ArknightsStudioCLI</AssemblyName>
<Version>0.17.2.0</Version> <Version>1.0.0</Version>
<Copyright>Copyright © Perfare; Copyright © aelurum 2023</Copyright> <Copyright>Copyright © Perfare; Copyright © aelurum 2023</Copyright>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
@ -24,6 +24,8 @@
<Target Name="CopyExtraFilesPortable" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == '' "> <Target Name="CopyExtraFilesPortable" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == '' ">
<Message Text="Copying windows extra files for $(TargetFramework)... " Importance="high" /> <Message Text="Copying windows extra files for $(TargetFramework)... " Importance="high" />
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\Win32\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\x64\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\Win32\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" /> <Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\Win32\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\x64\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" /> <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-x86\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" />
@ -32,6 +34,9 @@
<Target Name="CopyExtraFilesPortableNet" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == '' AND '$(TargetFramework)' != 'net472' "> <Target Name="CopyExtraFilesPortableNet" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == '' AND '$(TargetFramework)' != 'net472' ">
<Message Text="Copying other platforms extra files for $(TargetFramework)... " Importance="high" /> <Message Text="Copying other platforms extra files for $(TargetFramework)... " Importance="high" />
<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-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-x64\libfmod.so" DestinationFolder="$(TargetDir)runtimes\linux-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(ProjectDir)Libraries\osx-x64\libfmod.dylib" DestinationFolder="$(TargetDir)runtimes\osx-x64\native" ContinueOnError="false" /> <Copy SourceFiles="$(ProjectDir)Libraries\osx-x64\libfmod.dylib" DestinationFolder="$(TargetDir)runtimes\osx-x64\native" ContinueOnError="false" />
@ -42,6 +47,8 @@
The dll is cross-platform while the executable isn't --> The dll is cross-platform while the executable isn't -->
<Target Name="PublishExtraFilesPortable" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == '' "> <Target Name="PublishExtraFilesPortable" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == '' ">
<Message Text="Publishing windows extra files for Portable build ($(TargetFramework))... " Importance="high" /> <Message Text="Publishing windows extra files for Portable build ($(TargetFramework))... " Importance="high" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x86\native\AssetStudioFBXNative.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\AssetStudioFBXNative.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x86\native\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" /> <Copy SourceFiles="$(TargetDir)runtimes\win-x86\native\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" /> <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-x86\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" />
@ -50,6 +57,9 @@
<Target Name="PublishExtraFilesPortableNet" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == '' AND '$(TargetFramework)' != 'net472' "> <Target Name="PublishExtraFilesPortableNet" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == '' AND '$(TargetFramework)' != 'net472' ">
<Message Text="Publishing other platforms extra files for Portable build ($(TargetFramework))... " Importance="high" /> <Message Text="Publishing other platforms extra files for Portable build ($(TargetFramework))... " Importance="high" />
<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-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-x64\native\libfmod.so" DestinationFolder="$(PublishDir)runtimes\linux-x64\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-x64\native\libfmod.dylib" DestinationFolder="$(PublishDir)runtimes\osx-x64\native" ContinueOnError="false" />
@ -58,39 +68,46 @@
<Target Name="CopyExtraFilesWin86" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-x86' "> <Target Name="CopyExtraFilesWin86" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-x86' ">
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" /> <Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
<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="$(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\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target> </Target>
<Target Name="CopyExtraFilesWin64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-x64' "> <Target Name="CopyExtraFilesWin64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-x64' ">
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" /> <Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
<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="$(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\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target> </Target>
<Target Name="PublishExtraFilesWin" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('win-x')) "> <Target Name="PublishExtraFilesWin" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('win-x')) ">
<Message Text="Publishing extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" /> <Message Text="Publishing extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
<Copy SourceFiles="$(TargetDir)\AssetStudioFBXNative.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
<Copy SourceFiles="$(TargetDir)\Texture2DDecoderNative.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)\fmod.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
</Target> </Target>
<Target Name="CopyExtraFilesLinux64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'linux-x64' "> <Target Name="CopyExtraFilesLinux64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'linux-x64' ">
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" /> <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\libfmod.so" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target> </Target>
<Target Name="PublishExtraFilesLinux64" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == 'linux-x64' "> <Target Name="PublishExtraFilesLinux64" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == 'linux-x64' ">
<Message Text="Publishing extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" /> <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)\libfmod.so" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
</Target> </Target>
<Target Name="CopyExtraFilesMac" AfterTargets="AfterBuild" Condition=" $(RuntimeIdentifier.Contains('osx-')) "> <Target Name="CopyExtraFilesMac" AfterTargets="AfterBuild" Condition=" $(RuntimeIdentifier.Contains('osx-')) ">
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" /> <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)\libfmod.dylib" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
</Target> </Target>
<Target Name="PublishExtraFilesMac" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('osx-')) "> <Target Name="PublishExtraFilesMac" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('osx-')) ">
<Message Text="Publishing extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" /> <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)\libfmod.dylib" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
</Target> </Target>

View File

@ -148,11 +148,11 @@ namespace Arknights
bool resized = false; bool resized = false;
if (tex.Width != texMask.Width || tex.Height != texMask.Height) if (tex.Width != texMask.Width || tex.Height != texMask.Height)
{ {
texMask.Mutate(x => x.Resize(tex.Width, tex.Height, CLIOptions.o_akAlphaMaskResampler.Value)); texMask.Mutate(x => x.Resize(tex.Width, tex.Height, CLIOptions.o_akAlphaTexResampler.Value));
resized = true; resized = true;
} }
var invGamma = 1.0 / (1.0 + CLIOptions.o_akAlphaMaskGamma.Value / 10.0); var invGamma = 1.0 / (1.0 + CLIOptions.o_akShadowGamma.Value / 10.0);
if (CLIOptions.akResizedOnly && !resized) if (CLIOptions.akResizedOnly && !resized)
{ {
invGamma = 1.0; invGamma = 1.0;

View File

@ -14,6 +14,7 @@ namespace AssetStudioCLI
public ClassIDType Type; public ClassIDType Type;
public string Text; public string Text;
public string UniqueID; public string UniqueID;
public GameObjectNode Node;
public PortraitSprite AkPortraitSprite; public PortraitSprite AkPortraitSprite;
public AssetItem(Object asset) public AssetItem(Object asset)

View File

@ -0,0 +1,16 @@
using AssetStudio;
using System.Collections.Generic;
namespace AssetStudioCLI
{
internal class BaseNode
{
public List<BaseNode> nodes = new List<BaseNode>();
public BaseNode()
{
}
}
}

View File

@ -0,0 +1,16 @@
using AssetStudio;
using System.Collections.Generic;
namespace AssetStudioCLI
{
internal class GameObjectNode : BaseNode
{
public GameObject gameObject;
public GameObjectNode(GameObject gameObject)
{
this.gameObject = gameObject;
}
}
}

View File

@ -4,6 +4,7 @@ using AssetStudioCLI.Options;
using Newtonsoft.Json; using Newtonsoft.Json;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -243,7 +244,7 @@ namespace AssetStudioCLI
var alias = ""; var alias = "";
var m_Sprite = (Sprite)item.Asset; var m_Sprite = (Sprite)item.Asset;
var type = CLIOptions.o_imageFormat.Value; var type = CLIOptions.o_imageFormat.Value;
var spriteMaskMode = CLIOptions.o_akSpriteMaskMode.Value != AkSpriteMaskMode.None ? SpriteMaskMode.Export : SpriteMaskMode.Off; var spriteMaskMode = CLIOptions.o_akSpriteAlphaMode.Value != AkSpriteAlphaMode.None ? SpriteMaskMode.Export : SpriteMaskMode.Off;
var isCharAvgSprite = item.Container.Contains("avg/characters"); var isCharAvgSprite = item.Container.Contains("avg/characters");
var isCharArt = item.Container.Contains("arts/characters"); var isCharArt = item.Container.Contains("arts/characters");
@ -271,7 +272,7 @@ namespace AssetStudioCLI
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath, alias)) if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath, alias))
return false; return false;
if (CLIOptions.o_akSpriteMaskMode.Value == AkSpriteMaskMode.External && (isCharAvgSprite || isCharArt)) if (CLIOptions.o_akSpriteAlphaMode.Value == AkSpriteAlphaMode.SearchExternal && (isCharAvgSprite || isCharArt))
{ {
if (m_Sprite.m_RD.alphaTexture.IsNull) if (m_Sprite.m_RD.alphaTexture.IsNull)
{ {
@ -307,7 +308,7 @@ namespace AssetStudioCLI
public static bool ExportPortraitSprite(AssetItem item, string exportPath) public static bool ExportPortraitSprite(AssetItem item, string exportPath)
{ {
var type = CLIOptions.o_imageFormat.Value; var type = CLIOptions.o_imageFormat.Value;
var spriteMaskMode = CLIOptions.o_akSpriteMaskMode.Value != AkSpriteMaskMode.None ? SpriteMaskMode.Export : SpriteMaskMode.Off; var spriteMaskMode = CLIOptions.o_akSpriteAlphaMode.Value != AkSpriteAlphaMode.None ? SpriteMaskMode.Export : SpriteMaskMode.Off;
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath)) if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
return false; return false;
@ -342,6 +343,33 @@ namespace AssetStudioCLI
return true; return true;
} }
public static void ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
{
var convert = animationList != null
? new ModelConverter(gameObject, CLIOptions.o_imageFormat.Value, animationList.Select(x => (AnimationClip)x.Asset).ToArray())
: new ModelConverter(gameObject, CLIOptions.o_imageFormat.Value);
exportPath = exportPath + FixFileName(gameObject.m_Name) + ".fbx";
ExportFbx(convert, exportPath);
}
private static void ExportFbx(IImported convert, string exportPath)
{
var eulerFilter = true;
var filterPrecision = (float)0.25f;
var exportAllNodes = true;
var exportSkins = true;
var exportAnimations = true;
var exportBlendShape = true;
var castToBone = false;
var boneSize = CLIOptions.o_fbxBoneSize.Value;
var exportAllUvsAsDiffuseMaps = false;
var scaleFactor = CLIOptions.o_fbxScaleFactor.Value;
var fbxVersion = 3;
var fbxFormat = 0;
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision,
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, fbxVersion, fbxFormat == 1);
}
public static bool ExportDumpFile(AssetItem item, string exportPath) public static bool ExportDumpFile(AssetItem item, string exportPath)
{ {
if (item.Asset == null) if (item.Asset == null)

View File

@ -14,6 +14,8 @@ namespace AssetStudioCLI.Options
General, General,
Convert, Convert,
Logger, Logger,
FBX,
Filter,
Arknights, Arknights,
Advanced, Advanced,
} }
@ -25,6 +27,7 @@ namespace AssetStudioCLI.Options
Dump, Dump,
Info, Info,
ExportLive2D, ExportLive2D,
SplitObjects,
} }
internal enum AssetGroupOption internal enum AssetGroupOption
@ -58,11 +61,11 @@ namespace AssetStudioCLI.Options
NameAndContainer, NameAndContainer,
} }
internal enum AkSpriteMaskMode internal enum AkSpriteAlphaMode
{ {
None, None,
Internal, InternalOnly,
External SearchExternal
} }
internal static class CLIOptions internal static class CLIOptions
@ -75,7 +78,8 @@ namespace AssetStudioCLI.Options
private static Dictionary<string, string> optionsDict; private static Dictionary<string, string> optionsDict;
private static Dictionary<string, string> flagsDict; private static Dictionary<string, string> flagsDict;
private static Dictionary<HelpGroups, Dictionary<string, string>> optionGroups; private static Dictionary<HelpGroups, Dictionary<string, string>> optionGroups;
private static List<ClassIDType> supportedAssetTypes; private static List<ClassIDType> exportableAssetTypes;
private static Dictionary<string, ClassIDType> knownAssetTypesDict;
//general //general
public static Option<WorkMode> o_workMode; public static Option<WorkMode> o_workMode;
public static Option<List<ClassIDType>> o_exportAssetTypes; public static Option<List<ClassIDType>> o_exportAssetTypes;
@ -89,23 +93,28 @@ namespace AssetStudioCLI.Options
public static bool convertTexture; public static bool convertTexture;
public static Option<ImageFormat> o_imageFormat; public static Option<ImageFormat> o_imageFormat;
public static Option<AudioFormat> o_audioFormat; public static Option<AudioFormat> o_audioFormat;
//arknights //fbx
public static bool akResizedOnly; public static Option<float> o_fbxScaleFactor;
public static Option<AkSpriteMaskMode> o_akSpriteMaskMode; public static Option<int> o_fbxBoneSize;
public static Option<IResampler> o_akAlphaMaskResampler; //filter
private static string resamplerName;
public static Option<int> o_akAlphaMaskGamma;
public static Option<bool> f_akOriginalAvgNames;
public static Option<bool> f_akAddAliases;
//advanced
public static Option<ExportListType> o_exportAssetList;
public static Option<List<string>> o_filterByName; public static Option<List<string>> o_filterByName;
public static Option<List<string>> o_filterByContainer; public static Option<List<string>> o_filterByContainer;
public static Option<List<string>> o_filterByPathID; public static Option<List<string>> o_filterByPathID;
public static Option<List<string>> o_filterByText; public static Option<List<string>> o_filterByText;
//arknights
public static bool akResizedOnly;
public static Option<AkSpriteAlphaMode> o_akSpriteAlphaMode;
public static Option<IResampler> o_akAlphaTexResampler;
private static string resamplerName;
public static Option<int> o_akShadowGamma;
public static Option<bool> f_akOriginalAvgNames;
public static Option<bool> f_akAddAliases;
//advanced
public static Option<ExportListType> o_exportAssetList;
public static Option<string> o_assemblyPath; public static Option<string> o_assemblyPath;
public static Option<string> o_unityVersion; public static Option<string> o_unityVersion;
public static Option<bool> f_notRestoreExtensionName; public static Option<bool> f_notRestoreExtensionName;
public static Option<bool> f_loadAllAssets;
static CLIOptions() static CLIOptions()
{ {
@ -150,7 +159,7 @@ namespace AssetStudioCLI.Options
optionsDict = new Dictionary<string, string>(); optionsDict = new Dictionary<string, string>();
flagsDict = new Dictionary<string, string>(); flagsDict = new Dictionary<string, string>();
optionGroups = new Dictionary<HelpGroups, Dictionary<string, string>>(); optionGroups = new Dictionary<HelpGroups, Dictionary<string, string>>();
supportedAssetTypes = new List<ClassIDType> exportableAssetTypes = new List<ClassIDType>
{ {
ClassIDType.Texture2D, ClassIDType.Texture2D,
ClassIDType.Sprite, ClassIDType.Sprite,
@ -164,6 +173,7 @@ namespace AssetStudioCLI.Options
ClassIDType.MovieTexture, ClassIDType.MovieTexture,
ClassIDType.Mesh, ClassIDType.Mesh,
}; };
knownAssetTypesDict = ((ClassIDType[])Enum.GetValues(typeof(ClassIDType))).ToHashSet().ToDictionary(x => x.ToString().ToLower(), y => y);
#region Init General Options #region Init General Options
o_workMode = new GroupedOption<WorkMode> o_workMode = new GroupedOption<WorkMode>
@ -171,18 +181,19 @@ namespace AssetStudioCLI.Options
optionDefaultValue: WorkMode.Export, optionDefaultValue: WorkMode.Export,
optionName: "-m, --mode <value>", optionName: "-m, --mode <value>",
optionDescription: "Specify working mode\n" + optionDescription: "Specify working mode\n" +
"<Value: export(default) | exportRaw | dump | info | live2d>\n" + "<Value: export(default) | exportRaw | dump | info | live2d | splitObjects>\n" +
"Export - Exports converted assets\n" + "Export - Exports converted assets\n" +
"ExportRaw - Exports raw data\n" + "ExportRaw - Exports raw data\n" +
"Dump - Makes asset dumps\n" + "Dump - Makes asset dumps\n" +
"Info - Loads file(s), shows the number of available for export assets and exits\n" + "Info - Loads file(s), shows the number of available for export assets and exits\n" +
"Live2D - Exports Live2D Cubism 3 models\n" + "Live2D - Exports Live2D Cubism 3 models\n" +
"SplitObjects - Exports split objects (fbx)\n" +
"Example: \"-m info\"\n", "Example: \"-m info\"\n",
optionHelpGroup: HelpGroups.General optionHelpGroup: HelpGroups.General
); );
o_exportAssetTypes = new GroupedOption<List<ClassIDType>> o_exportAssetTypes = new GroupedOption<List<ClassIDType>>
( (
optionDefaultValue: supportedAssetTypes, optionDefaultValue: exportableAssetTypes,
optionName: "-t, --asset-type <value(s)>", optionName: "-t, --asset-type <value(s)>",
optionDescription: "Specify asset type(s) to export\n" + optionDescription: "Specify asset type(s) to export\n" +
"<Value(s): tex2d, sprite, akPortrait, textAsset, monoBehaviour, font, shader,\n" + "<Value(s): tex2d, sprite, akPortrait, textAsset, monoBehaviour, font, shader,\n" +
@ -208,7 +219,7 @@ namespace AssetStudioCLI.Options
); );
o_outputFolder = new GroupedOption<string> o_outputFolder = new GroupedOption<string>
( (
optionDefaultValue: "", optionDefaultValue: "ASExport",
optionName: "-o, --output <path>", optionName: "-o, --output <path>",
optionDescription: "Specify path to the output folder\n" + optionDescription: "Specify path to the output folder\n" +
"If path isn't specifyed, 'ASExport' folder will be created in the program's work folder\n", "If path isn't specifyed, 'ASExport' folder will be created in the program's work folder\n",
@ -268,52 +279,113 @@ namespace AssetStudioCLI.Options
); );
#endregion #endregion
#region Init FBX Options
o_fbxScaleFactor = new GroupedOption<float>
(
optionDefaultValue: 1f,
optionName: "--fbx-scale-factor <value>",
optionDescription: "Specify the FBX Scale Factor\n" +
"<Value: float number from 0 to 100 (default=1)\n" +
"Example: \"--fbx-scale-factor 50\"\n",
optionHelpGroup: HelpGroups.FBX
);
o_fbxBoneSize = new GroupedOption<int>
(
optionDefaultValue: 10,
optionName: "--fbx-bone-size <value>",
optionDescription: "Specify the FBX Bone Size\n" +
"<Value: integer number from 0 to 100 (default=10)\n" +
"Example: \"--fbx-bone-size 10\"",
optionHelpGroup: HelpGroups.FBX
);
#endregion
#region Init Filter Options
o_filterByName = new GroupedOption<List<string>>
(
optionDefaultValue: new List<string>(),
optionName: "--filter-by-name <text>",
optionDescription: "Specify the name by which assets should be filtered\n" +
"*To specify multiple names write them separated by ',' or ';' without spaces\n" +
"Example: \"--filter-by-name char\" or \"--filter-by-name char,bg\"\n",
optionHelpGroup: HelpGroups.Filter
);
o_filterByContainer = new GroupedOption<List<string>>
(
optionDefaultValue: new List<string>(),
optionName: "--filter-by-container <text>",
optionDescription: "Specify the container by which assets should be filtered\n" +
"*To specify multiple containers write them separated by ',' or ';' without spaces\n" +
"Example: \"--filter-by-container arts\" or \"--filter-by-container arts,icons\"\n",
optionHelpGroup: HelpGroups.Filter
);
o_filterByPathID = new GroupedOption<List<string>>
(
optionDefaultValue: new List<string>(),
optionName: "--filter-by-pathid <text>",
optionDescription: "Specify the PathID by which assets should be filtered\n" +
"*To specify multiple PathIDs write them separated by ',' or ';' without spaces\n" +
"Example: \"--filter-by-pathid 7238605633795851352,-2430306240205277265\"\n",
optionHelpGroup: HelpGroups.Filter
);
o_filterByText = new GroupedOption<List<string>>
(
optionDefaultValue: new List<string>(),
optionName: "--filter-by-text <text>",
optionDescription: "Specify the text by which assets should be filtered\n" +
"Looks for assets that contain the specified text in their names or containers\n" +
"*To specify multiple values write them separated by ',' or ';' without spaces\n" +
"Example: \"--filter-by-text portrait\" or \"--filter-by-text portrait,art\"\n",
optionHelpGroup: HelpGroups.Filter
);
#endregion
#region Arknights Options #region Arknights Options
akResizedOnly = true; akResizedOnly = true;
o_akSpriteMaskMode = new GroupedOption<AkSpriteMaskMode> o_akSpriteAlphaMode = new GroupedOption<AkSpriteAlphaMode>
( (
optionDefaultValue: AkSpriteMaskMode.External, optionDefaultValue: AkSpriteAlphaMode.SearchExternal,
optionName: "--spritemask-mode <value>", optionName: "--spritealpha-mode <value>",
optionDescription: "Specify the mode in which you want to export sprites with alpha mask\n" + optionDescription: "Specify the mode in which you want to export sprites with alpha texture\n" +
"<Value: none | internalOnly | searchExternal(default)>\n" + "<Value: none | internalOnly | searchExternal(default)>\n" +
"None - Export sprites without alpha mask applied\n" + "None - Export sprites without alpha texture applied\n" +
"Internal - Export sprites with internal alpha mask applied (if exist)\n" + "InternalOnly - Export sprites with internal alpha texture applied (if exist)\n" +
"SearchExternal - Export sprites with internal alpha mask applied,\n" + "SearchExternal - Export sprites with internal alpha texture applied,\n" +
"and in case it doesn't exist, Studio will try to find an external alpha mask\n" + "and in case it doesn't exist, Studio will try to find an external alpha texture\n" +
"Example: \"--spritemask-mode internalOnly\"\n", "Example: \"--spritealpha-mode internalOnly\"\n",
optionHelpGroup: HelpGroups.Arknights optionHelpGroup: HelpGroups.Arknights
); );
o_akAlphaMaskResampler = new GroupedOption<IResampler> o_akAlphaTexResampler = new GroupedOption<IResampler>
( (
optionDefaultValue: KnownResamplers.MitchellNetravali, optionDefaultValue: KnownResamplers.MitchellNetravali,
optionName: "--alphamask-resampler <value>", optionName: "--alphatex-resampler <value>",
optionDescription: "Specify the alpha mask upscale algorithm for 2048x2048 sprites\n" + optionDescription: "Specify the alpha texture upscale algorithm for 2048x2048 sprites\n" +
"<Value: nearest | bilinear | bicubic | mitchell(default) | spline | welch>\n" + "<Value: nearest | bilinear | bicubic | mitchell(default) | spline | welch>\n" +
"Mitchell - Mitchell Netravali algorithm. Yields good equilibrium between \n" + "Mitchell - Mitchell Netravali algorithm. Yields good equilibrium between \n" +
"sharpness and smoothness (produces less artifacts than bicubic in case of alpha masks)\n" + "sharpness and smoothness (produces less artifacts than bicubic in the current use case)\n" +
"Spline - Similar to Mitchell Netravali but yielding smoother results\n" + "Spline - Similar to Mitchell Netravali but yielding smoother results\n" +
"Welch - A high speed algorithm that delivers very sharpened results\n" + "Welch - A high speed algorithm that delivers very sharpened results\n" +
"Example: \"--alphamask-resampler bicubic\"\n", "Example: \"--alphatex-resampler bicubic\"\n",
optionHelpGroup: HelpGroups.Arknights optionHelpGroup: HelpGroups.Arknights
); );
resamplerName = "Mitchell"; resamplerName = "Mitchell";
o_akAlphaMaskGamma = new GroupedOption<int> o_akShadowGamma = new GroupedOption<int>
( (
optionDefaultValue: 2, optionDefaultValue: 2,
optionName: "--alphamask-gamma <value>", optionName: "--shadow-gamma <value>",
optionDescription: "Specify the alpha mask gamma correction for 2048x2048 sprites\n" + optionDescription: "Specify the gamma correction of semi-transparent shadow for 2048x2048 sprites\n" +
"<Value: integer number from -5 to 5 (default=2)>\n" + "<Value: integer number from -5 to 5 (default=2)>\n" +
"<0 - Make the alpha mask darker\n" + "<0 - Make the shadow darker\n" +
"0 - Do not change the gamma of alpha mask\n" + "0 - Do not change the brightness of the shadow\n" +
">0 - Make the alpha mask lighter\n" + ">0 - Make the shadow lighter\n" +
"Example: \"--alphamask-gamma 0\"\n", "Example: \"--shadow-gamma 0\"\n",
optionHelpGroup: HelpGroups.Arknights optionHelpGroup: HelpGroups.Arknights
); );
f_akOriginalAvgNames = new GroupedOption<bool> f_akOriginalAvgNames = new GroupedOption<bool>
( (
optionDefaultValue: false, optionDefaultValue: false,
optionName: "--original-avg-names", optionName: "--original-avg-names",
optionDescription: "(Flag) If specified, names of avg sprites with faces will not be fixed\n", optionDescription: "(Flag) If specified, names of avg character sprites will not be fixed\n",
optionHelpGroup: HelpGroups.Arknights, optionHelpGroup: HelpGroups.Arknights,
isFlag: true isFlag: true
); );
@ -321,7 +393,7 @@ namespace AssetStudioCLI.Options
( (
optionDefaultValue: false, optionDefaultValue: false,
optionName: "--add-aliases", optionName: "--add-aliases",
optionDescription: "(Flag) If specified, aliases will be added to avg sprite names (if exist)", optionDescription: "(Flag) If specified, aliases will be added to avg character sprite names (if exist)",
optionHelpGroup: HelpGroups.Arknights, optionHelpGroup: HelpGroups.Arknights,
isFlag: true isFlag: true
); );
@ -338,62 +410,33 @@ namespace AssetStudioCLI.Options
"Example: \"--export-asset-list xml\"\n", "Example: \"--export-asset-list xml\"\n",
optionHelpGroup: HelpGroups.Advanced optionHelpGroup: HelpGroups.Advanced
); );
o_filterByName = new GroupedOption<List<string>>
(
optionDefaultValue: new List<string>(),
optionName: "--filter-by-name <text>",
optionDescription: "Specify the name by which assets should be filtered\n" +
"*To specify multiple names write them separated by ',' or ';' without spaces\n" +
"Example: \"--filter-by-name char\" or \"--filter-by-name char,bg\"\n",
optionHelpGroup: HelpGroups.Advanced
);
o_filterByContainer = new GroupedOption<List<string>>
(
optionDefaultValue: new List<string>(),
optionName: "--filter-by-container <text>",
optionDescription: "Specify the container by which assets should be filtered\n" +
"*To specify multiple containers write them separated by ',' or ';' without spaces\n" +
"Example: \"--filter-by-container arts\" or \"--filter-by-container arts,icons\"\n",
optionHelpGroup: HelpGroups.Advanced
);
o_filterByPathID = new GroupedOption<List<string>>
(
optionDefaultValue: new List<string>(),
optionName: "--filter-by-pathid <text>",
optionDescription: "Specify the PathID by which assets should be filtered\n" +
"*To specify multiple PathIDs write them separated by ',' or ';' without spaces\n" +
"Example: \"--filter-by-pathid 7238605633795851352,-2430306240205277265\"\n",
optionHelpGroup: HelpGroups.Advanced
);
o_filterByText = new GroupedOption<List<string>>
(
optionDefaultValue: new List<string>(),
optionName: "--filter-by-text <text>",
optionDescription: "Specify the text by which assets should be filtered\n" +
"Looks for assets that contain the specified text in their names or containers\n" +
"*To specify multiple values write them separated by ',' or ';' without spaces\n" +
"Example: \"--filter-by-text portrait\" or \"--filter-by-text portrait,art\"\n",
optionHelpGroup: HelpGroups.Advanced
);
o_assemblyPath = new GroupedOption<string> o_assemblyPath = new GroupedOption<string>
( (
optionDefaultValue: "", optionDefaultValue: "",
optionName: "--assembly-folder <path>", optionName: "--assembly-folder <path>",
optionDescription: "Specify the path to the assembly folder", optionDescription: "Specify the path to the assembly folder\n",
optionHelpGroup: HelpGroups.Advanced optionHelpGroup: HelpGroups.Advanced
); );
o_unityVersion = new GroupedOption<string> o_unityVersion = new GroupedOption<string>
( (
optionDefaultValue: "", optionDefaultValue: "",
optionName: "--unity-version <text>", optionName: "--unity-version <text>",
optionDescription: "Specify Unity version. Example: \"--unity-version 2017.4.39f1\"", optionDescription: "Specify Unity version\nExample: \"--unity-version 2017.4.39f1\"\n",
optionHelpGroup: HelpGroups.Advanced optionHelpGroup: HelpGroups.Advanced
); );
f_notRestoreExtensionName = new GroupedOption<bool> f_notRestoreExtensionName = new GroupedOption<bool>
( (
optionDefaultValue: false, optionDefaultValue: false,
optionName: "--not-restore-extension", optionName: "--not-restore-extension",
optionDescription: "(Flag) If specified, Studio will not try to use/restore original TextAsset\nextension name, and will just export all TextAssets with the \".txt\" extension", optionDescription: "(Flag) If specified, Studio will not try to use/restore original TextAsset\nextension name, and will just export all TextAssets with the \".txt\" extension\n",
optionHelpGroup: HelpGroups.Advanced,
isFlag: true
);
f_loadAllAssets = new GroupedOption<bool>
(
optionDefaultValue: false,
optionName: "--load-all",
optionDescription: "(Flag) If specified, Studio will load assets of all types\n(Only for Dump, Info and ExportRaw modes)",
optionHelpGroup: HelpGroups.Advanced, optionHelpGroup: HelpGroups.Advanced,
isFlag: true isFlag: true
); );
@ -407,7 +450,7 @@ namespace AssetStudioCLI.Options
var brightYellow = CLIAnsiColors.BrightYellow; var brightYellow = CLIAnsiColors.BrightYellow;
var brightRed = CLIAnsiColors.BrightRed; var brightRed = CLIAnsiColors.BrightRed;
if (args.Length == 0 || args.Any(x => x == "-h" || x == "--help")) if (args.Length == 0 || args.Any(x => x.ToLower() == "-h" || x.ToLower() == "--help" || x.ToLower() == "-?"))
{ {
showHelp = true; showHelp = true;
return; return;
@ -422,7 +465,6 @@ namespace AssetStudioCLI.Options
$"Specified file or folder was not found. The input path must be specified as the first argument."); $"Specified file or folder was not found. The input path must be specified as the first argument.");
return; return;
} }
o_outputFolder.Value = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ASExport");
} }
else else
{ {
@ -447,6 +489,64 @@ namespace AssetStudioCLI.Options
} }
}; };
var workModeOptionIndex = resplittedArgs.FindIndex(x => x.ToLower() == "-m" || x.ToLower() == "--mode");
if (workModeOptionIndex >= 0)
{
var option = resplittedArgs[workModeOptionIndex];
if (workModeOptionIndex + 1 >= resplittedArgs.Count)
{
Console.WriteLine($"{"Error during parsing options:".Color(brightRed)} Value for [{option.Color(brightRed)}] option was not found.\n");
TryFindOptionDescription(option, optionsDict);
return;
}
var value = resplittedArgs[workModeOptionIndex + 1];
switch (value.ToLower())
{
case "export":
o_workMode.Value = WorkMode.Export;
break;
case "raw":
case "exportraw":
o_workMode.Value = WorkMode.ExportRaw;
break;
case "dump":
o_workMode.Value = WorkMode.Dump;
break;
case "info":
o_workMode.Value = WorkMode.Info;
break;
case "live2d":
o_workMode.Value = WorkMode.ExportLive2D;
o_exportAssetTypes.Value = new List<ClassIDType>()
{
ClassIDType.AnimationClip,
ClassIDType.GameObject,
ClassIDType.MonoBehaviour,
ClassIDType.Texture2D,
ClassIDType.Transform,
};
break;
case "splitobjects":
o_workMode.Value = WorkMode.SplitObjects;
o_exportAssetTypes.Value = new List<ClassIDType>()
{
ClassIDType.GameObject,
ClassIDType.Texture2D,
ClassIDType.Material,
ClassIDType.Transform,
ClassIDType.Mesh,
ClassIDType.MeshRenderer,
ClassIDType.MeshFilter,
};
break;
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported working mode: [{value.Color(brightRed)}].\n");
ShowOptionDescription(o_workMode.Description);
return;
}
resplittedArgs.RemoveRange(workModeOptionIndex, 2);
}
#region Parse Flags #region Parse Flags
for (int i = 0; i < resplittedArgs.Count; i++) for (int i = 0; i < resplittedArgs.Count; i++)
{ {
@ -458,6 +558,21 @@ namespace AssetStudioCLI.Options
f_notRestoreExtensionName.Value = true; f_notRestoreExtensionName.Value = true;
resplittedArgs.RemoveAt(i); resplittedArgs.RemoveAt(i);
break; break;
case "--load-all":
switch (o_workMode.Value)
{
case WorkMode.ExportRaw:
case WorkMode.Dump:
case WorkMode.Info:
f_loadAllAssets.Value = true;
resplittedArgs.RemoveAt(i);
break;
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{flag}] flag. This flag is not suitable for the current working mode [{o_workMode.Value}].\n");
ShowOptionDescription(f_loadAllAssets.Description, isFlag: true);
return;
}
break;
case "--original-avg-names": case "--original-avg-names":
f_akOriginalAvgNames.Value = true; f_akOriginalAvgNames.Value = true;
resplittedArgs.RemoveAt(i); resplittedArgs.RemoveAt(i);
@ -479,43 +594,9 @@ namespace AssetStudioCLI.Options
var value = resplittedArgs[i + 1].Replace("\"", ""); var value = resplittedArgs[i + 1].Replace("\"", "");
switch (option) switch (option)
{ {
case "-m":
case "--mode":
switch (value.ToLower())
{
case "export":
o_workMode.Value = WorkMode.Export;
break;
case "raw":
case "exportraw":
o_workMode.Value = WorkMode.ExportRaw;
break;
case "dump":
o_workMode.Value = WorkMode.Dump;
break;
case "info":
o_workMode.Value = WorkMode.Info;
break;
case "live2d":
o_workMode.Value = WorkMode.ExportLive2D;
o_exportAssetTypes.Value = new List<ClassIDType>()
{
ClassIDType.AnimationClip,
ClassIDType.GameObject,
ClassIDType.MonoBehaviour,
ClassIDType.Texture2D,
ClassIDType.Transform,
};
break;
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported working mode: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_workMode.Description);
return;
}
break;
case "-t": case "-t":
case "--asset-type": case "--asset-type":
if (o_workMode.Value == WorkMode.ExportLive2D) if (o_workMode.Value == WorkMode.ExportLive2D || o_workMode.Value == WorkMode.SplitObjects)
{ {
i++; i++;
continue; continue;
@ -527,47 +608,38 @@ namespace AssetStudioCLI.Options
switch (type.ToLower()) switch (type.ToLower())
{ {
case "tex2d": case "tex2d":
case "texture2d":
o_exportAssetTypes.Value.Add(ClassIDType.Texture2D); o_exportAssetTypes.Value.Add(ClassIDType.Texture2D);
break; break;
case "sprite":
o_exportAssetTypes.Value.Add(ClassIDType.Sprite);
break;
case "akportrait": case "akportrait":
o_exportAssetTypes.Value.Add(ClassIDType.AkPortraitSprite); o_exportAssetTypes.Value.Add(ClassIDType.AkPortraitSprite);
break; break;
case "textasset":
o_exportAssetTypes.Value.Add(ClassIDType.TextAsset);
break;
case "monobehaviour":
o_exportAssetTypes.Value.Add(ClassIDType.MonoBehaviour);
break;
case "font":
o_exportAssetTypes.Value.Add(ClassIDType.Font);
break;
case "shader":
o_exportAssetTypes.Value.Add(ClassIDType.Shader);
break;
case "audio": case "audio":
case "audioclip":
o_exportAssetTypes.Value.Add(ClassIDType.AudioClip); o_exportAssetTypes.Value.Add(ClassIDType.AudioClip);
break; break;
case "video": case "video":
case "videoclip":
o_exportAssetTypes.Value.Add(ClassIDType.VideoClip); o_exportAssetTypes.Value.Add(ClassIDType.VideoClip);
break; break;
case "movietexture":
o_exportAssetTypes.Value.Add(ClassIDType.MovieTexture);
break;
case "mesh":
o_exportAssetTypes.Value.Add(ClassIDType.Mesh);
break;
case "all": case "all":
o_exportAssetTypes.Value = supportedAssetTypes; o_exportAssetTypes.Value = exportableAssetTypes;
break; break;
default: default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported asset type: [{value.Color(brightRed)}].\n"); var isKnownType = knownAssetTypesDict.TryGetValue(type.ToLower(), out var assetType);
Console.WriteLine(o_exportAssetTypes.Description); if (isKnownType)
{
if (f_loadAllAssets.Value || exportableAssetTypes.Contains(assetType))
{
o_exportAssetTypes.Value.Add(assetType);
break;
}
}
else
{
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unknown asset type specified [{type.Color(brightRed)}].\n");
ShowOptionDescription(o_exportAssetTypes.Description);
return;
}
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Asset type [{type.Color(brightRed)}] is not supported for exporting.\n");
ShowOptionDescription(o_exportAssetTypes.Description);
return; return;
} }
} }
@ -593,7 +665,7 @@ namespace AssetStudioCLI.Options
break; break;
default: default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported grouping option: [{value.Color(brightRed)}].\n"); Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported grouping option: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_groupAssetsBy.Description); ShowOptionDescription(o_groupAssetsBy.Description);
return; return;
} }
break; break;
@ -606,6 +678,10 @@ namespace AssetStudioCLI.Options
{ {
Directory.CreateDirectory(value); Directory.CreateDirectory(value);
} }
if (!value.EndsWith($"{Path.DirectorySeparatorChar}"))
{
value += Path.DirectorySeparatorChar;
}
o_outputFolder.Value = value; o_outputFolder.Value = value;
} }
catch (Exception ex) catch (Exception ex)
@ -640,7 +716,7 @@ namespace AssetStudioCLI.Options
break; break;
default: default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported log level value: [{value.Color(brightRed)}].\n"); Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported log level value: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_logLevel.Description); ShowOptionDescription(o_logLevel.Description);
return; return;
} }
break; break;
@ -658,7 +734,7 @@ namespace AssetStudioCLI.Options
break; break;
default: default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported log output mode: [{value.Color(brightRed)}].\n"); Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported log output mode: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_logOutput.Description); ShowOptionDescription(o_logOutput.Description);
return; return;
} }
break; break;
@ -686,7 +762,7 @@ namespace AssetStudioCLI.Options
break; break;
default: default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported image format: [{value.Color(brightRed)}].\n"); Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported image format: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_imageFormat.Description); ShowOptionDescription(o_imageFormat.Description);
return; return;
} }
break; break;
@ -702,84 +778,40 @@ namespace AssetStudioCLI.Options
break; break;
default: default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported audio format: [{value.Color(brightRed)}].\n"); Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported audio format: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_audioFormat.Description); ShowOptionDescription(o_audioFormat.Description);
return; return;
} }
break; break;
case "--spritemask-mode": case "--fbx-scale-factor":
switch (value.ToLower())
{ {
case "none": var isFloat = float.TryParse(value, out float floatValue);
o_akSpriteMaskMode.Value = AkSpriteMaskMode.None; if (isFloat && floatValue >= 0 && floatValue <= 100)
break; {
case "internal": o_fbxScaleFactor.Value = floatValue;
o_akSpriteMaskMode.Value = AkSpriteMaskMode.Internal; }
break; else
case "searchexternal": {
o_akSpriteMaskMode.Value = AkSpriteMaskMode.External; Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported scale factor value: [{value.Color(brightRed)}].\n");
break; ShowOptionDescription(o_fbxScaleFactor.Description);
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported sprite mask mode: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_akSpriteMaskMode.Description);
return; return;
}
break;
} }
break; case "--fbx-bone-size":
case "--alphamask-resampler":
switch (value.ToLower())
{ {
case "nearest": var isInt = int.TryParse(value, out int intValue);
o_akAlphaMaskResampler.Value = KnownResamplers.NearestNeighbor; if (isInt && intValue >= 0 && intValue <= 100)
break; {
case "bilinear": o_fbxBoneSize.Value = intValue;
o_akAlphaMaskResampler.Value = KnownResamplers.Triangle; }
break; else
case "bicubic": {
o_akAlphaMaskResampler.Value = KnownResamplers.Bicubic; Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported bone size value: [{value.Color(brightRed)}].\n");
break; ShowOptionDescription(o_fbxBoneSize.Description);
case "mitchell":
o_akAlphaMaskResampler.Value = KnownResamplers.MitchellNetravali;
break;
case "spline":
o_akAlphaMaskResampler.Value = KnownResamplers.Spline;
break;
case "welch":
o_akAlphaMaskResampler.Value = KnownResamplers.Welch;
break;
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported alpha mask resampler: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_akAlphaMaskResampler.Description);
return; return;
}
break;
} }
resamplerName = value.ToLower();
break;
case "--alphamask-gamma":
var isInt = int.TryParse(value, out int intValue);
if (isInt && intValue >= -5 && intValue <= 5)
{
o_akAlphaMaskGamma.Value = intValue;
}
else
{
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported gamma correction value: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_akAlphaMaskGamma.Description);
return;
}
break;
case "--export-asset-list":
switch (value.ToLower())
{
case "xml":
o_exportAssetList.Value = ExportListType.XML;
break;
case "none":
o_exportAssetList.Value = ExportListType.None;
break;
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported asset list export option: [{value.Color(brightRed)}].\n");
Console.WriteLine(o_exportAssetList.Description);
return;
}
break;
case "--filter-by-name": case "--filter-by-name":
o_filterByName.Value.AddRange(ValueSplitter(value)); o_filterByName.Value.AddRange(ValueSplitter(value));
filterBy = filterBy == FilterBy.None ? FilterBy.Name : filterBy == FilterBy.Container ? FilterBy.NameAndContainer : filterBy; filterBy = filterBy == FilterBy.None ? FilterBy.Name : filterBy == FilterBy.Container ? FilterBy.NameAndContainer : filterBy;
@ -796,6 +828,82 @@ namespace AssetStudioCLI.Options
o_filterByText.Value.AddRange(ValueSplitter(value)); o_filterByText.Value.AddRange(ValueSplitter(value));
filterBy = FilterBy.NameOrContainer; filterBy = FilterBy.NameOrContainer;
break; break;
case "--spritealpha-mode":
switch (value.ToLower())
{
case "none":
o_akSpriteAlphaMode.Value = AkSpriteAlphaMode.None;
break;
case "internalonly":
o_akSpriteAlphaMode.Value = AkSpriteAlphaMode.InternalOnly;
break;
case "searchexternal":
o_akSpriteAlphaMode.Value = AkSpriteAlphaMode.SearchExternal;
break;
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported sprite alpha mode: [{value.Color(brightRed)}].\n");
ShowOptionDescription(o_akSpriteAlphaMode.Description);
return;
}
break;
case "--alphatex-resampler":
switch (value.ToLower())
{
case "nearest":
o_akAlphaTexResampler.Value = KnownResamplers.NearestNeighbor;
break;
case "bilinear":
o_akAlphaTexResampler.Value = KnownResamplers.Triangle;
break;
case "bicubic":
o_akAlphaTexResampler.Value = KnownResamplers.Bicubic;
break;
case "mitchell":
o_akAlphaTexResampler.Value = KnownResamplers.MitchellNetravali;
break;
case "spline":
o_akAlphaTexResampler.Value = KnownResamplers.Spline;
break;
case "welch":
o_akAlphaTexResampler.Value = KnownResamplers.Welch;
break;
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported alpha texture resampler: [{value.Color(brightRed)}].\n");
ShowOptionDescription(o_akAlphaTexResampler.Description);
return;
}
resamplerName = value.ToLower();
break;
case "--shadow-gamma":
{
var isInt = int.TryParse(value, out int intValue);
if (isInt && intValue >= -5 && intValue <= 5)
{
o_akShadowGamma.Value = intValue;
}
else
{
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported gamma correction value: [{value.Color(brightRed)}].\n");
ShowOptionDescription(o_akShadowGamma.Description);
return;
}
break;
}
case "--export-asset-list":
switch (value.ToLower())
{
case "xml":
o_exportAssetList.Value = ExportListType.XML;
break;
case "none":
o_exportAssetList.Value = ExportListType.None;
break;
default:
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported asset list export option: [{value.Color(brightRed)}].\n");
ShowOptionDescription(o_exportAssetList.Description);
return;
}
break;
case "--assembly-folder": case "--assembly-folder":
if (Directory.Exists(value)) if (Directory.Exists(value))
{ {
@ -813,9 +921,9 @@ namespace AssetStudioCLI.Options
break; break;
default: default:
Console.WriteLine($"{"Error:".Color(brightRed)} Unknown option [{option.Color(brightRed)}].\n"); Console.WriteLine($"{"Error:".Color(brightRed)} Unknown option [{option.Color(brightRed)}].\n");
if (!TryShowOptionDescription(option, optionsDict)) if (!TryFindOptionDescription(option, optionsDict))
{ {
TryShowOptionDescription(option, flagsDict); TryFindOptionDescription(option, flagsDict, isFlag: true);
} }
return; return;
} }
@ -826,12 +934,12 @@ namespace AssetStudioCLI.Options
if (optionsDict.Any(x => x.Key.Contains(option))) if (optionsDict.Any(x => x.Key.Contains(option)))
{ {
Console.WriteLine($"{"Error during parsing options:".Color(brightRed)} Value for [{option.Color(brightRed)}] option was not found.\n"); Console.WriteLine($"{"Error during parsing options:".Color(brightRed)} Value for [{option.Color(brightRed)}] option was not found.\n");
TryShowOptionDescription(option, optionsDict); TryFindOptionDescription(option, optionsDict);
} }
else if (flagsDict.Any(x => x.Key.Contains(option))) else if (flagsDict.Any(x => x.Key.Contains(option)))
{ {
Console.WriteLine($"{"Error:".Color(brightRed)} Unknown flag [{option.Color(brightRed)}].\n"); Console.WriteLine($"{"Error:".Color(brightRed)} Unknown flag [{option.Color(brightRed)}].\n");
TryShowOptionDescription(option, flagsDict); TryFindOptionDescription(option, flagsDict, isFlag: true);
} }
else else
{ {
@ -852,6 +960,15 @@ namespace AssetStudioCLI.Options
{ {
Studio.assemblyLoader.Loaded = true; Studio.assemblyLoader.Loaded = true;
} }
if (o_outputFolder.Value == o_outputFolder.DefaultValue)
{
var fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, o_outputFolder.DefaultValue + Path.DirectorySeparatorChar);
if (!Directory.Exists(fullPath))
{
Directory.CreateDirectory(fullPath);
}
o_outputFolder.Value = fullPath;
}
isParsed = true; isParsed = true;
} }
@ -861,14 +978,21 @@ namespace AssetStudioCLI.Options
return value.Split(separator); return value.Split(separator);
} }
private static bool TryShowOptionDescription(string option, Dictionary<string, string> descDict) private static void ShowOptionDescription(string desc, bool isFlag = false)
{ {
var optionDesc = descDict.Where(x => x.Key.Contains(option)); var arg = isFlag ? "Flag" : "Option";
Console.WriteLine($"{arg} description:\n{desc}");
}
private static bool TryFindOptionDescription(string option, Dictionary<string, string> dict, bool isFlag = false)
{
var optionDesc = dict.Where(x => x.Key.Contains(option));
if (optionDesc.Any()) if (optionDesc.Any())
{ {
var arg = isFlag ? "flag" : "option";
var rand = new Random(); var rand = new Random();
var rndOption = optionDesc.ElementAt(rand.Next(0, optionDesc.Count())); var rndOption = optionDesc.ElementAt(rand.Next(0, optionDesc.Count()));
Console.WriteLine($"Did you mean [{ $"{rndOption.Key}".Color(CLIAnsiColors.BrightYellow) }] option?"); Console.WriteLine($"Did you mean [{ $"{rndOption.Key}".Color(CLIAnsiColors.BrightYellow) }] {arg}?");
Console.WriteLine($"Here's a description of it: \n\n{rndOption.Value}"); Console.WriteLine($"Here's a description of it: \n\n{rndOption.Value}");
return true; return true;
@ -910,7 +1034,7 @@ namespace AssetStudioCLI.Options
else else
{ {
var arch = Environment.Is64BitProcess ? "x64" : "x32"; var arch = Environment.Is64BitProcess ? "x64" : "x32";
Console.WriteLine($"# {appAssembly.Name} [{arch}]\n# Based on AssetStudioMod v{appAssembly.Version}\n"); Console.WriteLine($"# {appAssembly.Name} [{arch}]\n# v{appAssembly.Version}\n# Based on AssetStudioMod v0.17.3\n");
Console.WriteLine($"{usage}\n\n{helpMessage}"); Console.WriteLine($"{usage}\n\n{helpMessage}");
} }
} }
@ -934,6 +1058,21 @@ namespace AssetStudioCLI.Options
} }
} }
private static string ShowExportTypes()
{
switch (o_workMode.Value)
{
case WorkMode.ExportRaw:
case WorkMode.Dump:
case WorkMode.Info:
return f_loadAllAssets.Value && o_exportAssetTypes.Value == o_exportAssetTypes.DefaultValue
? $"# Export Asset Type(s): All"
: $"# Export Asset Type(s): {string.Join(", ", o_exportAssetTypes.Value)}";
default:
return $"# Export Asset Type(s): {string.Join(", ", o_exportAssetTypes.Value)}";
}
}
public static void ShowCurrentOptions() public static void ShowCurrentOptions()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -942,31 +1081,24 @@ namespace AssetStudioCLI.Options
sb.AppendLine($"# Input Path: \"{inputPath}\""); sb.AppendLine($"# Input Path: \"{inputPath}\"");
switch (o_workMode.Value) switch (o_workMode.Value)
{ {
case WorkMode.Info: case WorkMode.Export:
sb.AppendLine($"# Export Asset Type(s): {string.Join(", ", o_exportAssetTypes.Value)}"); case WorkMode.ExportRaw:
sb.AppendLine($"# Log Level: {o_logLevel}"); case WorkMode.Dump:
sb.AppendLine($"# Log Output: {o_logOutput}");
sb.AppendLine($"# Export Asset List: {o_exportAssetList}");
sb.AppendLine(ShowCurrentFilter());
sb.AppendLine($"# Unity Version: \"{o_unityVersion}\"");
break;
case WorkMode.ExportLive2D:
sb.AppendLine($"# Output Path: \"{o_outputFolder}\""); sb.AppendLine($"# Output Path: \"{o_outputFolder}\"");
sb.AppendLine($"# Log Level: {o_logLevel}"); if (o_workMode.Value != WorkMode.Export)
sb.AppendLine($"# Log Output: {o_logOutput}"); {
sb.AppendLine($"# Export Asset List: {o_exportAssetList}"); sb.AppendLine($"# Load All Assets: {f_loadAllAssets}");
sb.AppendLine($"# Assebmly Path: \"{o_assemblyPath}\""); }
sb.AppendLine($"# Unity Version: \"{o_unityVersion}\""); sb.AppendLine(ShowExportTypes());
break;
default:
sb.AppendLine($"# Output Path: \"{o_outputFolder}\"");
sb.AppendLine($"# Export Asset Type(s): {string.Join(", ", o_exportAssetTypes.Value)}");
sb.AppendLine($"# Asset Group Option: {o_groupAssetsBy}"); sb.AppendLine($"# Asset Group Option: {o_groupAssetsBy}");
sb.AppendLine($"# Export Image Format: {o_imageFormat}"); if (o_workMode.Value == WorkMode.Export)
sb.AppendLine($"# Export Audio Format: {o_audioFormat}"); {
sb.AppendLine($"# [Arkingths] Sprite Mask Mode: {o_akSpriteMaskMode}"); sb.AppendLine($"# Export Image Format: {o_imageFormat}");
sb.AppendLine($"# [Arknights] Mask Resampler: {resamplerName}"); sb.AppendLine($"# Export Audio Format: {o_audioFormat}");
sb.AppendLine($"# [Arknights] Mask Gamma Correction: {o_akAlphaMaskGamma.Value * 10:+#;-#;0}%"); sb.AppendLine($"# [Arkingths] Sprite Alpha Mode: {o_akSpriteAlphaMode}");
sb.AppendLine($"# [Arknights] Alpha Texture Resampler: {resamplerName}");
sb.AppendLine($"# [Arknights] Shadow Gamma Correction: {o_akShadowGamma.Value * 10:+#;-#;0}%");
}
sb.AppendLine($"# [Arknights] Don't Fix Avg Names: {f_akOriginalAvgNames}"); sb.AppendLine($"# [Arknights] Don't Fix Avg Names: {f_akOriginalAvgNames}");
sb.AppendLine($"# [Arknights] Add Aliases: {f_akAddAliases}"); sb.AppendLine($"# [Arknights] Add Aliases: {f_akAddAliases}");
sb.AppendLine($"# Log Level: {o_logLevel}"); sb.AppendLine($"# Log Level: {o_logLevel}");
@ -975,7 +1107,36 @@ namespace AssetStudioCLI.Options
sb.AppendLine(ShowCurrentFilter()); sb.AppendLine(ShowCurrentFilter());
sb.AppendLine($"# Assebmly Path: \"{o_assemblyPath}\""); sb.AppendLine($"# Assebmly Path: \"{o_assemblyPath}\"");
sb.AppendLine($"# Unity Version: \"{o_unityVersion}\""); sb.AppendLine($"# Unity Version: \"{o_unityVersion}\"");
sb.AppendLine($"# Restore TextAsset Extension: {!f_notRestoreExtensionName.Value}"); if (o_workMode.Value == WorkMode.Export)
{
sb.AppendLine($"# Restore TextAsset Extension: {!f_notRestoreExtensionName.Value}");
}
break;
case WorkMode.Info:
sb.AppendLine($"# Load All Assets: {f_loadAllAssets}");
sb.AppendLine(ShowExportTypes());
sb.AppendLine($"# Log Level: {o_logLevel}");
sb.AppendLine($"# Log Output: {o_logOutput}");
sb.AppendLine($"# Export Asset List: {o_exportAssetList}");
sb.AppendLine(ShowCurrentFilter());
sb.AppendLine($"# Unity Version: \"{o_unityVersion}\"");
break;
case WorkMode.ExportLive2D:
case WorkMode.SplitObjects:
sb.AppendLine($"# Output Path: \"{o_outputFolder}\"");
sb.AppendLine($"# Log Level: {o_logLevel}");
sb.AppendLine($"# Log Output: {o_logOutput}");
sb.AppendLine($"# Export Asset List: {o_exportAssetList}");
if (o_workMode.Value == WorkMode.SplitObjects)
{
sb.AppendLine($"# Export Image Format: {o_imageFormat}");
sb.AppendLine($"# Filter by Name(s): \"{string.Join("\", \"", o_filterByName.Value)}\"");
}
else
{
sb.AppendLine($"# Assebmly Path: \"{o_assemblyPath}\"");
}
sb.AppendLine($"# Unity Version: \"{o_unityVersion}\"");
break; break;
} }
sb.AppendLine("======"); sb.AppendLine("======");

View File

@ -35,9 +35,9 @@ namespace AssetStudioCLI
if (Studio.LoadAssets()) if (Studio.LoadAssets())
{ {
Studio.ParseAssets(); Studio.ParseAssets();
if (CLIOptions.filterBy != FilterBy.None && CLIOptions.o_workMode.Value != WorkMode.ExportLive2D) if (CLIOptions.filterBy != FilterBy.None)
{ {
Studio.FilterAssets(); Studio.Filter();
} }
if (CLIOptions.o_exportAssetList.Value != ExportListType.None) if (CLIOptions.o_exportAssetList.Value != ExportListType.None)
{ {
@ -51,6 +51,9 @@ namespace AssetStudioCLI
case WorkMode.ExportLive2D: case WorkMode.ExportLive2D:
Studio.ExportLive2D(); Studio.ExportLive2D();
break; break;
case WorkMode.SplitObjects:
Studio.ExportSplitObjects();
break;
default: default:
Studio.ExportAssets(); Studio.ExportAssets();
break; break;

View File

@ -16,6 +16,7 @@ namespace AssetStudioCLI
public static AssetsManager assetsManager = new AssetsManager(); public static AssetsManager assetsManager = new AssetsManager();
public static List<AssetItem> exportableAssetsList = new List<AssetItem>(); public static List<AssetItem> exportableAssetsList = new List<AssetItem>();
public static List<AssetItem> loadedAssetsList = new List<AssetItem>(); public static List<AssetItem> loadedAssetsList = new List<AssetItem>();
public static List<BaseNode> gameObjectTree = new List<BaseNode>();
public static AssemblyLoader assemblyLoader = new AssemblyLoader(); public static AssemblyLoader assemblyLoader = new AssemblyLoader();
private static Dictionary<AssetStudio.Object, string> containers = new Dictionary<AssetStudio.Object, string>(); private static Dictionary<AssetStudio.Object, string> containers = new Dictionary<AssetStudio.Object, string>();
@ -33,8 +34,10 @@ namespace AssetStudioCLI
{ {
var isLoaded = false; var isLoaded = false;
assetsManager.SpecifyUnityVersion = CLIOptions.o_unityVersion.Value; assetsManager.SpecifyUnityVersion = CLIOptions.o_unityVersion.Value;
assetsManager.SetAssetFilter(CLIOptions.o_exportAssetTypes.Value); if (!CLIOptions.f_loadAllAssets.Value)
{
assetsManager.SetAssetFilter(CLIOptions.o_exportAssetTypes.Value);
}
assetsManager.LoadFilesAndFolders(CLIOptions.inputPath); assetsManager.LoadFilesAndFolders(CLIOptions.inputPath);
if (assetsManager.assetsFileList.Count == 0) if (assetsManager.assetsFileList.Count == 0)
{ {
@ -53,6 +56,7 @@ namespace AssetStudioCLI
Logger.Info("Parse assets..."); Logger.Info("Parse assets...");
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count); var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
var objectAssetItemDic = new Dictionary<AssetStudio.Object, AssetItem>(objectCount);
Progress.Reset(); Progress.Reset();
var i = 0; var i = 0;
@ -61,6 +65,7 @@ namespace AssetStudioCLI
foreach (var asset in assetsFile.Objects) foreach (var asset in assetsFile.Objects)
{ {
var assetItem = new AssetItem(asset); var assetItem = new AssetItem(asset);
objectAssetItemDic.Add(asset, assetItem);
assetItem.UniqueID = "_#" + i; assetItem.UniqueID = "_#" + i;
var isExportable = false; var isExportable = false;
switch (asset) switch (asset)
@ -80,6 +85,7 @@ namespace AssetStudioCLI
} }
} }
} }
assetItem.Text = m_AssetBundle.m_Name;
break; break;
case ResourceManager m_ResourceManager: case ResourceManager m_ResourceManager:
foreach (var m_Container in m_ResourceManager.m_Container) foreach (var m_Container in m_ResourceManager.m_Container)
@ -105,13 +111,6 @@ namespace AssetStudioCLI
assetItem.FullSize = asset.byteSize + m_VideoClip.m_ExternalResources.m_Size; assetItem.FullSize = asset.byteSize + m_VideoClip.m_ExternalResources.m_Size;
assetItem.Text = m_VideoClip.m_Name; assetItem.Text = m_VideoClip.m_Name;
break; break;
case Mesh _:
case MovieTexture _:
case TextAsset _:
case Font _:
case Sprite _:
assetItem.Text = ((NamedObject)asset).m_Name;
break;
case Shader m_Shader: case Shader m_Shader:
assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name; assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
break; break;
@ -125,15 +124,27 @@ namespace AssetStudioCLI
assetItem.Text = m_MonoBehaviour.m_Name; assetItem.Text = m_MonoBehaviour.m_Name;
} }
break; break;
case GameObject m_GameObject:
assetItem.Text = m_GameObject.m_Name;
break;
case Animator m_Animator:
if (m_Animator.m_GameObject.TryGet(out var gameObject))
{
assetItem.Text = gameObject.m_Name;
}
break;
case NamedObject m_NamedObject:
assetItem.Text = m_NamedObject.m_Name;
break;
} }
if (assetItem.Text == "") if (string.IsNullOrEmpty(assetItem.Text))
{ {
assetItem.Text = assetItem.TypeString + assetItem.UniqueID; assetItem.Text = assetItem.TypeString + assetItem.UniqueID;
} }
loadedAssetsList.Add(assetItem); loadedAssetsList.Add(assetItem);
isExportable = CLIOptions.o_exportAssetTypes.Value.Contains(asset.type); isExportable = CLIOptions.o_exportAssetTypes.Value.Contains(asset.type);
if (isExportable) if (isExportable || (CLIOptions.f_loadAllAssets.Value && CLIOptions.o_exportAssetTypes.Value == CLIOptions.o_exportAssetTypes.DefaultValue))
{ {
exportableAssetsList.Add(assetItem); exportableAssetsList.Add(assetItem);
} }
@ -161,6 +172,11 @@ namespace AssetStudioCLI
containers.Clear(); containers.Clear();
} }
} }
if (CLIOptions.o_workMode.Value == WorkMode.SplitObjects)
{
BuildTreeStructure(objectAssetItemDic);
}
var log = $"Finished loading {assetsManager.assetsFileList.Count} files with {exportableAssetsList.Count} exportable assets"; var log = $"Finished loading {assetsManager.assetsFileList.Count} files with {exportableAssetsList.Count} exportable assets";
var unityVer = assetsManager.assetsFileList[0].version; var unityVer = assetsManager.assetsFileList[0].version;
long m_ObjectsCount; long m_ObjectsCount;
@ -183,6 +199,85 @@ namespace AssetStudioCLI
Logger.Info(log); Logger.Info(log);
} }
public static void BuildTreeStructure(Dictionary<AssetStudio.Object, AssetItem> objectAssetItemDic)
{
Logger.Info("Building tree structure...");
var treeNodeDictionary = new Dictionary<GameObject, GameObjectNode>();
var assetsFileCount = assetsManager.assetsFileList.Count;
int j = 0;
Progress.Reset();
foreach (var assetsFile in assetsManager.assetsFileList)
{
var fileNode = new BaseNode(); //RootNode
foreach (var obj in assetsFile.Objects)
{
if (obj is GameObject m_GameObject)
{
if (!treeNodeDictionary.TryGetValue(m_GameObject, out var currentNode))
{
currentNode = new GameObjectNode(m_GameObject);
treeNodeDictionary.Add(m_GameObject, currentNode);
}
foreach (var pptr in m_GameObject.m_Components)
{
if (pptr.TryGet(out var m_Component))
{
objectAssetItemDic[m_Component].Node = currentNode;
if (m_Component is MeshFilter m_MeshFilter)
{
if (m_MeshFilter.m_Mesh.TryGet(out var m_Mesh))
{
objectAssetItemDic[m_Mesh].Node = currentNode;
}
}
else if (m_Component is SkinnedMeshRenderer m_SkinnedMeshRenderer)
{
if (m_SkinnedMeshRenderer.m_Mesh.TryGet(out var m_Mesh))
{
objectAssetItemDic[m_Mesh].Node = currentNode;
}
}
}
}
var parentNode = fileNode;
if (m_GameObject.m_Transform != null)
{
if (m_GameObject.m_Transform.m_Father.TryGet(out var m_Father))
{
if (m_Father.m_GameObject.TryGet(out var parentGameObject))
{
if (!treeNodeDictionary.TryGetValue(parentGameObject, out var parentGameObjectNode))
{
parentGameObjectNode = new GameObjectNode(parentGameObject);
treeNodeDictionary.Add(parentGameObject, parentGameObjectNode);
}
parentNode = parentGameObjectNode;
}
}
}
parentNode.nodes.Add(currentNode);
}
}
if (fileNode.nodes.Count > 0)
{
gameObjectTree.Add(fileNode);
}
Progress.Report(++j, assetsFileCount);
}
treeNodeDictionary.Clear();
objectAssetItemDic.Clear();
}
public static void ShowExportableAssetsInfo() public static void ShowExportableAssetsInfo()
{ {
var exportableAssetsCountDict = new Dictionary<ClassIDType, int>(); var exportableAssetsCountDict = new Dictionary<ClassIDType, int>();
@ -226,7 +321,20 @@ namespace AssetStudioCLI
} }
} }
public static void FilterAssets() public static void Filter()
{
switch (CLIOptions.o_workMode.Value)
{
case WorkMode.ExportLive2D:
case WorkMode.SplitObjects:
break;
default:
FilterAssets();
break;
}
}
private static void FilterAssets()
{ {
var assetsCount = exportableAssetsList.Count; var assetsCount = exportableAssetsList.Count;
var filteredAssets = new List<AssetItem>(); var filteredAssets = new List<AssetItem>();
@ -234,14 +342,14 @@ namespace AssetStudioCLI
switch(CLIOptions.filterBy) switch(CLIOptions.filterBy)
{ {
case FilterBy.Name: case FilterBy.Name:
filteredAssets = exportableAssetsList.FindAll(x => CLIOptions.o_filterByName.Value.Any(y => x.Text.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)); filteredAssets = exportableAssetsList.FindAll(x => CLIOptions.o_filterByName.Value.Any(y => x.Text.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0));
Logger.Info( Logger.Info(
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " + $"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByName.Value)}\"".Color(Ansi.BrightYellow)} in their Names." $"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByName.Value)}\"".Color(Ansi.BrightYellow)} in their Names."
); );
break; break;
case FilterBy.Container: case FilterBy.Container:
filteredAssets = exportableAssetsList.FindAll(x => CLIOptions.o_filterByContainer.Value.Any(y => x.Container.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)); filteredAssets = exportableAssetsList.FindAll(x => CLIOptions.o_filterByContainer.Value.Any(y => x.Container.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0));
Logger.Info( Logger.Info(
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " + $"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByContainer.Value)}\"".Color(Ansi.BrightYellow)} in their Containers." $"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByContainer.Value)}\"".Color(Ansi.BrightYellow)} in their Containers."
@ -256,8 +364,8 @@ namespace AssetStudioCLI
break; break;
case FilterBy.NameOrContainer: case FilterBy.NameOrContainer:
filteredAssets = exportableAssetsList.FindAll(x => filteredAssets = exportableAssetsList.FindAll(x =>
CLIOptions.o_filterByText.Value.Any(y => x.Text.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) || CLIOptions.o_filterByText.Value.Any(y => x.Text.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) ||
CLIOptions.o_filterByText.Value.Any(y => x.Container.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) CLIOptions.o_filterByText.Value.Any(y => x.Container.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)
); );
Logger.Info( Logger.Info(
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " + $"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
@ -266,8 +374,8 @@ namespace AssetStudioCLI
break; break;
case FilterBy.NameAndContainer: case FilterBy.NameAndContainer:
filteredAssets = exportableAssetsList.FindAll(x => filteredAssets = exportableAssetsList.FindAll(x =>
CLIOptions.o_filterByName.Value.Any(y => x.Text.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) && CLIOptions.o_filterByName.Value.Any(y => x.Text.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) &&
CLIOptions.o_filterByContainer.Value.Any(y => x.Container.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) CLIOptions.o_filterByContainer.Value.Any(y => x.Container.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)
); );
Logger.Info( Logger.Info(
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " + $"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
@ -411,6 +519,101 @@ namespace AssetStudioCLI
Logger.Info($"Finished exporting asset list with {exportableAssetsList.Count} items."); Logger.Info($"Finished exporting asset list with {exportableAssetsList.Count} items.");
} }
public static void ExportSplitObjects()
{
var savePath = CLIOptions.o_outputFolder.Value;
var searchList = CLIOptions.o_filterByName.Value;
var isFiltered = CLIOptions.filterBy == FilterBy.Name;
var exportableObjects = new List<GameObjectNode>();
var exportedCount = 0;
var k = 0;
Logger.Info($"Searching for objects to export..");
Progress.Reset();
var count = gameObjectTree.Sum(x => x.nodes.Count);
foreach (var node in gameObjectTree)
{
foreach (GameObjectNode j in node.nodes)
{
if (isFiltered)
{
if (!searchList.Any(searchText => j.gameObject.m_Name.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0))
continue;
}
var gameObjects = new List<GameObject>();
CollectNode(j, gameObjects);
if (gameObjects.All(x => x.m_SkinnedMeshRenderer == null && x.m_MeshFilter == null))
{
Progress.Report(++k, count);
continue;
}
exportableObjects.Add(j);
}
}
gameObjectTree.Clear();
var exportableCount = exportableObjects.Count;
var log = $"Found {exportableCount} exportable object(s) ";
if (isFiltered)
{
log += $"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByName.Value)}\"".Color(Ansi.BrightYellow)} in their Names";
}
Logger.Info(log);
if (exportableCount > 0)
{
Progress.Reset();
k = 0;
foreach (var gameObjectNode in exportableObjects)
{
var gameObject = gameObjectNode.gameObject;
var filename = FixFileName(gameObject.m_Name);
var targetPath = $"{savePath}{filename}{Path.DirectorySeparatorChar}";
//重名文件处理
for (int i = 1; ; i++)
{
if (Directory.Exists(targetPath))
{
targetPath = $"{savePath}{filename} ({i}){Path.DirectorySeparatorChar}";
}
else
{
break;
}
}
Directory.CreateDirectory(targetPath);
//导出FBX
Logger.Info($"Exporting {filename}.fbx");
Progress.Report(k, exportableCount);
try
{
ExportGameObject(gameObject, targetPath);
Logger.Debug($"{gameObject.type} \"{filename}\" saved to \"{targetPath}\"");
exportedCount++;
}
catch (Exception ex)
{
Logger.Error($"Export GameObject:{gameObject.m_Name} error", ex);
}
k++;
}
}
var status = exportedCount > 0
? $"Finished exporting [{exportedCount}/{exportableCount}] object(s) to \"{CLIOptions.o_outputFolder.Value.Color(Ansi.BrightCyan)}\""
: "Nothing exported";
Logger.Default.Log(LoggerEvent.Info, status, ignoreLevel: true);
}
private static void CollectNode(GameObjectNode node, List<GameObject> gameObjects)
{
gameObjects.Add(node.gameObject);
foreach (GameObjectNode i in node.nodes)
{
CollectNode(i, gameObjects);
}
}
public static void ExportLive2D() public static void ExportLive2D()
{ {
var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput"); var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput");

View File

@ -0,0 +1,22 @@
# Set the minimum version of CMake that can be used
cmake_minimum_required (VERSION 3.8)
# Set the project name
project("AssetStudioFBXNative")
# Set the C++ standard to C++ 14
set(CMAKE_CXX_STANDARD 14)
# Generate the shared library from the library sources
add_library(AssetStudioFBXNative SHARED
asfbx_skin_context.cpp
asfbx_morph_context.cpp
api.cpp
utils.cpp
asfbx_context.cpp
asfbx_anim_context.cpp)
# Add the given directories to those the compiler uses to search for include files
target_include_directories(AssetStudioFBXNative PRIVATE .)
target_link_libraries(AssetStudioFBXNative PRIVATE fbxsdk xml2)

View File

@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows</TargetFrameworks> <TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.17.2.0</Version> <Version>1.0.0</Version>
<Copyright>Copyright © Perfare 2018-2022; Copyright © hozuki 2020</Copyright> <Copyright>Copyright © Perfare 2018-2022; Copyright © hozuki 2020</Copyright>
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
</PropertyGroup> </PropertyGroup>

View File

@ -49,7 +49,7 @@
this.label7 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label();
this.modVersionLabel = new System.Windows.Forms.Label(); this.modVersionLabel = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label();
this.label8 = new System.Windows.Forms.Label(); this.basedOnLabel = new System.Windows.Forms.Label();
this.checkUpdatesLinkLabel = new System.Windows.Forms.LinkLabel(); this.checkUpdatesLinkLabel = new System.Windows.Forms.LinkLabel();
this.tabPage2 = new System.Windows.Forms.TabPage(); this.tabPage2 = new System.Windows.Forms.TabPage();
this.licenseRichTextBox = new System.Windows.Forms.RichTextBox(); this.licenseRichTextBox = new System.Windows.Forms.RichTextBox();
@ -116,8 +116,7 @@
this.label2.Name = "label2"; this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(347, 46); this.label2.Size = new System.Drawing.Size(347, 46);
this.label2.TabIndex = 0; this.label2.TabIndex = 0;
this.label2.Text = "AssetStudio is a tool for exploring, extracting, and exporting assets and asset b" + this.label2.Text = "ArknightsStudio is a modified version of AssetStudio designed for Arknights.";
"undles.";
this.label2.UseCompatibleTextRendering = true; this.label2.UseCompatibleTextRendering = true;
// //
// textBox2 // textBox2
@ -164,7 +163,7 @@
this.tableLayoutPanel2.ColumnCount = 3; this.tableLayoutPanel2.ColumnCount = 3;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.37931F)); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.37931F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.62069F)); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.62069F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 111F)); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 113F));
this.tableLayoutPanel2.Controls.Add(this.label16, 0, 0); this.tableLayoutPanel2.Controls.Add(this.label16, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.label17, 1, 0); this.tableLayoutPanel2.Controls.Add(this.label17, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.gitPerfareLinkLabel, 2, 0); this.tableLayoutPanel2.Controls.Add(this.gitPerfareLinkLabel, 2, 0);
@ -194,7 +193,7 @@
// //
this.label17.AutoSize = true; this.label17.AutoSize = true;
this.label17.BackColor = System.Drawing.Color.Transparent; this.label17.BackColor = System.Drawing.Color.Transparent;
this.label17.Location = new System.Drawing.Point(102, 2); this.label17.Location = new System.Drawing.Point(101, 2);
this.label17.Name = "label17"; this.label17.Name = "label17";
this.label17.Size = new System.Drawing.Size(110, 13); this.label17.Size = new System.Drawing.Size(110, 13);
this.label17.TabIndex = 10; this.label17.TabIndex = 10;
@ -204,7 +203,7 @@
// //
this.gitPerfareLinkLabel.AutoSize = true; this.gitPerfareLinkLabel.AutoSize = true;
this.gitPerfareLinkLabel.BackColor = System.Drawing.Color.Transparent; this.gitPerfareLinkLabel.BackColor = System.Drawing.Color.Transparent;
this.gitPerfareLinkLabel.Location = new System.Drawing.Point(239, 2); this.gitPerfareLinkLabel.Location = new System.Drawing.Point(237, 2);
this.gitPerfareLinkLabel.Name = "gitPerfareLinkLabel"; this.gitPerfareLinkLabel.Name = "gitPerfareLinkLabel";
this.gitPerfareLinkLabel.Size = new System.Drawing.Size(67, 13); this.gitPerfareLinkLabel.Size = new System.Drawing.Size(67, 13);
this.gitPerfareLinkLabel.TabIndex = 11; this.gitPerfareLinkLabel.TabIndex = 11;
@ -226,7 +225,7 @@
// //
this.label19.AutoSize = true; this.label19.AutoSize = true;
this.label19.BackColor = System.Drawing.Color.Transparent; this.label19.BackColor = System.Drawing.Color.Transparent;
this.label19.Location = new System.Drawing.Point(102, 20); this.label19.Location = new System.Drawing.Point(101, 20);
this.label19.Name = "label19"; this.label19.Name = "label19";
this.label19.Size = new System.Drawing.Size(113, 13); this.label19.Size = new System.Drawing.Size(113, 13);
this.label19.TabIndex = 13; this.label19.TabIndex = 13;
@ -236,7 +235,7 @@
// //
this.gitAelurumLinkLabel.AutoSize = true; this.gitAelurumLinkLabel.AutoSize = true;
this.gitAelurumLinkLabel.BackColor = System.Drawing.Color.Transparent; this.gitAelurumLinkLabel.BackColor = System.Drawing.Color.Transparent;
this.gitAelurumLinkLabel.Location = new System.Drawing.Point(239, 20); this.gitAelurumLinkLabel.Location = new System.Drawing.Point(237, 20);
this.gitAelurumLinkLabel.Name = "gitAelurumLinkLabel"; this.gitAelurumLinkLabel.Name = "gitAelurumLinkLabel";
this.gitAelurumLinkLabel.Size = new System.Drawing.Size(67, 13); this.gitAelurumLinkLabel.Size = new System.Drawing.Size(67, 13);
this.gitAelurumLinkLabel.TabIndex = 14; this.gitAelurumLinkLabel.TabIndex = 14;
@ -250,13 +249,13 @@
this.tableLayoutPanel1.ColumnCount = 3; this.tableLayoutPanel1.ColumnCount = 3;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.37931F)); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.37931F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.62069F)); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.62069F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 111F)); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 113F));
this.tableLayoutPanel1.Controls.Add(this.label5, 0, 0); this.tableLayoutPanel1.Controls.Add(this.label5, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.productNamelabel, 1, 0); this.tableLayoutPanel1.Controls.Add(this.productNamelabel, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.label7, 0, 1); this.tableLayoutPanel1.Controls.Add(this.label7, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.modVersionLabel, 1, 1); this.tableLayoutPanel1.Controls.Add(this.modVersionLabel, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.label4, 0, 2); this.tableLayoutPanel1.Controls.Add(this.label4, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.label8, 1, 2); this.tableLayoutPanel1.Controls.Add(this.basedOnLabel, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.checkUpdatesLinkLabel, 2, 1); this.tableLayoutPanel1.Controls.Add(this.checkUpdatesLinkLabel, 2, 1);
this.tableLayoutPanel1.Location = new System.Drawing.Point(6, 80); this.tableLayoutPanel1.Location = new System.Drawing.Point(6, 80);
this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.Name = "tableLayoutPanel1";
@ -285,11 +284,11 @@
// //
this.productNamelabel.AutoSize = true; this.productNamelabel.AutoSize = true;
this.productNamelabel.BackColor = System.Drawing.Color.Transparent; this.productNamelabel.BackColor = System.Drawing.Color.Transparent;
this.productNamelabel.Location = new System.Drawing.Point(102, 2); this.productNamelabel.Location = new System.Drawing.Point(101, 2);
this.productNamelabel.Name = "productNamelabel"; this.productNamelabel.Name = "productNamelabel";
this.productNamelabel.Size = new System.Drawing.Size(103, 13); this.productNamelabel.Size = new System.Drawing.Size(100, 13);
this.productNamelabel.TabIndex = 1; this.productNamelabel.TabIndex = 1;
this.productNamelabel.Text = "AssetStudioModGUI"; this.productNamelabel.Text = "ArknightsStudioGUI";
// //
// label7 // label7
// //
@ -297,16 +296,16 @@
this.label7.BackColor = System.Drawing.Color.Transparent; this.label7.BackColor = System.Drawing.Color.Transparent;
this.label7.Location = new System.Drawing.Point(5, 20); this.label7.Location = new System.Drawing.Point(5, 20);
this.label7.Name = "label7"; this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(68, 13); this.label7.Size = new System.Drawing.Size(45, 13);
this.label7.TabIndex = 2; this.label7.TabIndex = 2;
this.label7.Text = "Mod version:"; this.label7.Text = "Version:";
// //
// modVersionLabel // modVersionLabel
// //
this.modVersionLabel.AutoSize = true; this.modVersionLabel.AutoSize = true;
this.modVersionLabel.BackColor = System.Drawing.Color.Transparent; this.modVersionLabel.BackColor = System.Drawing.Color.Transparent;
this.modVersionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.modVersionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.modVersionLabel.Location = new System.Drawing.Point(102, 20); this.modVersionLabel.Location = new System.Drawing.Point(101, 20);
this.modVersionLabel.Name = "modVersionLabel"; this.modVersionLabel.Name = "modVersionLabel";
this.modVersionLabel.Size = new System.Drawing.Size(52, 13); this.modVersionLabel.Size = new System.Drawing.Size(52, 13);
this.modVersionLabel.TabIndex = 3; this.modVersionLabel.TabIndex = 3;
@ -323,21 +322,21 @@
this.label4.TabIndex = 4; this.label4.TabIndex = 4;
this.label4.Text = "Based on:"; this.label4.Text = "Based on:";
// //
// label8 // basedOnLabel
// //
this.label8.AutoSize = true; this.basedOnLabel.AutoSize = true;
this.label8.BackColor = System.Drawing.Color.Transparent; this.basedOnLabel.BackColor = System.Drawing.Color.Transparent;
this.label8.Location = new System.Drawing.Point(102, 38); this.basedOnLabel.Location = new System.Drawing.Point(101, 38);
this.label8.Name = "label8"; this.basedOnLabel.Name = "basedOnLabel";
this.label8.Size = new System.Drawing.Size(108, 13); this.basedOnLabel.Size = new System.Drawing.Size(123, 13);
this.label8.TabIndex = 5; this.basedOnLabel.TabIndex = 5;
this.label8.Text = "AssetStudio v0.16.47"; this.basedOnLabel.Text = "AssetStudioMod v0.17.0";
// //
// checkUpdatesLinkLabel // checkUpdatesLinkLabel
// //
this.checkUpdatesLinkLabel.AutoSize = true; this.checkUpdatesLinkLabel.AutoSize = true;
this.checkUpdatesLinkLabel.BackColor = System.Drawing.Color.Transparent; this.checkUpdatesLinkLabel.BackColor = System.Drawing.Color.Transparent;
this.checkUpdatesLinkLabel.Location = new System.Drawing.Point(239, 20); this.checkUpdatesLinkLabel.Location = new System.Drawing.Point(237, 20);
this.checkUpdatesLinkLabel.Name = "checkUpdatesLinkLabel"; this.checkUpdatesLinkLabel.Name = "checkUpdatesLinkLabel";
this.checkUpdatesLinkLabel.Size = new System.Drawing.Size(96, 13); this.checkUpdatesLinkLabel.Size = new System.Drawing.Size(96, 13);
this.checkUpdatesLinkLabel.TabIndex = 6; this.checkUpdatesLinkLabel.TabIndex = 6;
@ -391,7 +390,7 @@
this.productTitleLabel.Name = "productTitleLabel"; this.productTitleLabel.Name = "productTitleLabel";
this.productTitleLabel.Size = new System.Drawing.Size(384, 30); this.productTitleLabel.Size = new System.Drawing.Size(384, 30);
this.productTitleLabel.TabIndex = 1; this.productTitleLabel.TabIndex = 1;
this.productTitleLabel.Text = "AssetStudioModGUI"; this.productTitleLabel.Text = "ArknightsStudioGUI";
this.productTitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.productTitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
// //
// CloseButton // CloseButton
@ -492,7 +491,7 @@
private System.Windows.Forms.Label label7; private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label modVersionLabel; private System.Windows.Forms.Label modVersionLabel;
private System.Windows.Forms.Label label4; private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label8; private System.Windows.Forms.Label basedOnLabel;
private System.Windows.Forms.LinkLabel checkUpdatesLinkLabel; private System.Windows.Forms.LinkLabel checkUpdatesLinkLabel;
private System.Windows.Forms.RichTextBox licenseRichTextBox; private System.Windows.Forms.RichTextBox licenseRichTextBox;
private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.TextBox textBox2;

View File

@ -17,6 +17,7 @@ namespace AssetStudioGUI
productVersionLabel.Text = $"v{Application.ProductVersion} [{arch}]"; productVersionLabel.Text = $"v{Application.ProductVersion} [{arch}]";
productNamelabel.Text = productName; productNamelabel.Text = productName;
modVersionLabel.Text = Application.ProductVersion; modVersionLabel.Text = Application.ProductVersion;
basedOnLabel.Text = "AssetStudioMod v0.17.3";
licenseRichTextBox.Text = GetLicenseText(); licenseRichTextBox.Text = GetLicenseText();
} }
@ -41,7 +42,7 @@ namespace AssetStudioGUI
private void checkUpdatesLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) private void checkUpdatesLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{ {
var ps = new ProcessStartInfo("https://github.com/aelurum/AssetStudio/releases") var ps = new ProcessStartInfo("https://github.com/aelurum/AssetStudio/tags")
{ {
UseShellExecute = true UseShellExecute = true
}; };

View File

@ -5,9 +5,9 @@
<TargetFrameworks>net472;net6.0-windows;net7.0-windows</TargetFrameworks> <TargetFrameworks>net472;net6.0-windows;net7.0-windows</TargetFrameworks>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>Resources\as.ico</ApplicationIcon> <ApplicationIcon>Resources\as.ico</ApplicationIcon>
<AssemblyTitle>AssetStudioMod by aelurum</AssemblyTitle> <AssemblyTitle>ArknightsStudio by aelurum</AssemblyTitle>
<AssemblyName>AssetStudioModGUI</AssemblyName> <AssemblyName>ArknightsStudioGUI</AssemblyName>
<Version>0.17.2.0</Version> <Version>1.0.0</Version>
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2021-2023</Copyright> <Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2021-2023</Copyright>
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
</PropertyGroup> </PropertyGroup>

View File

@ -293,7 +293,7 @@
this.akTitleMenuItem.Name = "akTitleMenuItem"; this.akTitleMenuItem.Name = "akTitleMenuItem";
this.akTitleMenuItem.ShowShortcutKeys = false; this.akTitleMenuItem.ShowShortcutKeys = false;
this.akTitleMenuItem.Size = new System.Drawing.Size(265, 22); this.akTitleMenuItem.Size = new System.Drawing.Size(265, 22);
this.akTitleMenuItem.Text = "Arknighs"; this.akTitleMenuItem.Text = "Arknights";
// //
// akFixFaceSpriteNamesToolStripMenuItem // akFixFaceSpriteNamesToolStripMenuItem
// //
@ -302,7 +302,7 @@
this.akFixFaceSpriteNamesToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; this.akFixFaceSpriteNamesToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.akFixFaceSpriteNamesToolStripMenuItem.Name = "akFixFaceSpriteNamesToolStripMenuItem"; this.akFixFaceSpriteNamesToolStripMenuItem.Name = "akFixFaceSpriteNamesToolStripMenuItem";
this.akFixFaceSpriteNamesToolStripMenuItem.Size = new System.Drawing.Size(265, 22); this.akFixFaceSpriteNamesToolStripMenuItem.Size = new System.Drawing.Size(265, 22);
this.akFixFaceSpriteNamesToolStripMenuItem.Text = "Fix names of avg face sprites"; this.akFixFaceSpriteNamesToolStripMenuItem.Text = "Fix names of avg character sprites";
this.akFixFaceSpriteNamesToolStripMenuItem.ToolTipText = "Rename face sprites with numeric names to correct ones"; this.akFixFaceSpriteNamesToolStripMenuItem.ToolTipText = "Rename face sprites with numeric names to correct ones";
this.akFixFaceSpriteNamesToolStripMenuItem.CheckedChanged += new System.EventHandler(this.akFixFaceSpriteNamesToolStripMenuItem_Check); this.akFixFaceSpriteNamesToolStripMenuItem.CheckedChanged += new System.EventHandler(this.akFixFaceSpriteNamesToolStripMenuItem_Check);
// //

View File

@ -512,9 +512,9 @@
this.akResamplerLabel.AutoSize = true; this.akResamplerLabel.AutoSize = true;
this.akResamplerLabel.Location = new System.Drawing.Point(6, 21); this.akResamplerLabel.Location = new System.Drawing.Point(6, 21);
this.akResamplerLabel.Name = "akResamplerLabel"; this.akResamplerLabel.Name = "akResamplerLabel";
this.akResamplerLabel.Size = new System.Drawing.Size(113, 13); this.akResamplerLabel.Size = new System.Drawing.Size(120, 13);
this.akResamplerLabel.TabIndex = 5; this.akResamplerLabel.TabIndex = 5;
this.akResamplerLabel.Text = "Alpha mask resampler:"; this.akResamplerLabel.Text = "Alpha texture resampler:";
this.exportUvsTooltip.SetToolTip(this.akResamplerLabel, "Only affects exported images"); this.exportUvsTooltip.SetToolTip(this.akResamplerLabel, "Only affects exported images");
// //
// akResamplerComboBox // akResamplerComboBox
@ -528,9 +528,9 @@
"Mitchell-Netravali", "Mitchell-Netravali",
"Spline", "Spline",
"Welch"}); "Welch"});
this.akResamplerComboBox.Location = new System.Drawing.Point(125, 18); this.akResamplerComboBox.Location = new System.Drawing.Point(132, 18);
this.akResamplerComboBox.Name = "akResamplerComboBox"; this.akResamplerComboBox.Name = "akResamplerComboBox";
this.akResamplerComboBox.Size = new System.Drawing.Size(169, 21); this.akResamplerComboBox.Size = new System.Drawing.Size(162, 21);
this.akResamplerComboBox.TabIndex = 4; this.akResamplerComboBox.TabIndex = 4;
this.exportUvsTooltip.SetToolTip(this.akResamplerComboBox, "Only affects exported images"); this.exportUvsTooltip.SetToolTip(this.akResamplerComboBox, "Only affects exported images");
// //
@ -549,7 +549,7 @@
this.akSpritesAlphaGroupBox.Size = new System.Drawing.Size(300, 178); this.akSpritesAlphaGroupBox.Size = new System.Drawing.Size(300, 178);
this.akSpritesAlphaGroupBox.TabIndex = 12; this.akSpritesAlphaGroupBox.TabIndex = 12;
this.akSpritesAlphaGroupBox.TabStop = false; this.akSpritesAlphaGroupBox.TabStop = false;
this.akSpritesAlphaGroupBox.Text = "Sprites: Alpha Mask [Arknights]"; this.akSpritesAlphaGroupBox.Text = "Sprites: Alpha Texture [Arknights]";
// //
// akGammaNoteLabel // akGammaNoteLabel
// //
@ -567,9 +567,9 @@
this.akResamplerDescLabel.ForeColor = System.Drawing.SystemColors.GrayText; this.akResamplerDescLabel.ForeColor = System.Drawing.SystemColors.GrayText;
this.akResamplerDescLabel.Location = new System.Drawing.Point(6, 43); this.akResamplerDescLabel.Location = new System.Drawing.Point(6, 43);
this.akResamplerDescLabel.Name = "akResamplerDescLabel"; this.akResamplerDescLabel.Name = "akResamplerDescLabel";
this.akResamplerDescLabel.Size = new System.Drawing.Size(244, 13); this.akResamplerDescLabel.Size = new System.Drawing.Size(251, 13);
this.akResamplerDescLabel.TabIndex = 6; this.akResamplerDescLabel.TabIndex = 6;
this.akResamplerDescLabel.Text = "Alpha mask upscale method for 2048x2048 sprites"; this.akResamplerDescLabel.Text = "Alpha texture upscale method for 2048x2048 sprites";
// //
// akResizedOnlyCheckBox // akResizedOnlyCheckBox
// //
@ -597,9 +597,9 @@
this.akGammaLabel.AutoSize = true; this.akGammaLabel.AutoSize = true;
this.akGammaLabel.Location = new System.Drawing.Point(6, 86); this.akGammaLabel.Location = new System.Drawing.Point(6, 86);
this.akGammaLabel.Name = "akGammaLabel"; this.akGammaLabel.Name = "akGammaLabel";
this.akGammaLabel.Size = new System.Drawing.Size(102, 13); this.akGammaLabel.Size = new System.Drawing.Size(86, 13);
this.akGammaLabel.TabIndex = 1; this.akGammaLabel.TabIndex = 1;
this.akGammaLabel.Text = "Alpha mask gamma:"; this.akGammaLabel.Text = "Shadow gamma:";
// //
// akAlphaMaskGammaTrackBar // akAlphaMaskGammaTrackBar
// //
@ -627,9 +627,9 @@
this.akAddAliasesCheckBox.AutoSize = true; this.akAddAliasesCheckBox.AutoSize = true;
this.akAddAliasesCheckBox.Location = new System.Drawing.Point(6, 28); this.akAddAliasesCheckBox.Location = new System.Drawing.Point(6, 28);
this.akAddAliasesCheckBox.Name = "akAddAliasesCheckBox"; this.akAddAliasesCheckBox.Name = "akAddAliasesCheckBox";
this.akAddAliasesCheckBox.Size = new System.Drawing.Size(213, 17); this.akAddAliasesCheckBox.Size = new System.Drawing.Size(261, 17);
this.akAddAliasesCheckBox.TabIndex = 0; this.akAddAliasesCheckBox.TabIndex = 0;
this.akAddAliasesCheckBox.Text = "Add aliases to avg sprite names (if exist)"; this.akAddAliasesCheckBox.Text = "Add aliases to avg character sprite names (if exist)";
this.akAddAliasesCheckBox.UseVisualStyleBackColor = true; this.akAddAliasesCheckBox.UseVisualStyleBackColor = true;
// //
// ExportOptions // ExportOptions

View File

@ -33,7 +33,12 @@ namespace AssetStudio
public TypeDefinition GetTypeDefinition(string assemblyName, string fullName) public TypeDefinition GetTypeDefinition(string assemblyName, string fullName)
{ {
if (moduleDic.TryGetValue(assemblyName, out var module)) moduleDic.TryGetValue(assemblyName, out var module);
if (module == null && !assemblyName.Contains(".dll"))
{
moduleDic.TryGetValue(assemblyName + ".dll", out module);
}
if (module != null)
{ {
var typeDef = module.GetType(fullName); var typeDef = module.GetType(fullName);
if (typeDef == null && assemblyName == "UnityEngine.dll") if (typeDef == null && assemblyName == "UnityEngine.dll")

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows</TargetFrameworks> <TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows</TargetFrameworks>
<Version>0.17.2.0</Version> <Version>1.0.0</Version>
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2023</Copyright> <Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2023</Copyright>
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
</PropertyGroup> </PropertyGroup>

View File

@ -1,5 +1,14 @@
# Changelog # Changelog
## v0.17.3.0 [13-09-2023]
- [CLI] Added support for exporting split objects (fbx) (https://github.com/aelurum/AssetStudio/pull/10)
- [CLI] Fixed display of asset names in the exported asset list in some working modes
- [CLI] Fixed a bug where the default output folder might not exist
- Added support of Texture2D assets from Unity 2022.2+
- Fixed AssemblyLoader (https://github.com/aelurum/AssetStudio/issues/6)
- [CLI] Added --load-all flag to load assets of all types
- [CLI] Improved option grouping on the help screen
## v0.17.2.0 [27-08-2023] ## v0.17.2.0 [27-08-2023]
- [GUI] Improved Scene Hierarchy tab - [GUI] Improved Scene Hierarchy tab
- Added "Related assets" item to the context menu (https://github.com/aelurum/AssetStudio/issues/7) - Added "Related assets" item to the context menu (https://github.com/aelurum/AssetStudio/issues/7)

View File

@ -70,7 +70,7 @@ You can read CLI readme [here](https://github.com/aelurum/AssetStudio/blob/Asset
``` ```
AssetStudioModCLI <asset folder path> -m info AssetStudioModCLI <asset folder path> -m info
``` ```
- Export assets of all supported types - Export assets of all supported for export types
``` ```
AssetStudioModCLI <asset folder path> AssetStudioModCLI <asset folder path>
``` ```
@ -89,12 +89,22 @@ AssetStudioModCLI <asset folder path> -g type
``` ```
AssetStudioModCLI <asset folder path> -o <output folder path> AssetStudioModCLI <asset folder path> -o <output folder path>
``` ```
- Dump assets to a specified output folder
```
AssetStudioModCLI <asset folder path> -m dump -o <output folder path>
```
- Export Live2D Cubism models - Export Live2D Cubism models
``` ```
AssetStudioModCLI <asset folder path> -m live2d AssetStudioModCLI <asset folder path> -m live2d
``` ```
> When running in live2d mode you can only specify `-o`, `--log-level`, `--log-output`, `--export-asset-list`, `--unity-version` and `--assembly-folder` options. > When running in live2d mode you can only specify `-o`, `--log-level`, `--log-output`, `--export-asset-list`, `--unity-version` and `--assembly-folder` options.
Any other options will be ignored. Any other options will be ignored.
- Export all FBX objects (similar to "Export all objects (split)" option in the GUI)
```
AssetStudioModCLI <asset folder path> -m splitObjects
```
> When running in splitObjects mode you can only specify `-o`, `--log-level`, `--log-output`, `--export-asset-list`, `--image-format`, `--filter-by-name` and `--unity-version` options.
Any other options will be ignored.
### Advanced Samples ### Advanced Samples
- Export image assets converted to webp format to a specified output folder - Export image assets converted to webp format to a specified output folder
@ -109,6 +119,13 @@ AssetStudioModCLI <asset folder path> -m info -t audio --filter-by-name voice
``` ```
AssetStudioModCLI <asset folder path> -t audio --filter-by-name voice AssetStudioModCLI <asset folder path> -t audio --filter-by-name voice
``` ```
- Export audio assets that have "music" or "voice" in their names
```
AssetStudioModCLI <asset folder path> -t audio --filter-by-name music,voice
```
```
AssetStudioModCLI <asset folder path> -t audio --filter-by-name music --filter-by-name voice
```
- Export audio assets that have "char" in their names **or** containers - Export audio assets that have "char" in their names **or** containers
``` ```
AssetStudioModCLI <asset folder path> -t audio --filter-by-text char AssetStudioModCLI <asset folder path> -t audio --filter-by-text char
@ -117,6 +134,10 @@ AssetStudioModCLI <asset folder path> -t audio --filter-by-text char
``` ```
AssetStudioModCLI <asset folder path> -t audio --filter-by-name voice --filter-by-container char AssetStudioModCLI <asset folder path> -t audio --filter-by-name voice --filter-by-container char
``` ```
- Export FBX objects that have "model" or "scene" in their names and set the scale factor to 10
```
AssetStudioModCLI <asset folder path> -m splitObjects --filter-by-name model,scene --fbx-scale-factor 10
```
- Export MonoBehaviour assets that require an assembly folder to read and create a log file - Export MonoBehaviour assets that require an assembly folder to read and create a log file
``` ```
AssetStudioModCLI <asset folder path> -t monobehaviour --assembly-folder <assembly folder path> --log-output both AssetStudioModCLI <asset folder path> -t monobehaviour --assembly-folder <assembly folder path> --log-output both
@ -125,6 +146,14 @@ AssetStudioModCLI <asset folder path> -t monobehaviour --assembly-folder <assemb
``` ```
AssetStudioModCLI <asset folder path> --unity-version 2017.4.39f1 AssetStudioModCLI <asset folder path> --unity-version 2017.4.39f1
``` ```
- Load assets of all types and show them (similar to "Display all assets" option in the GUI)
```
AssetStudioModCLI <asset folder path> -m info --load-all
```
- Load assets of all types and dump Material assets
```
AssetStudioModCLI <asset folder path> -m dump -t material --load-all
```
## GUI Usage ## GUI Usage
@ -140,7 +169,7 @@ Use **File->Extract file** or **File->Extract folder**.
### Export Assets, Live2D models ### Export Assets, Live2D models
use **Export** menu. Use **Export** menu.
### Export Model ### Export Model

View File

@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net472</TargetFramework> <TargetFramework>net472</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.17.2.0</Version> <Version>1.0.0</Version>
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright> <Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
</PropertyGroup> </PropertyGroup>