diff --git a/AssetStudio.PInvoke/AssetStudio.PInvoke.csproj b/AssetStudio.PInvoke/AssetStudio.PInvoke.csproj
index fc533b6..59938d8 100644
--- a/AssetStudio.PInvoke/AssetStudio.PInvoke.csproj
+++ b/AssetStudio.PInvoke/AssetStudio.PInvoke.csproj
@@ -3,7 +3,7 @@
net472;net6.0;net6.0-windows;net7.0;net7.0-windows
true
- 0.17.2.0
+ 1.0.0
Copyright © Perfare 2020-2022; Copyright © hozuki 2020
embedded
diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj
index 90b4762..cb2ed75 100644
--- a/AssetStudio/AssetStudio.csproj
+++ b/AssetStudio/AssetStudio.csproj
@@ -2,7 +2,7 @@
net472;net6.0;net6.0-windows;net7.0;net7.0-windows
- 0.17.2.0
+ 1.0.0
Copyright © Perfare 2018-2022; Copyright © aelurum 2023
embedded
diff --git a/AssetStudio/Classes/Texture2D.cs b/AssetStudio/Classes/Texture2D.cs
index af90baf..d9cadfb 100644
--- a/AssetStudio/Classes/Texture2D.cs
+++ b/AssetStudio/Classes/Texture2D.cs
@@ -91,7 +91,14 @@ namespace AssetStudio
}
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
{
@@ -100,6 +107,11 @@ namespace AssetStudio
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
{
var m_StreamingMipmaps = reader.ReadBoolean();
diff --git a/AssetStudioCLI/AssetStudioCLI.csproj b/AssetStudioCLI/AssetStudioCLI.csproj
index 326ad44..7aca31b 100644
--- a/AssetStudioCLI/AssetStudioCLI.csproj
+++ b/AssetStudioCLI/AssetStudioCLI.csproj
@@ -3,9 +3,9 @@
Exe
net472;net6.0;net7.0
- AssetStudioMod by aelurum
- AssetStudioModCLI
- 0.17.2.0
+ ArknightsStudio by aelurum
+ ArknightsStudioCLI
+ 1.0.0
Copyright © Perfare; Copyright © aelurum 2023
AnyCPU
embedded
@@ -24,6 +24,8 @@
+
+
@@ -32,6 +34,9 @@
+
+
+
@@ -42,6 +47,8 @@
The dll is cross-platform while the executable isn't -->
+
+
@@ -50,6 +57,9 @@
+
+
+
@@ -58,39 +68,46 @@
+
+
+
+
+
+
+
diff --git a/AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs b/AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs
index b86ff28..5d8ef2b 100644
--- a/AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs
+++ b/AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs
@@ -148,11 +148,11 @@ namespace Arknights
bool resized = false;
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;
}
- 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)
{
invGamma = 1.0;
diff --git a/AssetStudioCLI/Components/AssetItem.cs b/AssetStudioCLI/Components/AssetItem.cs
index acb25ac..47f1cbb 100644
--- a/AssetStudioCLI/Components/AssetItem.cs
+++ b/AssetStudioCLI/Components/AssetItem.cs
@@ -14,6 +14,7 @@ namespace AssetStudioCLI
public ClassIDType Type;
public string Text;
public string UniqueID;
+ public GameObjectNode Node;
public PortraitSprite AkPortraitSprite;
public AssetItem(Object asset)
diff --git a/AssetStudioCLI/Components/BaseNode.cs b/AssetStudioCLI/Components/BaseNode.cs
new file mode 100644
index 0000000..ecc3a60
--- /dev/null
+++ b/AssetStudioCLI/Components/BaseNode.cs
@@ -0,0 +1,16 @@
+using AssetStudio;
+using System.Collections.Generic;
+
+namespace AssetStudioCLI
+{
+ internal class BaseNode
+ {
+ public List nodes = new List();
+
+ public BaseNode()
+ {
+
+ }
+
+ }
+}
diff --git a/AssetStudioCLI/Components/GameObjectNode.cs b/AssetStudioCLI/Components/GameObjectNode.cs
new file mode 100644
index 0000000..4d88ee0
--- /dev/null
+++ b/AssetStudioCLI/Components/GameObjectNode.cs
@@ -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;
+ }
+
+ }
+}
diff --git a/AssetStudioCLI/Exporter.cs b/AssetStudioCLI/Exporter.cs
index ba09615..b55d327 100644
--- a/AssetStudioCLI/Exporter.cs
+++ b/AssetStudioCLI/Exporter.cs
@@ -4,6 +4,7 @@ using AssetStudioCLI.Options;
using Newtonsoft.Json;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
@@ -243,7 +244,7 @@ namespace AssetStudioCLI
var alias = "";
var m_Sprite = (Sprite)item.Asset;
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 isCharArt = item.Container.Contains("arts/characters");
@@ -271,7 +272,7 @@ namespace AssetStudioCLI
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath, alias))
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)
{
@@ -307,7 +308,7 @@ namespace AssetStudioCLI
public static bool ExportPortraitSprite(AssetItem item, string exportPath)
{
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))
return false;
@@ -342,6 +343,33 @@ namespace AssetStudioCLI
return true;
}
+ public static void ExportGameObject(GameObject gameObject, string exportPath, List 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)
{
if (item.Asset == null)
diff --git a/AssetStudioCLI/Libraries/linux-x64/libAssetStudioFBXNative.so b/AssetStudioCLI/Libraries/linux-x64/libAssetStudioFBXNative.so
new file mode 100644
index 0000000..6ee1b36
Binary files /dev/null and b/AssetStudioCLI/Libraries/linux-x64/libAssetStudioFBXNative.so differ
diff --git a/AssetStudioCLI/Libraries/osx-arm64/libAssetStudioFBXNative.dylib b/AssetStudioCLI/Libraries/osx-arm64/libAssetStudioFBXNative.dylib
new file mode 100644
index 0000000..85263f5
Binary files /dev/null and b/AssetStudioCLI/Libraries/osx-arm64/libAssetStudioFBXNative.dylib differ
diff --git a/AssetStudioCLI/Libraries/osx-x64/libAssetStudioFBXNative.dylib b/AssetStudioCLI/Libraries/osx-x64/libAssetStudioFBXNative.dylib
new file mode 100644
index 0000000..8d4d6ca
Binary files /dev/null and b/AssetStudioCLI/Libraries/osx-x64/libAssetStudioFBXNative.dylib differ
diff --git a/AssetStudioCLI/Options/CLIOptions.cs b/AssetStudioCLI/Options/CLIOptions.cs
index 28d127b..0f8dab7 100644
--- a/AssetStudioCLI/Options/CLIOptions.cs
+++ b/AssetStudioCLI/Options/CLIOptions.cs
@@ -14,6 +14,8 @@ namespace AssetStudioCLI.Options
General,
Convert,
Logger,
+ FBX,
+ Filter,
Arknights,
Advanced,
}
@@ -25,6 +27,7 @@ namespace AssetStudioCLI.Options
Dump,
Info,
ExportLive2D,
+ SplitObjects,
}
internal enum AssetGroupOption
@@ -58,11 +61,11 @@ namespace AssetStudioCLI.Options
NameAndContainer,
}
- internal enum AkSpriteMaskMode
+ internal enum AkSpriteAlphaMode
{
None,
- Internal,
- External
+ InternalOnly,
+ SearchExternal
}
internal static class CLIOptions
@@ -75,7 +78,8 @@ namespace AssetStudioCLI.Options
private static Dictionary optionsDict;
private static Dictionary flagsDict;
private static Dictionary> optionGroups;
- private static List supportedAssetTypes;
+ private static List exportableAssetTypes;
+ private static Dictionary knownAssetTypesDict;
//general
public static Option o_workMode;
public static Option> o_exportAssetTypes;
@@ -89,23 +93,28 @@ namespace AssetStudioCLI.Options
public static bool convertTexture;
public static Option o_imageFormat;
public static Option o_audioFormat;
- //arknights
- public static bool akResizedOnly;
- public static Option o_akSpriteMaskMode;
- public static Option o_akAlphaMaskResampler;
- private static string resamplerName;
- public static Option o_akAlphaMaskGamma;
- public static Option f_akOriginalAvgNames;
- public static Option f_akAddAliases;
- //advanced
- public static Option o_exportAssetList;
+ //fbx
+ public static Option o_fbxScaleFactor;
+ public static Option o_fbxBoneSize;
+ //filter
public static Option> o_filterByName;
public static Option> o_filterByContainer;
public static Option> o_filterByPathID;
public static Option> o_filterByText;
+ //arknights
+ public static bool akResizedOnly;
+ public static Option o_akSpriteAlphaMode;
+ public static Option o_akAlphaTexResampler;
+ private static string resamplerName;
+ public static Option o_akShadowGamma;
+ public static Option f_akOriginalAvgNames;
+ public static Option f_akAddAliases;
+ //advanced
+ public static Option o_exportAssetList;
public static Option o_assemblyPath;
public static Option o_unityVersion;
public static Option f_notRestoreExtensionName;
+ public static Option f_loadAllAssets;
static CLIOptions()
{
@@ -150,7 +159,7 @@ namespace AssetStudioCLI.Options
optionsDict = new Dictionary();
flagsDict = new Dictionary();
optionGroups = new Dictionary>();
- supportedAssetTypes = new List
+ exportableAssetTypes = new List
{
ClassIDType.Texture2D,
ClassIDType.Sprite,
@@ -164,6 +173,7 @@ namespace AssetStudioCLI.Options
ClassIDType.MovieTexture,
ClassIDType.Mesh,
};
+ knownAssetTypesDict = ((ClassIDType[])Enum.GetValues(typeof(ClassIDType))).ToHashSet().ToDictionary(x => x.ToString().ToLower(), y => y);
#region Init General Options
o_workMode = new GroupedOption
@@ -171,18 +181,19 @@ namespace AssetStudioCLI.Options
optionDefaultValue: WorkMode.Export,
optionName: "-m, --mode ",
optionDescription: "Specify working mode\n" +
- "\n" +
+ "\n" +
"Export - Exports converted assets\n" +
"ExportRaw - Exports raw data\n" +
"Dump - Makes asset dumps\n" +
"Info - Loads file(s), shows the number of available for export assets and exits\n" +
"Live2D - Exports Live2D Cubism 3 models\n" +
+ "SplitObjects - Exports split objects (fbx)\n" +
"Example: \"-m info\"\n",
optionHelpGroup: HelpGroups.General
);
o_exportAssetTypes = new GroupedOption>
(
- optionDefaultValue: supportedAssetTypes,
+ optionDefaultValue: exportableAssetTypes,
optionName: "-t, --asset-type ",
optionDescription: "Specify asset type(s) to export\n" +
"
(
- optionDefaultValue: "",
+ optionDefaultValue: "ASExport",
optionName: "-o, --output ",
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",
@@ -268,52 +279,113 @@ namespace AssetStudioCLI.Options
);
#endregion
+ #region Init FBX Options
+ o_fbxScaleFactor = new GroupedOption
+ (
+ optionDefaultValue: 1f,
+ optionName: "--fbx-scale-factor ",
+ optionDescription: "Specify the FBX Scale Factor\n" +
+ "
+ (
+ optionDefaultValue: 10,
+ optionName: "--fbx-bone-size ",
+ optionDescription: "Specify the FBX Bone Size\n" +
+ ">
+ (
+ optionDefaultValue: new List(),
+ optionName: "--filter-by-name ",
+ 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>
+ (
+ optionDefaultValue: new List(),
+ optionName: "--filter-by-container ",
+ 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>
+ (
+ optionDefaultValue: new List(),
+ optionName: "--filter-by-pathid ",
+ 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>
+ (
+ optionDefaultValue: new List(),
+ optionName: "--filter-by-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
akResizedOnly = true;
- o_akSpriteMaskMode = new GroupedOption
+ o_akSpriteAlphaMode = new GroupedOption
(
- optionDefaultValue: AkSpriteMaskMode.External,
- optionName: "--spritemask-mode ",
- optionDescription: "Specify the mode in which you want to export sprites with alpha mask\n" +
+ optionDefaultValue: AkSpriteAlphaMode.SearchExternal,
+ optionName: "--spritealpha-mode ",
+ optionDescription: "Specify the mode in which you want to export sprites with alpha texture\n" +
"\n" +
- "None - Export sprites without alpha mask applied\n" +
- "Internal - Export sprites with internal alpha mask applied (if exist)\n" +
- "SearchExternal - Export sprites with internal alpha mask applied,\n" +
- "and in case it doesn't exist, Studio will try to find an external alpha mask\n" +
- "Example: \"--spritemask-mode internalOnly\"\n",
+ "None - Export sprites without alpha texture applied\n" +
+ "InternalOnly - Export sprites with internal alpha texture applied (if exist)\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 texture\n" +
+ "Example: \"--spritealpha-mode internalOnly\"\n",
optionHelpGroup: HelpGroups.Arknights
);
- o_akAlphaMaskResampler = new GroupedOption
+ o_akAlphaTexResampler = new GroupedOption
(
optionDefaultValue: KnownResamplers.MitchellNetravali,
- optionName: "--alphamask-resampler ",
- optionDescription: "Specify the alpha mask upscale algorithm for 2048x2048 sprites\n" +
+ optionName: "--alphatex-resampler ",
+ optionDescription: "Specify the alpha texture upscale algorithm for 2048x2048 sprites\n" +
"\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" +
"Welch - A high speed algorithm that delivers very sharpened results\n" +
- "Example: \"--alphamask-resampler bicubic\"\n",
+ "Example: \"--alphatex-resampler bicubic\"\n",
optionHelpGroup: HelpGroups.Arknights
);
resamplerName = "Mitchell";
- o_akAlphaMaskGamma = new GroupedOption
+ o_akShadowGamma = new GroupedOption
(
optionDefaultValue: 2,
- optionName: "--alphamask-gamma ",
- optionDescription: "Specify the alpha mask gamma correction for 2048x2048 sprites\n" +
+ optionName: "--shadow-gamma ",
+ optionDescription: "Specify the gamma correction of semi-transparent shadow for 2048x2048 sprites\n" +
"\n" +
- "<0 - Make the alpha mask darker\n" +
- "0 - Do not change the gamma of alpha mask\n" +
- ">0 - Make the alpha mask lighter\n" +
- "Example: \"--alphamask-gamma 0\"\n",
+ "<0 - Make the shadow darker\n" +
+ "0 - Do not change the brightness of the shadow\n" +
+ ">0 - Make the shadow lighter\n" +
+ "Example: \"--shadow-gamma 0\"\n",
optionHelpGroup: HelpGroups.Arknights
);
f_akOriginalAvgNames = new GroupedOption
(
optionDefaultValue: false,
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,
isFlag: true
);
@@ -321,7 +393,7 @@ namespace AssetStudioCLI.Options
(
optionDefaultValue: false,
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,
isFlag: true
);
@@ -338,62 +410,33 @@ namespace AssetStudioCLI.Options
"Example: \"--export-asset-list xml\"\n",
optionHelpGroup: HelpGroups.Advanced
);
- o_filterByName = new GroupedOption>
- (
- optionDefaultValue: new List(),
- optionName: "--filter-by-name ",
- 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>
- (
- optionDefaultValue: new List(),
- optionName: "--filter-by-container ",
- 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>
- (
- optionDefaultValue: new List(),
- optionName: "--filter-by-pathid ",
- 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>
- (
- optionDefaultValue: new List(),
- optionName: "--filter-by-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
(
optionDefaultValue: "",
optionName: "--assembly-folder ",
- optionDescription: "Specify the path to the assembly folder",
+ optionDescription: "Specify the path to the assembly folder\n",
optionHelpGroup: HelpGroups.Advanced
);
o_unityVersion = new GroupedOption
(
optionDefaultValue: "",
optionName: "--unity-version ",
- optionDescription: "Specify Unity version. Example: \"--unity-version 2017.4.39f1\"",
+ optionDescription: "Specify Unity version\nExample: \"--unity-version 2017.4.39f1\"\n",
optionHelpGroup: HelpGroups.Advanced
);
f_notRestoreExtensionName = new GroupedOption
(
optionDefaultValue: false,
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
+ (
+ 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,
isFlag: true
);
@@ -407,7 +450,7 @@ namespace AssetStudioCLI.Options
var brightYellow = CLIAnsiColors.BrightYellow;
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;
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.");
return;
}
- o_outputFolder.Value = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ASExport");
}
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.AnimationClip,
+ ClassIDType.GameObject,
+ ClassIDType.MonoBehaviour,
+ ClassIDType.Texture2D,
+ ClassIDType.Transform,
+ };
+ break;
+ case "splitobjects":
+ o_workMode.Value = WorkMode.SplitObjects;
+ o_exportAssetTypes.Value = new List()
+ {
+ 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
for (int i = 0; i < resplittedArgs.Count; i++)
{
@@ -458,6 +558,21 @@ namespace AssetStudioCLI.Options
f_notRestoreExtensionName.Value = true;
resplittedArgs.RemoveAt(i);
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":
f_akOriginalAvgNames.Value = true;
resplittedArgs.RemoveAt(i);
@@ -479,43 +594,9 @@ namespace AssetStudioCLI.Options
var value = resplittedArgs[i + 1].Replace("\"", "");
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.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 "--asset-type":
- if (o_workMode.Value == WorkMode.ExportLive2D)
+ if (o_workMode.Value == WorkMode.ExportLive2D || o_workMode.Value == WorkMode.SplitObjects)
{
i++;
continue;
@@ -527,47 +608,38 @@ namespace AssetStudioCLI.Options
switch (type.ToLower())
{
case "tex2d":
- case "texture2d":
o_exportAssetTypes.Value.Add(ClassIDType.Texture2D);
break;
- case "sprite":
- o_exportAssetTypes.Value.Add(ClassIDType.Sprite);
- break;
case "akportrait":
o_exportAssetTypes.Value.Add(ClassIDType.AkPortraitSprite);
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 "audioclip":
o_exportAssetTypes.Value.Add(ClassIDType.AudioClip);
break;
case "video":
- case "videoclip":
o_exportAssetTypes.Value.Add(ClassIDType.VideoClip);
break;
- case "movietexture":
- o_exportAssetTypes.Value.Add(ClassIDType.MovieTexture);
- break;
- case "mesh":
- o_exportAssetTypes.Value.Add(ClassIDType.Mesh);
- break;
case "all":
- o_exportAssetTypes.Value = supportedAssetTypes;
+ o_exportAssetTypes.Value = exportableAssetTypes;
break;
default:
- Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported asset type: [{value.Color(brightRed)}].\n");
- Console.WriteLine(o_exportAssetTypes.Description);
+ var isKnownType = knownAssetTypesDict.TryGetValue(type.ToLower(), out var assetType);
+ 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;
}
}
@@ -593,7 +665,7 @@ namespace AssetStudioCLI.Options
break;
default:
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;
}
break;
@@ -606,6 +678,10 @@ namespace AssetStudioCLI.Options
{
Directory.CreateDirectory(value);
}
+ if (!value.EndsWith($"{Path.DirectorySeparatorChar}"))
+ {
+ value += Path.DirectorySeparatorChar;
+ }
o_outputFolder.Value = value;
}
catch (Exception ex)
@@ -640,7 +716,7 @@ namespace AssetStudioCLI.Options
break;
default:
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;
}
break;
@@ -658,7 +734,7 @@ namespace AssetStudioCLI.Options
break;
default:
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;
}
break;
@@ -686,7 +762,7 @@ namespace AssetStudioCLI.Options
break;
default:
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;
}
break;
@@ -702,84 +778,40 @@ namespace AssetStudioCLI.Options
break;
default:
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;
}
break;
- case "--spritemask-mode":
- switch (value.ToLower())
+ case "--fbx-scale-factor":
{
- case "none":
- o_akSpriteMaskMode.Value = AkSpriteMaskMode.None;
- break;
- case "internal":
- o_akSpriteMaskMode.Value = AkSpriteMaskMode.Internal;
- break;
- case "searchexternal":
- o_akSpriteMaskMode.Value = AkSpriteMaskMode.External;
- break;
- default:
- Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported sprite mask mode: [{value.Color(brightRed)}].\n");
- Console.WriteLine(o_akSpriteMaskMode.Description);
+ var isFloat = float.TryParse(value, out float floatValue);
+ if (isFloat && floatValue >= 0 && floatValue <= 100)
+ {
+ o_fbxScaleFactor.Value = floatValue;
+ }
+ else
+ {
+ Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported scale factor value: [{value.Color(brightRed)}].\n");
+ ShowOptionDescription(o_fbxScaleFactor.Description);
return;
+ }
+ break;
}
- break;
- case "--alphamask-resampler":
- switch (value.ToLower())
+ case "--fbx-bone-size":
{
- case "nearest":
- o_akAlphaMaskResampler.Value = KnownResamplers.NearestNeighbor;
- break;
- case "bilinear":
- o_akAlphaMaskResampler.Value = KnownResamplers.Triangle;
- break;
- case "bicubic":
- o_akAlphaMaskResampler.Value = KnownResamplers.Bicubic;
- break;
- 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);
+ var isInt = int.TryParse(value, out int intValue);
+ if (isInt && intValue >= 0 && intValue <= 100)
+ {
+ o_fbxBoneSize.Value = intValue;
+ }
+ else
+ {
+ Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported bone size value: [{value.Color(brightRed)}].\n");
+ ShowOptionDescription(o_fbxBoneSize.Description);
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":
o_filterByName.Value.AddRange(ValueSplitter(value));
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));
filterBy = FilterBy.NameOrContainer;
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":
if (Directory.Exists(value))
{
@@ -813,9 +921,9 @@ namespace AssetStudioCLI.Options
break;
default:
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;
}
@@ -826,12 +934,12 @@ namespace AssetStudioCLI.Options
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");
- TryShowOptionDescription(option, optionsDict);
+ TryFindOptionDescription(option, optionsDict);
}
else if (flagsDict.Any(x => x.Key.Contains(option)))
{
Console.WriteLine($"{"Error:".Color(brightRed)} Unknown flag [{option.Color(brightRed)}].\n");
- TryShowOptionDescription(option, flagsDict);
+ TryFindOptionDescription(option, flagsDict, isFlag: true);
}
else
{
@@ -852,6 +960,15 @@ namespace AssetStudioCLI.Options
{
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;
}
@@ -861,14 +978,21 @@ namespace AssetStudioCLI.Options
return value.Split(separator);
}
- private static bool TryShowOptionDescription(string option, Dictionary 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 dict, bool isFlag = false)
+ {
+ var optionDesc = dict.Where(x => x.Key.Contains(option));
if (optionDesc.Any())
{
+ var arg = isFlag ? "flag" : "option";
var rand = new Random();
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}");
return true;
@@ -910,7 +1034,7 @@ namespace AssetStudioCLI.Options
else
{
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}");
}
}
@@ -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()
{
var sb = new StringBuilder();
@@ -942,31 +1081,24 @@ namespace AssetStudioCLI.Options
sb.AppendLine($"# Input Path: \"{inputPath}\"");
switch (o_workMode.Value)
{
- case WorkMode.Info:
- sb.AppendLine($"# Export Asset Type(s): {string.Join(", ", o_exportAssetTypes.Value)}");
- 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.Export:
+ case WorkMode.ExportRaw:
+ case WorkMode.Dump:
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}");
- sb.AppendLine($"# Assebmly Path: \"{o_assemblyPath}\"");
- sb.AppendLine($"# Unity Version: \"{o_unityVersion}\"");
- break;
- default:
- sb.AppendLine($"# Output Path: \"{o_outputFolder}\"");
- sb.AppendLine($"# Export Asset Type(s): {string.Join(", ", o_exportAssetTypes.Value)}");
+ if (o_workMode.Value != WorkMode.Export)
+ {
+ sb.AppendLine($"# Load All Assets: {f_loadAllAssets}");
+ }
+ sb.AppendLine(ShowExportTypes());
sb.AppendLine($"# Asset Group Option: {o_groupAssetsBy}");
- sb.AppendLine($"# Export Image Format: {o_imageFormat}");
- sb.AppendLine($"# Export Audio Format: {o_audioFormat}");
- sb.AppendLine($"# [Arkingths] Sprite Mask Mode: {o_akSpriteMaskMode}");
- sb.AppendLine($"# [Arknights] Mask Resampler: {resamplerName}");
- sb.AppendLine($"# [Arknights] Mask Gamma Correction: {o_akAlphaMaskGamma.Value * 10:+#;-#;0}%");
+ if (o_workMode.Value == WorkMode.Export)
+ {
+ sb.AppendLine($"# Export Image Format: {o_imageFormat}");
+ sb.AppendLine($"# Export Audio Format: {o_audioFormat}");
+ 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] Add Aliases: {f_akAddAliases}");
sb.AppendLine($"# Log Level: {o_logLevel}");
@@ -975,7 +1107,36 @@ namespace AssetStudioCLI.Options
sb.AppendLine(ShowCurrentFilter());
sb.AppendLine($"# Assebmly Path: \"{o_assemblyPath}\"");
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;
}
sb.AppendLine("======");
diff --git a/AssetStudioCLI/Program.cs b/AssetStudioCLI/Program.cs
index a7d6f01..40de9d5 100644
--- a/AssetStudioCLI/Program.cs
+++ b/AssetStudioCLI/Program.cs
@@ -35,9 +35,9 @@ namespace AssetStudioCLI
if (Studio.LoadAssets())
{
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)
{
@@ -51,6 +51,9 @@ namespace AssetStudioCLI
case WorkMode.ExportLive2D:
Studio.ExportLive2D();
break;
+ case WorkMode.SplitObjects:
+ Studio.ExportSplitObjects();
+ break;
default:
Studio.ExportAssets();
break;
diff --git a/AssetStudioCLI/Studio.cs b/AssetStudioCLI/Studio.cs
index c12bb55..ecd6c8f 100644
--- a/AssetStudioCLI/Studio.cs
+++ b/AssetStudioCLI/Studio.cs
@@ -16,6 +16,7 @@ namespace AssetStudioCLI
public static AssetsManager assetsManager = new AssetsManager();
public static List exportableAssetsList = new List();
public static List loadedAssetsList = new List();
+ public static List gameObjectTree = new List();
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
private static Dictionary containers = new Dictionary();
@@ -33,8 +34,10 @@ namespace AssetStudioCLI
{
var isLoaded = false;
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);
if (assetsManager.assetsFileList.Count == 0)
{
@@ -53,6 +56,7 @@ namespace AssetStudioCLI
Logger.Info("Parse assets...");
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
+ var objectAssetItemDic = new Dictionary(objectCount);
Progress.Reset();
var i = 0;
@@ -61,6 +65,7 @@ namespace AssetStudioCLI
foreach (var asset in assetsFile.Objects)
{
var assetItem = new AssetItem(asset);
+ objectAssetItemDic.Add(asset, assetItem);
assetItem.UniqueID = "_#" + i;
var isExportable = false;
switch (asset)
@@ -80,6 +85,7 @@ namespace AssetStudioCLI
}
}
}
+ assetItem.Text = m_AssetBundle.m_Name;
break;
case ResourceManager m_ResourceManager:
foreach (var m_Container in m_ResourceManager.m_Container)
@@ -104,14 +110,7 @@ namespace AssetStudioCLI
if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath))
assetItem.FullSize = asset.byteSize + m_VideoClip.m_ExternalResources.m_Size;
assetItem.Text = m_VideoClip.m_Name;
- break;
- case Mesh _:
- case MovieTexture _:
- case TextAsset _:
- case Font _:
- case Sprite _:
- assetItem.Text = ((NamedObject)asset).m_Name;
- break;
+ break;
case Shader m_Shader:
assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
break;
@@ -125,15 +124,27 @@ namespace AssetStudioCLI
assetItem.Text = m_MonoBehaviour.m_Name;
}
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;
}
loadedAssetsList.Add(assetItem);
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);
}
@@ -161,6 +172,11 @@ namespace AssetStudioCLI
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 unityVer = assetsManager.assetsFileList[0].version;
long m_ObjectsCount;
@@ -183,6 +199,85 @@ namespace AssetStudioCLI
Logger.Info(log);
}
+ public static void BuildTreeStructure(Dictionary objectAssetItemDic)
+ {
+ Logger.Info("Building tree structure...");
+
+ var treeNodeDictionary = new Dictionary();
+ 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()
{
var exportableAssetsCountDict = new Dictionary();
@@ -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 filteredAssets = new List();
@@ -234,14 +342,14 @@ namespace AssetStudioCLI
switch(CLIOptions.filterBy)
{
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(
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByName.Value)}\"".Color(Ansi.BrightYellow)} in their Names."
);
break;
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(
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByContainer.Value)}\"".Color(Ansi.BrightYellow)} in their Containers."
@@ -256,8 +364,8 @@ namespace AssetStudioCLI
break;
case FilterBy.NameOrContainer:
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.Container.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.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)
);
Logger.Info(
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
@@ -266,8 +374,8 @@ namespace AssetStudioCLI
break;
case FilterBy.NameAndContainer:
filteredAssets = exportableAssetsList.FindAll(x =>
- CLIOptions.o_filterByName.Value.Any(y => x.Text.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) &&
- CLIOptions.o_filterByContainer.Value.Any(y => x.Container.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.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)
);
Logger.Info(
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
@@ -411,6 +519,101 @@ namespace AssetStudioCLI
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();
+ 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();
+ 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 gameObjects)
+ {
+ gameObjects.Add(node.gameObject);
+ foreach (GameObjectNode i in node.nodes)
+ {
+ CollectNode(i, gameObjects);
+ }
+ }
+
public static void ExportLive2D()
{
var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput");
diff --git a/AssetStudioFBXNative/CMakeLists.txt b/AssetStudioFBXNative/CMakeLists.txt
new file mode 100644
index 0000000..f90011d
--- /dev/null
+++ b/AssetStudioFBXNative/CMakeLists.txt
@@ -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)
\ No newline at end of file
diff --git a/AssetStudioFBXWrapper/AssetStudioFBXWrapper.csproj b/AssetStudioFBXWrapper/AssetStudioFBXWrapper.csproj
index 816445e..5c50fe8 100644
--- a/AssetStudioFBXWrapper/AssetStudioFBXWrapper.csproj
+++ b/AssetStudioFBXWrapper/AssetStudioFBXWrapper.csproj
@@ -3,7 +3,7 @@
net472;net6.0;net6.0-windows;net7.0;net7.0-windows
true
- 0.17.2.0
+ 1.0.0
Copyright © Perfare 2018-2022; Copyright © hozuki 2020
embedded
diff --git a/AssetStudioGUI/AboutForm.Designer.cs b/AssetStudioGUI/AboutForm.Designer.cs
index c54f55a..e2b5997 100644
--- a/AssetStudioGUI/AboutForm.Designer.cs
+++ b/AssetStudioGUI/AboutForm.Designer.cs
@@ -49,7 +49,7 @@
this.label7 = new System.Windows.Forms.Label();
this.modVersionLabel = 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.tabPage2 = new System.Windows.Forms.TabPage();
this.licenseRichTextBox = new System.Windows.Forms.RichTextBox();
@@ -116,8 +116,7 @@
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(347, 46);
this.label2.TabIndex = 0;
- this.label2.Text = "AssetStudio is a tool for exploring, extracting, and exporting assets and asset b" +
- "undles.";
+ this.label2.Text = "ArknightsStudio is a modified version of AssetStudio designed for Arknights.";
this.label2.UseCompatibleTextRendering = true;
//
// textBox2
@@ -164,7 +163,7 @@
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, 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.label17, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.gitPerfareLinkLabel, 2, 0);
@@ -194,7 +193,7 @@
//
this.label17.AutoSize = true;
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.Size = new System.Drawing.Size(110, 13);
this.label17.TabIndex = 10;
@@ -204,7 +203,7 @@
//
this.gitPerfareLinkLabel.AutoSize = true;
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.Size = new System.Drawing.Size(67, 13);
this.gitPerfareLinkLabel.TabIndex = 11;
@@ -226,7 +225,7 @@
//
this.label19.AutoSize = true;
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.Size = new System.Drawing.Size(113, 13);
this.label19.TabIndex = 13;
@@ -236,7 +235,7 @@
//
this.gitAelurumLinkLabel.AutoSize = true;
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.Size = new System.Drawing.Size(67, 13);
this.gitAelurumLinkLabel.TabIndex = 14;
@@ -250,13 +249,13 @@
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, 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.productNamelabel, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.label7, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.modVersionLabel, 1, 1);
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.Location = new System.Drawing.Point(6, 80);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
@@ -285,11 +284,11 @@
//
this.productNamelabel.AutoSize = true;
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.Size = new System.Drawing.Size(103, 13);
+ this.productNamelabel.Size = new System.Drawing.Size(100, 13);
this.productNamelabel.TabIndex = 1;
- this.productNamelabel.Text = "AssetStudioModGUI";
+ this.productNamelabel.Text = "ArknightsStudioGUI";
//
// label7
//
@@ -297,16 +296,16 @@
this.label7.BackColor = System.Drawing.Color.Transparent;
this.label7.Location = new System.Drawing.Point(5, 20);
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.Text = "Mod version:";
+ this.label7.Text = "Version:";
//
// modVersionLabel
//
this.modVersionLabel.AutoSize = true;
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.Location = new System.Drawing.Point(102, 20);
+ this.modVersionLabel.Location = new System.Drawing.Point(101, 20);
this.modVersionLabel.Name = "modVersionLabel";
this.modVersionLabel.Size = new System.Drawing.Size(52, 13);
this.modVersionLabel.TabIndex = 3;
@@ -323,21 +322,21 @@
this.label4.TabIndex = 4;
this.label4.Text = "Based on:";
//
- // label8
+ // basedOnLabel
//
- this.label8.AutoSize = true;
- this.label8.BackColor = System.Drawing.Color.Transparent;
- this.label8.Location = new System.Drawing.Point(102, 38);
- this.label8.Name = "label8";
- this.label8.Size = new System.Drawing.Size(108, 13);
- this.label8.TabIndex = 5;
- this.label8.Text = "AssetStudio v0.16.47";
+ this.basedOnLabel.AutoSize = true;
+ this.basedOnLabel.BackColor = System.Drawing.Color.Transparent;
+ this.basedOnLabel.Location = new System.Drawing.Point(101, 38);
+ this.basedOnLabel.Name = "basedOnLabel";
+ this.basedOnLabel.Size = new System.Drawing.Size(123, 13);
+ this.basedOnLabel.TabIndex = 5;
+ this.basedOnLabel.Text = "AssetStudioMod v0.17.0";
//
// checkUpdatesLinkLabel
//
this.checkUpdatesLinkLabel.AutoSize = true;
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.Size = new System.Drawing.Size(96, 13);
this.checkUpdatesLinkLabel.TabIndex = 6;
@@ -391,7 +390,7 @@
this.productTitleLabel.Name = "productTitleLabel";
this.productTitleLabel.Size = new System.Drawing.Size(384, 30);
this.productTitleLabel.TabIndex = 1;
- this.productTitleLabel.Text = "AssetStudioModGUI";
+ this.productTitleLabel.Text = "ArknightsStudioGUI";
this.productTitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// CloseButton
@@ -492,7 +491,7 @@
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label modVersionLabel;
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.RichTextBox licenseRichTextBox;
private System.Windows.Forms.TextBox textBox2;
diff --git a/AssetStudioGUI/AboutForm.cs b/AssetStudioGUI/AboutForm.cs
index 307a60e..d3467e5 100644
--- a/AssetStudioGUI/AboutForm.cs
+++ b/AssetStudioGUI/AboutForm.cs
@@ -17,6 +17,7 @@ namespace AssetStudioGUI
productVersionLabel.Text = $"v{Application.ProductVersion} [{arch}]";
productNamelabel.Text = productName;
modVersionLabel.Text = Application.ProductVersion;
+ basedOnLabel.Text = "AssetStudioMod v0.17.3";
licenseRichTextBox.Text = GetLicenseText();
}
@@ -41,7 +42,7 @@ namespace AssetStudioGUI
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
};
diff --git a/AssetStudioGUI/AssetStudioGUI.csproj b/AssetStudioGUI/AssetStudioGUI.csproj
index 9ea2e5d..6436eac 100644
--- a/AssetStudioGUI/AssetStudioGUI.csproj
+++ b/AssetStudioGUI/AssetStudioGUI.csproj
@@ -5,9 +5,9 @@
net472;net6.0-windows;net7.0-windows
true
Resources\as.ico
- AssetStudioMod by aelurum
- AssetStudioModGUI
- 0.17.2.0
+ ArknightsStudio by aelurum
+ ArknightsStudioGUI
+ 1.0.0
Copyright © Perfare 2018-2022; Copyright © aelurum 2021-2023
embedded
diff --git a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs
index 7c339d3..0653839 100644
--- a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs
+++ b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs
@@ -293,7 +293,7 @@
this.akTitleMenuItem.Name = "akTitleMenuItem";
this.akTitleMenuItem.ShowShortcutKeys = false;
this.akTitleMenuItem.Size = new System.Drawing.Size(265, 22);
- this.akTitleMenuItem.Text = "Arknighs";
+ this.akTitleMenuItem.Text = "Arknights";
//
// akFixFaceSpriteNamesToolStripMenuItem
//
@@ -302,7 +302,7 @@
this.akFixFaceSpriteNamesToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.akFixFaceSpriteNamesToolStripMenuItem.Name = "akFixFaceSpriteNamesToolStripMenuItem";
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.CheckedChanged += new System.EventHandler(this.akFixFaceSpriteNamesToolStripMenuItem_Check);
//
diff --git a/AssetStudioGUI/ExportOptions.Designer.cs b/AssetStudioGUI/ExportOptions.Designer.cs
index b068685..3bb6da3 100644
--- a/AssetStudioGUI/ExportOptions.Designer.cs
+++ b/AssetStudioGUI/ExportOptions.Designer.cs
@@ -512,9 +512,9 @@
this.akResamplerLabel.AutoSize = true;
this.akResamplerLabel.Location = new System.Drawing.Point(6, 21);
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.Text = "Alpha mask resampler:";
+ this.akResamplerLabel.Text = "Alpha texture resampler:";
this.exportUvsTooltip.SetToolTip(this.akResamplerLabel, "Only affects exported images");
//
// akResamplerComboBox
@@ -528,9 +528,9 @@
"Mitchell-Netravali",
"Spline",
"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.Size = new System.Drawing.Size(169, 21);
+ this.akResamplerComboBox.Size = new System.Drawing.Size(162, 21);
this.akResamplerComboBox.TabIndex = 4;
this.exportUvsTooltip.SetToolTip(this.akResamplerComboBox, "Only affects exported images");
//
@@ -549,7 +549,7 @@
this.akSpritesAlphaGroupBox.Size = new System.Drawing.Size(300, 178);
this.akSpritesAlphaGroupBox.TabIndex = 12;
this.akSpritesAlphaGroupBox.TabStop = false;
- this.akSpritesAlphaGroupBox.Text = "Sprites: Alpha Mask [Arknights]";
+ this.akSpritesAlphaGroupBox.Text = "Sprites: Alpha Texture [Arknights]";
//
// akGammaNoteLabel
//
@@ -567,9 +567,9 @@
this.akResamplerDescLabel.ForeColor = System.Drawing.SystemColors.GrayText;
this.akResamplerDescLabel.Location = new System.Drawing.Point(6, 43);
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.Text = "Alpha mask upscale method for 2048x2048 sprites";
+ this.akResamplerDescLabel.Text = "Alpha texture upscale method for 2048x2048 sprites";
//
// akResizedOnlyCheckBox
//
@@ -597,9 +597,9 @@
this.akGammaLabel.AutoSize = true;
this.akGammaLabel.Location = new System.Drawing.Point(6, 86);
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.Text = "Alpha mask gamma:";
+ this.akGammaLabel.Text = "Shadow gamma:";
//
// akAlphaMaskGammaTrackBar
//
@@ -627,9 +627,9 @@
this.akAddAliasesCheckBox.AutoSize = true;
this.akAddAliasesCheckBox.Location = new System.Drawing.Point(6, 28);
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.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;
//
// ExportOptions
diff --git a/AssetStudioUtility/AssemblyLoader.cs b/AssetStudioUtility/AssemblyLoader.cs
index 021b713..d2a7d0a 100644
--- a/AssetStudioUtility/AssemblyLoader.cs
+++ b/AssetStudioUtility/AssemblyLoader.cs
@@ -33,7 +33,12 @@ namespace AssetStudio
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);
if (typeDef == null && assemblyName == "UnityEngine.dll")
diff --git a/AssetStudioUtility/AssetStudioUtility.csproj b/AssetStudioUtility/AssetStudioUtility.csproj
index 5fc9266..2c8a47e 100644
--- a/AssetStudioUtility/AssetStudioUtility.csproj
+++ b/AssetStudioUtility/AssetStudioUtility.csproj
@@ -2,7 +2,7 @@
net472;net6.0;net6.0-windows;net7.0;net7.0-windows
- 0.17.2.0
+ 1.0.0
Copyright © Perfare 2018-2022; Copyright © aelurum 2023
embedded
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d280287..9b31626 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
# 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]
- [GUI] Improved Scene Hierarchy tab
- Added "Related assets" item to the context menu (https://github.com/aelurum/AssetStudio/issues/7)
diff --git a/README.md b/README.md
index d345c5d..ccbad86 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,7 @@ You can read CLI readme [here](https://github.com/aelurum/AssetStudio/blob/Asset
```
AssetStudioModCLI -m info
```
-- Export assets of all supported types
+- Export assets of all supported for export types
```
AssetStudioModCLI
```
@@ -89,12 +89,22 @@ AssetStudioModCLI -g type
```
AssetStudioModCLI -o