Compare commits
190 Commits
v0.16.8.1
...
ArknightsS
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87151e065b | ||
|
|
f3a748ba6b | ||
|
|
d07fc6d6f5 | ||
|
|
ee2976aaf1 | ||
|
|
f144037bc0 | ||
|
|
0e097bda04 | ||
|
|
9686eee3b7 | ||
|
|
b6318e6d9b | ||
|
|
e0d90d1b1e | ||
|
|
dd727758a8 | ||
|
|
d44ed315e3 | ||
|
|
a00c857ac3 | ||
|
|
5333757843 | ||
|
|
4747687bec | ||
|
|
5c2ac1a5e8 | ||
|
|
e2eae53ac0 | ||
|
|
87347e8b60 | ||
|
|
0fdbddea55 | ||
|
|
823190abb7 | ||
|
|
60aef1b8ed | ||
|
|
f82a73f018 | ||
|
|
d42a1879ab | ||
|
|
632e5f8d08 | ||
|
|
51d259464b | ||
|
|
efd06648ad | ||
|
|
b27482e22b | ||
|
|
d572bd0e64 | ||
|
|
e415740373 | ||
|
|
e30b9e9e89 | ||
|
|
45bf9251c9 | ||
|
|
9632e88115 | ||
|
|
bb19dd5019 | ||
|
|
75ebe67713 | ||
|
|
ed7b0a2415 | ||
|
|
22ab5c0633 | ||
|
|
a2bc935850 | ||
|
|
b6c6ceba1c | ||
|
|
7c0a6375b1 | ||
|
|
5c489c5f83 | ||
|
|
cb84c137e5 | ||
|
|
25c611fb9e | ||
|
|
6d3875cb2c | ||
|
|
be4ced77ea | ||
|
|
2bd762e8f4 | ||
|
|
a926644ff6 | ||
|
|
a4cdff5934 | ||
|
|
2e10e627b0 | ||
|
|
e216abd6be | ||
|
|
93c7e617d8 | ||
|
|
000916913e | ||
|
|
28f9744497 | ||
|
|
c3f99216b6 | ||
|
|
19c4835ea3 | ||
|
|
6b321da695 | ||
|
|
7cca301f7a | ||
|
|
5ac597c935 | ||
|
|
e90af43459 | ||
|
|
171962e61f | ||
|
|
c8a21838c9 | ||
|
|
cf67815d53 | ||
|
|
381a7d89ae | ||
|
|
572e3bf0d6 | ||
|
|
3d7d51b54f | ||
|
|
abbd27fde7 | ||
|
|
94c8b355fe | ||
|
|
4e41caf203 | ||
|
|
74a8555514 | ||
|
|
e1d883adf6 | ||
|
|
9784df0e16 | ||
|
|
4d919a2bfe | ||
|
|
6701f467b7 | ||
|
|
50f5da5554 | ||
|
|
2b6dcca9c8 | ||
|
|
0bdcb89b08 | ||
|
|
dcd7b98229 | ||
|
|
007e5c7e4d | ||
|
|
63564d5fff | ||
|
|
aea6cbc97f | ||
|
|
6d41693b85 | ||
|
|
5695afae7b | ||
|
|
bb9ea7d86b | ||
|
|
547659e151 | ||
|
|
2f8f57c1a6 | ||
|
|
b7d5d73f23 | ||
|
|
f0c237473c | ||
|
|
09947fd14f | ||
|
|
da216dace8 | ||
|
|
c7356875f9 | ||
|
|
02e46eaa0d | ||
|
|
b0bf5e0cfd | ||
|
|
11b9ca37da | ||
|
|
5944dd8c58 | ||
|
|
1c67e39504 | ||
|
|
2d81007556 | ||
|
|
4bae98813b | ||
|
|
90ec395b2a | ||
|
|
af3684bab8 | ||
|
|
1da51ac95b | ||
|
|
9e14f1ef00 | ||
|
|
4edadb19f8 | ||
|
|
44a1240f5f | ||
|
|
01957a9443 | ||
|
|
ad1b3b4911 | ||
|
|
0925751776 | ||
|
|
b59ba3ba94 | ||
|
|
67898c72ca | ||
|
|
0425423ca9 | ||
|
|
16a7107d4e | ||
|
|
10b7e84ffb | ||
|
|
679e7041a6 | ||
|
|
629c6248a4 | ||
|
|
7674081df7 | ||
|
|
fb574064c9 | ||
|
|
c52940abc4 | ||
|
|
5c662d64e4 | ||
|
|
b9cf95616b | ||
|
|
39490d4e03 | ||
|
|
a96d1a5d5d | ||
|
|
568daafc7f | ||
|
|
2a2216e2bf | ||
|
|
dfbe46e1e5 | ||
|
|
6a9aad510c | ||
|
|
fd21cafd29 | ||
|
|
ea09a8de64 | ||
|
|
7fa5b4f355 | ||
|
|
c22d92009a | ||
|
|
53f3e8232a | ||
|
|
2fe57a1c5d | ||
|
|
ded2dcd54e | ||
|
|
8ae3df6197 | ||
|
|
64d9718c34 | ||
|
|
220004c976 | ||
|
|
a324366be9 | ||
|
|
06b4ae9ffe | ||
|
|
77b056de5e | ||
|
|
344edb722f | ||
|
|
98c4d0c3ab | ||
|
|
23ac590648 | ||
|
|
54445475a3 | ||
|
|
7299bcba6d | ||
|
|
5487ff4e60 | ||
|
|
b3621a75b0 | ||
|
|
8b048b9e1e | ||
|
|
41a79f485f | ||
|
|
a060a392e7 | ||
|
|
0798af7c5c | ||
|
|
8ebfa16e19 | ||
|
|
d158e864b5 | ||
|
|
b70b5196e3 | ||
|
|
4f88841026 | ||
|
|
dc9429feac | ||
|
|
a3c16ed3d6 | ||
|
|
5b83eebdda | ||
|
|
1fcf7a4364 | ||
|
|
973d50ce8b | ||
|
|
50485a9bd3 | ||
|
|
dbb3d3fef7 | ||
|
|
e1cfff63c3 | ||
|
|
44514a4e10 | ||
|
|
b1205808e2 | ||
|
|
7d3a4a10fc | ||
|
|
b909857820 | ||
|
|
b674e66407 | ||
|
|
d7dcd3f405 | ||
|
|
44145e0b9c | ||
|
|
d4e21f824c | ||
|
|
e7a4604a65 | ||
|
|
74f2c3190b | ||
|
|
8d193a63cd | ||
|
|
e61a317185 | ||
|
|
f67965b1dd | ||
|
|
07a81d9bfe | ||
|
|
95fd1823c8 | ||
|
|
d25451d5b9 | ||
|
|
0e1a886e0b | ||
|
|
97b5f51f3a | ||
|
|
7295feda72 | ||
|
|
fe95c91759 | ||
|
|
d220315d9b | ||
|
|
a94caa5e34 | ||
|
|
3660b4ed67 | ||
|
|
3370f93037 | ||
|
|
80653711cd | ||
|
|
f0b23bbfe7 | ||
|
|
88c5804586 | ||
|
|
e501940f03 | ||
|
|
d4060cde6d | ||
|
|
582a779441 | ||
|
|
5fa4934787 | ||
|
|
18277fbea8 |
57
.github/workflows/build.yml
vendored
Normal file
57
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: AssetStudioBuild
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: microsoft/setup-msbuild@v1.1
|
||||
|
||||
- name: Download FBX SDK
|
||||
run: |
|
||||
md fbx
|
||||
cd fbx
|
||||
Invoke-WebRequest "https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/2020-2-1/fbx202021_fbxsdk_vs2019_win.exe" -OutFile "fbxsdk.exe"
|
||||
Start-Process -FilePath "fbxsdk.exe" /S -Wait
|
||||
Invoke-WebRequest "https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/2020-2-1/fbx202021_fbxsdk_vs2019_pdbs.exe" -OutFile "fbxpdb.exe"
|
||||
Start-Process -FilePath "fbxpdb.exe" /S -Wait
|
||||
cd ..
|
||||
|
||||
- name: Nuget Restore
|
||||
run: nuget restore
|
||||
|
||||
- name: Build .Net472
|
||||
run: msbuild /p:Configuration=Release /p:TargetFramework=net472 /verbosity:minimal
|
||||
|
||||
- name: Build .Net5
|
||||
run: msbuild /t:AssetStudioGUI:publish /p:Configuration=Release /p:TargetFramework=net5.0-windows /p:SelfContained=false /verbosity:minimal
|
||||
|
||||
- name: Build .Net6
|
||||
run: msbuild /t:AssetStudioGUI:publish /p:Configuration=Release /p:TargetFramework=net6.0-windows /p:SelfContained=false /verbosity:minimal
|
||||
|
||||
- name: Upload .Net472 Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: AssetStudio.net472
|
||||
path: AssetStudioGUI/bin/Release/net472
|
||||
|
||||
- name: Upload .Net5 Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: AssetStudio.net5
|
||||
path: AssetStudioGUI/bin/Release/net5.0-windows/publish
|
||||
|
||||
- name: Upload .Net6 Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: AssetStudio.net6
|
||||
path: AssetStudioGUI/bin/Release/net6.0-windows/publish
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -35,6 +35,9 @@ bld/
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# Launch Settings
|
||||
*launchSettings.json
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Version>0.16.8.1</Version>
|
||||
<AssemblyVersion>0.16.8.1</AssemblyVersion>
|
||||
<FileVersion>0.16.8.1</FileVersion>
|
||||
<Copyright>Copyright © Perfare 2020-2021; Copyright © hozuki 2020</Copyright>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net472|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<Version>1.2.0</Version>
|
||||
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -4,33 +4,29 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#if NETFRAMEWORK
|
||||
namespace AssetStudio.PInvoke
|
||||
{
|
||||
public static class DllLoader
|
||||
{
|
||||
|
||||
public static void PreloadDll(string dllName)
|
||||
{
|
||||
var dllDir = GetDirectedDllDirectory();
|
||||
var localPath = Process.GetCurrentProcess().MainModule.FileName;
|
||||
var localDir = Path.GetDirectoryName(localPath);
|
||||
|
||||
// Not using OperatingSystem.Platform.
|
||||
// See: https://www.mono-project.com/docs/faq/technical/#how-to-detect-the-execution-platform
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
Win32.LoadDll(dllDir, dllName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Posix.LoadDll(dllDir, dllName);
|
||||
Win32.LoadDll(GetDirectedDllDirectory(localDir), dllName);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetDirectedDllDirectory()
|
||||
private static string GetDirectedDllDirectory(string localDir)
|
||||
{
|
||||
var localPath = Process.GetCurrentProcess().MainModule.FileName;
|
||||
var localDir = Path.GetDirectoryName(localPath);
|
||||
|
||||
var subDir = Environment.Is64BitProcess ? "x64" : "x86";
|
||||
var win32Path = Path.Combine("runtimes", "win-x86", "native");
|
||||
var win64Path = Path.Combine("runtimes", "win-x64", "native");
|
||||
var subDir = Environment.Is64BitProcess ? win64Path : win32Path;
|
||||
|
||||
var directedDllDir = Path.Combine(localDir, subDir);
|
||||
|
||||
@@ -64,61 +60,7 @@ namespace AssetStudio.PInvoke
|
||||
|
||||
private const uint LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x1000;
|
||||
private const uint LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x100;
|
||||
|
||||
}
|
||||
|
||||
private static class Posix
|
||||
{
|
||||
|
||||
internal static void LoadDll(string dllDir, string dllName)
|
||||
{
|
||||
string dllExtension;
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
dllExtension = ".so";
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
dllExtension = ".dylib";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
var dllFileName = $"lib{dllName}{dllExtension}";
|
||||
var directedDllPath = Path.Combine(dllDir, dllFileName);
|
||||
|
||||
const int ldFlags = RTLD_NOW | RTLD_GLOBAL;
|
||||
var hLibrary = DlOpen(directedDllPath, ldFlags);
|
||||
|
||||
if (hLibrary == IntPtr.Zero)
|
||||
{
|
||||
var pErrStr = DlError();
|
||||
// `PtrToStringAnsi` always uses the specific constructor of `String` (see dotnet/core#2325),
|
||||
// which in turn interprets the byte sequence with system default codepage. On OSX and Linux
|
||||
// the codepage is UTF-8 so the error message should be handled correctly.
|
||||
var errorMessage = Marshal.PtrToStringAnsi(pErrStr);
|
||||
|
||||
throw new DllNotFoundException(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
// OSX and most Linux OS use LP64 so `int` is still 32-bit even on 64-bit platforms.
|
||||
// void *dlopen(const char *filename, int flag);
|
||||
[DllImport("libdl", EntryPoint = "dlopen")]
|
||||
private static extern IntPtr DlOpen([MarshalAs(UnmanagedType.LPStr)] string fileName, int flags);
|
||||
|
||||
// char *dlerror(void);
|
||||
[DllImport("libdl", EntryPoint = "dlerror")]
|
||||
private static extern IntPtr DlError();
|
||||
|
||||
private const int RTLD_LAZY = 0x1;
|
||||
private const int RTLD_NOW = 0x2;
|
||||
private const int RTLD_GLOBAL = 0x100;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31410.357
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.33414.496
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{422FEC21-EF60-4F29-AA56-95DFDA23C913}"
|
||||
EndProject
|
||||
@@ -25,6 +25,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBXNative", "Ass
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Texture2DDecoderNative", "Texture2DDecoderNative\Texture2DDecoderNative.vcxproj", "{29356642-C46E-4144-83D8-22DC09D0D7FD}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioCLI", "AssetStudioCLI\AssetStudioCLI.csproj", "{34B6329B-0E73-45AC-B8CC-015F119F63DC}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913} = {422FEC21-EF60-4F29-AA56-95DFDA23C913}
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF} = {65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -131,6 +137,18 @@ Global
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x64.Build.0 = Release|x64
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x86.ActiveCfg = Release|Win32
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x86.Build.0 = Release|Win32
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|x64.Build.0 = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
|
||||
<Version>0.16.8.1</Version>
|
||||
<AssemblyVersion>0.16.8.1</AssemblyVersion>
|
||||
<FileVersion>0.16.8.1</FileVersion>
|
||||
<Copyright>Copyright © Perfare 2018-2021</Copyright>
|
||||
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
||||
<Version>1.2.0</Version>
|
||||
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2025</Copyright>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net472|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
||||
<PackageReference Include="System.Memory" Version="4.5.5" />
|
||||
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using static AssetStudio.ImportHelper;
|
||||
@@ -11,27 +12,97 @@ namespace AssetStudio
|
||||
{
|
||||
public string SpecifyUnityVersion;
|
||||
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
|
||||
private HashSet<ClassIDType> filteredAssetTypesList = new HashSet<ClassIDType>();
|
||||
|
||||
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
||||
internal Dictionary<string, BinaryReader> resourceFileReaders = new Dictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private List<string> importFiles = new List<string>();
|
||||
private HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public void LoadFiles(params string[] files)
|
||||
public void SetAssetFilter(params ClassIDType[] classIDTypes)
|
||||
{
|
||||
var path = Path.GetDirectoryName(files[0]);
|
||||
MergeSplitAssets(path);
|
||||
var toReadFile = ProcessingSplitFiles(files.ToList());
|
||||
Load(toReadFile);
|
||||
if (filteredAssetTypesList.Count == 0)
|
||||
{
|
||||
filteredAssetTypesList.UnionWith(new HashSet<ClassIDType>
|
||||
{
|
||||
ClassIDType.AssetBundle,
|
||||
ClassIDType.ResourceManager,
|
||||
});
|
||||
}
|
||||
|
||||
public void LoadFolder(string path)
|
||||
if (classIDTypes.Contains(ClassIDType.MonoBehaviour))
|
||||
{
|
||||
MergeSplitAssets(path, true);
|
||||
var files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).ToList();
|
||||
var toReadFile = ProcessingSplitFiles(files);
|
||||
filteredAssetTypesList.Add(ClassIDType.MonoScript);
|
||||
}
|
||||
if (classIDTypes.Contains(ClassIDType.Sprite) || classIDTypes.Contains(ClassIDType.AkPortraitSprite))
|
||||
{
|
||||
filteredAssetTypesList.UnionWith(new HashSet<ClassIDType>
|
||||
{
|
||||
ClassIDType.Texture2D,
|
||||
ClassIDType.SpriteAtlas,
|
||||
ClassIDType.MonoBehaviour,
|
||||
ClassIDType.MonoScript
|
||||
});
|
||||
}
|
||||
|
||||
filteredAssetTypesList.UnionWith(classIDTypes);
|
||||
}
|
||||
|
||||
public void SetAssetFilter(List<ClassIDType> classIDTypeList)
|
||||
{
|
||||
SetAssetFilter(classIDTypeList.ToArray());
|
||||
}
|
||||
|
||||
public void LoadFilesAndFolders(params string[] path)
|
||||
{
|
||||
List<string> pathList = new List<string>();
|
||||
pathList.AddRange(path);
|
||||
LoadFilesAndFolders(out _, pathList);
|
||||
}
|
||||
|
||||
public void LoadFilesAndFolders(out string parentPath, params string[] path)
|
||||
{
|
||||
List<string> pathList = new List<string>();
|
||||
pathList.AddRange(path);
|
||||
LoadFilesAndFolders(out parentPath, pathList);
|
||||
}
|
||||
|
||||
public void LoadFilesAndFolders(out string parentPath, List<string> pathList)
|
||||
{
|
||||
List<string> fileList = new List<string>();
|
||||
bool filesInPath = false;
|
||||
parentPath = "";
|
||||
foreach (var path in pathList)
|
||||
{
|
||||
var fullPath = Path.GetFullPath(path);
|
||||
if (Directory.Exists(fullPath))
|
||||
{
|
||||
var parent = Directory.GetParent(fullPath).FullName;
|
||||
if (!filesInPath && (parentPath == "" || parentPath.Length > parent.Length))
|
||||
{
|
||||
parentPath = parent;
|
||||
}
|
||||
MergeSplitAssets(fullPath, true);
|
||||
fileList.AddRange(Directory.GetFiles(fullPath, "*.*", SearchOption.AllDirectories));
|
||||
}
|
||||
else if (File.Exists(fullPath))
|
||||
{
|
||||
parentPath = Path.GetDirectoryName(fullPath);
|
||||
fileList.Add(fullPath);
|
||||
filesInPath = true;
|
||||
}
|
||||
}
|
||||
if (filesInPath)
|
||||
{
|
||||
MergeSplitAssets(parentPath);
|
||||
}
|
||||
var toReadFile = ProcessingSplitFiles(fileList);
|
||||
fileList.Clear();
|
||||
pathList.Clear();
|
||||
|
||||
Load(toReadFile);
|
||||
}
|
||||
|
||||
@@ -53,6 +124,7 @@ namespace AssetStudio
|
||||
|
||||
importFiles.Clear();
|
||||
importFilesHash.Clear();
|
||||
noexistFiles.Clear();
|
||||
assetsFileListHash.Clear();
|
||||
|
||||
ReadAssets();
|
||||
@@ -67,7 +139,7 @@ namespace AssetStudio
|
||||
|
||||
private void LoadFile(FileReader reader)
|
||||
{
|
||||
switch (reader.FileType)
|
||||
switch (reader?.FileType)
|
||||
{
|
||||
case FileType.AssetsFile:
|
||||
LoadAssetsFile(reader);
|
||||
@@ -84,6 +156,9 @@ namespace AssetStudio
|
||||
case FileType.BrotliFile:
|
||||
LoadFile(DecompressBrotli(reader));
|
||||
break;
|
||||
case FileType.ZipFile:
|
||||
LoadZipFile(reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +166,7 @@ namespace AssetStudio
|
||||
{
|
||||
if (!assetsFileListHash.Contains(reader.FileName))
|
||||
{
|
||||
Logger.Info($"Loading {reader.FileName}");
|
||||
Logger.Info($"Loading {reader.FullPath}");
|
||||
try
|
||||
{
|
||||
var assetsFile = new SerializedFile(reader, this);
|
||||
@@ -106,6 +181,8 @@ namespace AssetStudio
|
||||
if (!importFilesHash.Contains(sharedFileName))
|
||||
{
|
||||
var sharedFilePath = Path.Combine(Path.GetDirectoryName(reader.FullPath), sharedFileName);
|
||||
if (!noexistFiles.Contains(sharedFilePath))
|
||||
{
|
||||
if (!File.Exists(sharedFilePath))
|
||||
{
|
||||
var findFiles = Directory.GetFiles(Path.GetDirectoryName(reader.FullPath), sharedFileName, SearchOption.AllDirectories);
|
||||
@@ -114,23 +191,33 @@ namespace AssetStudio
|
||||
sharedFilePath = findFiles[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(sharedFilePath))
|
||||
{
|
||||
importFiles.Add(sharedFilePath);
|
||||
importFilesHash.Add(sharedFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
noexistFiles.Add(sharedFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NotSupportedException e)
|
||||
{
|
||||
Logger.Error(e.Message);
|
||||
reader.Dispose();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Error while reading assets file {reader.FileName}", e);
|
||||
Logger.Warning($"Error while reading assets file {reader.FullPath}\r\n{e}");
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info($"Skipping {reader.FullPath}");
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -143,7 +230,7 @@ namespace AssetStudio
|
||||
{
|
||||
var assetsFile = new SerializedFile(reader, this);
|
||||
assetsFile.originalPath = originalPath;
|
||||
if (!string.IsNullOrEmpty(unityVersion) && assetsFile.header.m_Version < SerializedFileFormatVersion.kUnknown_7)
|
||||
if (!string.IsNullOrEmpty(unityVersion) && assetsFile.header.m_Version < SerializedFileFormatVersion.Unknown_7)
|
||||
{
|
||||
assetsFile.SetVersion(unityVersion);
|
||||
}
|
||||
@@ -151,20 +238,27 @@ namespace AssetStudio
|
||||
assetsFileList.Add(assetsFile);
|
||||
assetsFileListHash.Add(assetsFile.fileName);
|
||||
}
|
||||
catch (NotSupportedException e)
|
||||
{
|
||||
Logger.Error(e.Message);
|
||||
resourceFileReaders.Add(reader.FileName, reader);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Error while reading assets file {reader.FileName} from {Path.GetFileName(originalPath)}", e);
|
||||
Logger.Warning($"Error while reading assets file {reader.FullPath} from {Path.GetFileName(originalPath)}\r\n{e}");
|
||||
resourceFileReaders.Add(reader.FileName, reader);
|
||||
}
|
||||
}
|
||||
else
|
||||
Logger.Info($"Skipping {originalPath} ({reader.FileName})");
|
||||
}
|
||||
|
||||
private void LoadBundleFile(FileReader reader, string originalPath = null)
|
||||
{
|
||||
Logger.Info("Loading " + reader.FileName);
|
||||
Logger.Info("Loading " + reader.FullPath);
|
||||
try
|
||||
{
|
||||
var bundleFile = new BundleFile(reader);
|
||||
var bundleFile = new BundleFile(reader, SpecifyUnityVersion);
|
||||
foreach (var file in bundleFile.fileList)
|
||||
{
|
||||
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
|
||||
@@ -179,14 +273,18 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NotSupportedException e)
|
||||
{
|
||||
Logger.Error(e.Message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var str = $"Error while reading bundle file {reader.FileName}";
|
||||
var str = $"Error while reading bundle file {reader.FullPath}";
|
||||
if (originalPath != null)
|
||||
{
|
||||
str += $" from {Path.GetFileName(originalPath)}";
|
||||
}
|
||||
Logger.Error(str, e);
|
||||
Logger.Warning($"{str}\r\n{e}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -196,7 +294,7 @@ namespace AssetStudio
|
||||
|
||||
private void LoadWebFile(FileReader reader)
|
||||
{
|
||||
Logger.Info("Loading " + reader.FileName);
|
||||
Logger.Info("Loading " + reader.FullPath);
|
||||
try
|
||||
{
|
||||
var webFile = new WebFile(reader);
|
||||
@@ -223,7 +321,111 @@ namespace AssetStudio
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Error while reading web file {reader.FileName}", e);
|
||||
Logger.Error($"Error while reading web file {reader.FullPath}", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadZipFile(FileReader reader)
|
||||
{
|
||||
Logger.Info("Reading " + reader.FileName);
|
||||
try
|
||||
{
|
||||
using (ZipArchive archive = new ZipArchive(reader.BaseStream, ZipArchiveMode.Read))
|
||||
{
|
||||
List<string> splitFiles = new List<string>();
|
||||
// register all files before parsing the assets so that the external references can be found
|
||||
// and find split files
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
{
|
||||
if (entry.Name.Contains(".split"))
|
||||
{
|
||||
string baseName = Path.GetFileNameWithoutExtension(entry.Name);
|
||||
string basePath = Path.Combine(Path.GetDirectoryName(entry.FullName), baseName);
|
||||
if (!splitFiles.Contains(basePath))
|
||||
{
|
||||
splitFiles.Add(basePath);
|
||||
importFilesHash.Add(baseName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
importFilesHash.Add(entry.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// merge split files and load the result
|
||||
foreach (string basePath in splitFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
Stream splitStream = new MemoryStream();
|
||||
int i = 0;
|
||||
while (true)
|
||||
{
|
||||
string path = $"{basePath}.split{i++}";
|
||||
ZipArchiveEntry entry = archive.GetEntry(path);
|
||||
if (entry == null)
|
||||
break;
|
||||
using (Stream entryStream = entry.Open())
|
||||
{
|
||||
entryStream.CopyTo(splitStream);
|
||||
}
|
||||
}
|
||||
splitStream.Seek(0, SeekOrigin.Begin);
|
||||
FileReader entryReader = new FileReader(basePath, splitStream);
|
||||
LoadFile(entryReader);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warning($"Error while reading zip split file {basePath}\r\n{e}");
|
||||
}
|
||||
}
|
||||
|
||||
// load all entries
|
||||
var progressCount = archive.Entries.Count;
|
||||
int k = 0;
|
||||
Progress.Reset();
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
{
|
||||
try
|
||||
{
|
||||
string dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), reader.FileName, entry.FullName);
|
||||
// create a new stream
|
||||
// - to store the deflated stream in
|
||||
// - to keep the data for later extraction
|
||||
Stream streamReader = new MemoryStream();
|
||||
using (Stream entryStream = entry.Open())
|
||||
{
|
||||
entryStream.CopyTo(streamReader);
|
||||
}
|
||||
streamReader.Position = 0;
|
||||
|
||||
FileReader entryReader = new FileReader(dummyPath, streamReader);
|
||||
LoadFile(entryReader);
|
||||
if (entryReader.FileType == FileType.ResourceFile)
|
||||
{
|
||||
entryReader.Position = 0;
|
||||
if (!resourceFileReaders.ContainsKey(entry.Name))
|
||||
{
|
||||
resourceFileReaders.Add(entry.Name, entryReader);
|
||||
}
|
||||
}
|
||||
Progress.Report(++k, progressCount);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warning($"Error while reading zip entry {entry.FullName}\r\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Error while reading zip file {reader.FileName}", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -235,7 +437,7 @@ namespace AssetStudio
|
||||
{
|
||||
if (assetsFile.IsVersionStripped && string.IsNullOrEmpty(SpecifyUnityVersion))
|
||||
{
|
||||
throw new Exception("The Unity version has been stripped, please set the version in the options");
|
||||
throw new NotSupportedException("The Unity version has been stripped, please set the version in the options");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(SpecifyUnityVersion))
|
||||
{
|
||||
@@ -273,9 +475,13 @@ namespace AssetStudio
|
||||
foreach (var objectInfo in assetsFile.m_Objects)
|
||||
{
|
||||
var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objectInfo);
|
||||
if (filteredAssetTypesList.Count > 0 && !filteredAssetTypesList.Contains(objectReader.type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
Object obj;
|
||||
Object obj = null;
|
||||
switch (objectReader.type)
|
||||
{
|
||||
case ClassIDType.Animation:
|
||||
@@ -332,10 +538,14 @@ namespace AssetStudio
|
||||
case ClassIDType.PlayerSettings:
|
||||
obj = new PlayerSettings(objectReader);
|
||||
break;
|
||||
case ClassIDType.PreloadData:
|
||||
obj = new PreloadData(objectReader);
|
||||
break;
|
||||
case ClassIDType.RectTransform:
|
||||
obj = new RectTransform(objectReader);
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
if (objectReader.version[0] < 2021)
|
||||
obj = new Shader(objectReader);
|
||||
break;
|
||||
case ClassIDType.SkinnedMeshRenderer:
|
||||
@@ -366,6 +576,7 @@ namespace AssetStudio
|
||||
obj = new Object(objectReader);
|
||||
break;
|
||||
}
|
||||
if (obj != null)
|
||||
assetsFile.AddObject(obj);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -373,10 +584,11 @@ namespace AssetStudio
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Unable to load object")
|
||||
.AppendLine($"Assets {assetsFile.fileName}")
|
||||
.AppendLine($"Path {assetsFile.originalPath}")
|
||||
.AppendLine($"Type {objectReader.type}")
|
||||
.AppendLine($"PathID {objectInfo.m_PathID}")
|
||||
.Append(e);
|
||||
Logger.Error(sb.ToString());
|
||||
Logger.Warning(sb.ToString());
|
||||
}
|
||||
|
||||
Progress.Report(++i, progressCount);
|
||||
@@ -386,7 +598,7 @@ namespace AssetStudio
|
||||
|
||||
private void ProcessAssets()
|
||||
{
|
||||
Logger.Info("Process Assets...");
|
||||
Logger.Info("Process assets...");
|
||||
|
||||
foreach (var assetsFile in assetsFileList)
|
||||
{
|
||||
@@ -432,6 +644,17 @@ namespace AssetStudio
|
||||
{
|
||||
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
||||
}
|
||||
else if (m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlaOld))
|
||||
{
|
||||
if (m_SpriteAtlaOld.m_IsVariant)
|
||||
{
|
||||
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warning($"\"{m_Sprite.m_Name}\": Sprite loading error. SpriteAtlas with PathID: \"{m_Sprite.m_SpriteAtlas.m_PathID}\" was not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
AssetStudio/BigArrayPool.cs
Normal file
10
AssetStudio/BigArrayPool.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Buffers;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static class BigArrayPool<T>
|
||||
{
|
||||
private static readonly ArrayPool<T> s_shared = ArrayPool<T>.Create(64 * 1024 * 1024, 3);
|
||||
public static ArrayPool<T> Shared => s_shared;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,8 @@ namespace AssetStudio
|
||||
public enum BuildTarget
|
||||
{
|
||||
NoTarget = -2,
|
||||
DashboardWidget = 1,
|
||||
AnyPlayer = -1,
|
||||
ValidPlayer = 1,
|
||||
StandaloneOSX = 2,
|
||||
StandaloneOSXPPC = 3,
|
||||
StandaloneOSXIntel = 4,
|
||||
@@ -19,8 +20,10 @@ namespace AssetStudio
|
||||
iOS = 9,
|
||||
PS3,
|
||||
XBOX360,
|
||||
Broadcom = 12,
|
||||
Android = 13,
|
||||
StandaloneGLESEmu = 14,
|
||||
StandaloneGLES20Emu = 15,
|
||||
NaCl = 16,
|
||||
StandaloneLinux = 17,
|
||||
FlashPlayer = 18,
|
||||
@@ -48,6 +51,8 @@ namespace AssetStudio
|
||||
GameCoreXboxSeries,
|
||||
GameCoreXboxOne,
|
||||
PS5,
|
||||
EmbeddedLinux,
|
||||
QNX,
|
||||
UnknownPlatform = 9999
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using K4os.Compression.LZ4;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Lz4;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
[Flags]
|
||||
public enum ArchiveFlags
|
||||
{
|
||||
CompressionTypeMask = 0x3f,
|
||||
BlocksAndDirectoryInfoCombined = 0x40,
|
||||
BlocksInfoAtTheEnd = 0x80,
|
||||
OldWebPluginCompatibility = 0x100,
|
||||
BlockInfoNeedPaddingAtStart = 0x200
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum CnEncryptionFlags
|
||||
{
|
||||
OldFlag = 0x200,
|
||||
NewFlag = 0x400
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum StorageBlockFlags
|
||||
{
|
||||
CompressionTypeMask = 0x3f,
|
||||
Streamed = 0x40
|
||||
}
|
||||
|
||||
public enum CompressionType
|
||||
{
|
||||
None,
|
||||
Lzma,
|
||||
Lz4,
|
||||
Lz4HC,
|
||||
Lz4Inv,
|
||||
}
|
||||
|
||||
public class BundleFile
|
||||
{
|
||||
public class Header
|
||||
@@ -17,14 +49,14 @@ namespace AssetStudio
|
||||
public long size;
|
||||
public uint compressedBlocksInfoSize;
|
||||
public uint uncompressedBlocksInfoSize;
|
||||
public uint flags;
|
||||
public ArchiveFlags flags;
|
||||
}
|
||||
|
||||
public class StorageBlock
|
||||
{
|
||||
public uint compressedSize;
|
||||
public uint uncompressedSize;
|
||||
public ushort flags;
|
||||
public StorageBlockFlags flags;
|
||||
}
|
||||
|
||||
public class Node
|
||||
@@ -41,7 +73,7 @@ namespace AssetStudio
|
||||
|
||||
public StreamFile[] fileList;
|
||||
|
||||
public BundleFile(FileReader reader)
|
||||
public BundleFile(FileReader reader, string specUnityVer = "")
|
||||
{
|
||||
m_Header = new Header();
|
||||
m_Header.signature = reader.ReadStringToNull();
|
||||
@@ -67,7 +99,31 @@ namespace AssetStudio
|
||||
break;
|
||||
case "UnityFS":
|
||||
ReadHeader(reader);
|
||||
ReadBlocksInfoAndDirectory(reader);
|
||||
|
||||
bool isUnityCnEnc = false;
|
||||
string unityVer = string.IsNullOrEmpty(specUnityVer) ? m_Header.unityRevision : specUnityVer;
|
||||
int[] ver = new string(unityVer.SkipWhile(x => !char.IsDigit(x)).TakeWhile(x => char.IsDigit(x) || x == '.').ToArray()).Split('.').Select(x => int.Parse(x)).ToArray();
|
||||
if (ver[0] != 0)
|
||||
{
|
||||
// https://issuetracker.unity3d.com/issues/files-within-assetbundles-do-not-start-on-aligned-boundaries-breaking-patching-on-nintendo-switch
|
||||
if (ver[0] < 2020 ||
|
||||
(ver[0] == 2020 && ver[1] <= 3 && ver[2] < 34) ||
|
||||
(ver[0] == 2021 && ver[1] <= 3 && ver[2] < 2) ||
|
||||
(ver[0] == 2022 && ver[1] <= 1 && ver[2] < 1))
|
||||
{
|
||||
isUnityCnEnc = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.OldFlag) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
isUnityCnEnc = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.NewFlag) != 0;
|
||||
}
|
||||
}
|
||||
if (isUnityCnEnc)
|
||||
{
|
||||
throw new NotSupportedException("Unsupported bundle file. UnityCN encryption was detected.");
|
||||
}
|
||||
|
||||
ReadBlocksInfoAndDirectory(reader, ver);
|
||||
using (var blocksStream = CreateBlocksStream(reader.FullPath))
|
||||
{
|
||||
ReadBlocks(reader, blocksStream);
|
||||
@@ -79,7 +135,6 @@ namespace AssetStudio
|
||||
|
||||
private void ReadHeaderAndBlocksInfo(EndianBinaryReader reader)
|
||||
{
|
||||
var isCompressed = m_Header.signature == "UnityWeb";
|
||||
if (m_Header.version >= 4)
|
||||
{
|
||||
var hash = reader.ReadBytes(16);
|
||||
@@ -96,7 +151,6 @@ namespace AssetStudio
|
||||
{
|
||||
compressedSize = reader.ReadUInt32(),
|
||||
uncompressedSize = reader.ReadUInt32(),
|
||||
flags = (ushort)(isCompressed ? 1 : 0)
|
||||
};
|
||||
if (i == levelCount - 1)
|
||||
{
|
||||
@@ -133,10 +187,11 @@ namespace AssetStudio
|
||||
|
||||
private void ReadBlocksAndDirectory(EndianBinaryReader reader, Stream blocksStream)
|
||||
{
|
||||
var isCompressed = m_Header.signature == "UnityWeb";
|
||||
foreach (var blockInfo in m_BlocksInfo)
|
||||
{
|
||||
var uncompressedBytes = reader.ReadBytes((int)blockInfo.compressedSize);
|
||||
if (blockInfo.flags == 1)
|
||||
if (isCompressed)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream(uncompressedBytes))
|
||||
{
|
||||
@@ -196,59 +251,79 @@ namespace AssetStudio
|
||||
m_Header.size = reader.ReadInt64();
|
||||
m_Header.compressedBlocksInfoSize = reader.ReadUInt32();
|
||||
m_Header.uncompressedBlocksInfoSize = reader.ReadUInt32();
|
||||
m_Header.flags = reader.ReadUInt32();
|
||||
m_Header.flags = (ArchiveFlags)reader.ReadUInt32();
|
||||
if (m_Header.signature != "UnityFS")
|
||||
{
|
||||
reader.ReadByte();
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader)
|
||||
private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader, int[] unityVer)
|
||||
{
|
||||
byte[] blocksInfoBytes;
|
||||
|
||||
if (m_Header.version >= 7)
|
||||
{
|
||||
reader.AlignStream(16);
|
||||
}
|
||||
if ((m_Header.flags & 0x80) != 0) //kArchiveBlocksInfoAtTheEnd
|
||||
else if (unityVer[0] >= 2019 && unityVer[1] >= 4)
|
||||
{
|
||||
//check if we need to align the reader
|
||||
//- align to 16 bytes and check if all are 0
|
||||
//- if not, reset the reader to the previous position
|
||||
var preAlign = reader.Position;
|
||||
var alignData = reader.ReadBytes((16 - (int)(preAlign % 16)) % 16);
|
||||
if (alignData.Any(x => x != 0))
|
||||
{
|
||||
reader.Position = preAlign;
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
|
||||
{
|
||||
var position = reader.Position;
|
||||
reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
|
||||
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
||||
reader.Position = position;
|
||||
}
|
||||
else //0x40 kArchiveBlocksAndDirectoryInfoCombined
|
||||
else //0x40 BlocksAndDirectoryInfoCombined
|
||||
{
|
||||
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
||||
}
|
||||
var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
|
||||
MemoryStream blocksInfoUncompresseddStream;
|
||||
switch (m_Header.flags & 0x3F) //kArchiveCompressionTypeMask
|
||||
var uncompressedSize = m_Header.uncompressedBlocksInfoSize;
|
||||
var compressionType = (CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask);
|
||||
switch (compressionType)
|
||||
{
|
||||
default: //None
|
||||
case CompressionType.None:
|
||||
{
|
||||
blocksInfoUncompresseddStream = blocksInfoCompressedStream;
|
||||
blocksInfoUncompresseddStream = new MemoryStream(blocksInfoBytes);
|
||||
break;
|
||||
}
|
||||
case 1: //LZMA
|
||||
case CompressionType.Lzma:
|
||||
{
|
||||
blocksInfoUncompresseddStream = new MemoryStream((int)(uncompressedSize));
|
||||
using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
|
||||
{
|
||||
blocksInfoUncompresseddStream = new MemoryStream((int)(m_Header.uncompressedBlocksInfoSize));
|
||||
SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompresseddStream, m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
|
||||
}
|
||||
blocksInfoUncompresseddStream.Position = 0;
|
||||
blocksInfoCompressedStream.Close();
|
||||
break;
|
||||
}
|
||||
case 2: //LZ4
|
||||
case 3: //LZ4HC
|
||||
case CompressionType.Lz4:
|
||||
case CompressionType.Lz4HC:
|
||||
{
|
||||
var uncompressedBytes = new byte[m_Header.uncompressedBlocksInfoSize];
|
||||
using (var decoder = new Lz4DecoderStream(blocksInfoCompressedStream))
|
||||
var uncompressedBytes = new byte[uncompressedSize];
|
||||
var numWrite = LZ4Codec.Decode(blocksInfoBytes, uncompressedBytes);
|
||||
if (numWrite != uncompressedSize)
|
||||
{
|
||||
decoder.Read(uncompressedBytes, 0, uncompressedBytes.Length);
|
||||
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
|
||||
}
|
||||
blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IOException($"Unsupported compression type {compressionType}");
|
||||
}
|
||||
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
|
||||
{
|
||||
@@ -261,7 +336,7 @@ namespace AssetStudio
|
||||
{
|
||||
uncompressedSize = blocksInfoReader.ReadUInt32(),
|
||||
compressedSize = blocksInfoReader.ReadUInt32(),
|
||||
flags = blocksInfoReader.ReadUInt16()
|
||||
flags = (StorageBlockFlags)blocksInfoReader.ReadUInt16()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -278,34 +353,60 @@ namespace AssetStudio
|
||||
};
|
||||
}
|
||||
}
|
||||
if ((m_Header.flags & ArchiveFlags.BlockInfoNeedPaddingAtStart) != 0)
|
||||
{
|
||||
reader.AlignStream(16);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
|
||||
{
|
||||
foreach (var blockInfo in m_BlocksInfo)
|
||||
{
|
||||
switch (blockInfo.flags & 0x3F) //kStorageBlockCompressionTypeMask
|
||||
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
|
||||
switch (compressionType)
|
||||
{
|
||||
default: //None
|
||||
case CompressionType.None:
|
||||
{
|
||||
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
|
||||
break;
|
||||
}
|
||||
case 1: //LZMA
|
||||
case CompressionType.Lzma:
|
||||
{
|
||||
SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
|
||||
break;
|
||||
}
|
||||
case 2: //LZ4
|
||||
case 3: //LZ4HC
|
||||
case CompressionType.Lz4:
|
||||
case CompressionType.Lz4HC:
|
||||
case CompressionType.Lz4Inv:
|
||||
{
|
||||
var compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize));
|
||||
using (var lz4Stream = new Lz4DecoderStream(compressedStream))
|
||||
var compressedSize = (int)blockInfo.compressedSize;
|
||||
var compressedBytes = BigArrayPool<byte>.Shared.Rent(compressedSize);
|
||||
_ = reader.Read(compressedBytes, 0, compressedSize);
|
||||
var uncompressedSize = (int)blockInfo.uncompressedSize;
|
||||
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
|
||||
try
|
||||
{
|
||||
lz4Stream.CopyTo(blocksStream, blockInfo.uncompressedSize);
|
||||
var compressedSpan = compressedBytes.AsSpan(0, compressedSize);
|
||||
var uncompressedSpan = uncompressedBytes.AsSpan(0, uncompressedSize);
|
||||
var numWrite = compressionType == CompressionType.Lz4Inv
|
||||
? LZ4Inv.Instance.Decompress(compressedSpan, uncompressedSpan)
|
||||
: LZ4Codec.Decode(compressedSpan, uncompressedSpan);
|
||||
if (numWrite != uncompressedSize)
|
||||
{
|
||||
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
|
||||
}
|
||||
blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
|
||||
}
|
||||
finally
|
||||
{
|
||||
BigArrayPool<byte>.Shared.Return(compressedBytes);
|
||||
BigArrayPool<byte>.Shared.Return(uncompressedBytes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IOException($"Unsupported compression type {compressionType}");
|
||||
}
|
||||
}
|
||||
blocksStream.Position = 0;
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace AssetStudio
|
||||
{
|
||||
public enum ClassIDType
|
||||
{
|
||||
AkPortraitSprite = -2,
|
||||
UnknownType = -1,
|
||||
Object = 0,
|
||||
GameObject = 1,
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace AssetStudio
|
||||
public T inWeight;
|
||||
public T outWeight;
|
||||
|
||||
|
||||
public Keyframe(ObjectReader reader, Func<T> readerFunc)
|
||||
{
|
||||
time = reader.ReadSingle();
|
||||
@@ -294,15 +293,20 @@ namespace AssetStudio
|
||||
public string path;
|
||||
public ClassIDType classID;
|
||||
public PPtr<MonoScript> script;
|
||||
|
||||
public int flags;
|
||||
|
||||
public FloatCurve(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
curve = new AnimationCurve<float>(reader, reader.ReadSingle);
|
||||
attribute = reader.ReadAlignedString();
|
||||
path = reader.ReadAlignedString();
|
||||
classID = (ClassIDType)reader.ReadInt32();
|
||||
script = new PPtr<MonoScript>(reader);
|
||||
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
|
||||
{
|
||||
flags = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +315,6 @@ namespace AssetStudio
|
||||
public float time;
|
||||
public PPtr<Object> value;
|
||||
|
||||
|
||||
public PPtrKeyframe(ObjectReader reader)
|
||||
{
|
||||
time = reader.ReadSingle();
|
||||
@@ -326,10 +329,11 @@ namespace AssetStudio
|
||||
public string path;
|
||||
public int classID;
|
||||
public PPtr<MonoScript> script;
|
||||
|
||||
public int flags;
|
||||
|
||||
public PPtrCurve(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
int numCurves = reader.ReadInt32();
|
||||
curve = new PPtrKeyframe[numCurves];
|
||||
for (int i = 0; i < numCurves; i++)
|
||||
@@ -341,6 +345,10 @@ namespace AssetStudio
|
||||
path = reader.ReadAlignedString();
|
||||
classID = reader.ReadInt32();
|
||||
script = new PPtr<MonoScript>(reader);
|
||||
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
|
||||
{
|
||||
flags = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -797,6 +805,7 @@ namespace AssetStudio
|
||||
public ClassIDType typeID;
|
||||
public byte customType;
|
||||
public byte isPPtrCurve;
|
||||
public byte isIntCurve;
|
||||
|
||||
public GenericBinding() { }
|
||||
|
||||
@@ -816,6 +825,10 @@ namespace AssetStudio
|
||||
}
|
||||
customType = reader.ReadByte();
|
||||
isPPtrCurve = reader.ReadByte();
|
||||
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
|
||||
{
|
||||
isIntCurve = reader.ReadByte();
|
||||
}
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
@@ -909,9 +922,9 @@ namespace AssetStudio
|
||||
|
||||
public enum AnimationType
|
||||
{
|
||||
kLegacy = 1,
|
||||
kGeneric = 2,
|
||||
kHumanoid = 3
|
||||
Legacy = 1,
|
||||
Generic = 2,
|
||||
Humanoid = 3
|
||||
};
|
||||
|
||||
public sealed class AnimationClip : NamedObject
|
||||
@@ -935,7 +948,6 @@ namespace AssetStudio
|
||||
public AnimationClipBindingConstant m_ClipBindingConstant;
|
||||
public AnimationEvent[] m_Events;
|
||||
|
||||
|
||||
public AnimationClip(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (version[0] >= 5)//5.0 and up
|
||||
@@ -945,7 +957,7 @@ namespace AssetStudio
|
||||
else if (version[0] >= 4)//4.0 and up
|
||||
{
|
||||
m_AnimationType = (AnimationType)reader.ReadInt32();
|
||||
if (m_AnimationType == AnimationType.kLegacy)
|
||||
if (m_AnimationType == AnimationType.Legacy)
|
||||
m_Legacy = true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -23,22 +20,47 @@ namespace AssetStudio
|
||||
{
|
||||
public PPtr<Object>[] m_PreloadTable;
|
||||
public KeyValuePair<string, AssetInfo>[] m_Container;
|
||||
public string m_AssetBundleName;
|
||||
public string[] m_Dependencies;
|
||||
public bool m_IsStreamedSceneAssetBundle;
|
||||
|
||||
public AssetBundle(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var m_PreloadTableSize = reader.ReadInt32();
|
||||
m_PreloadTable = new PPtr<Object>[m_PreloadTableSize];
|
||||
for (int i = 0; i < m_PreloadTableSize; i++)
|
||||
for (var i = 0; i < m_PreloadTableSize; i++)
|
||||
{
|
||||
m_PreloadTable[i] = new PPtr<Object>(reader);
|
||||
}
|
||||
|
||||
var m_ContainerSize = reader.ReadInt32();
|
||||
m_Container = new KeyValuePair<string, AssetInfo>[m_ContainerSize];
|
||||
for (int i = 0; i < m_ContainerSize; i++)
|
||||
for (var i = 0; i < m_ContainerSize; i++)
|
||||
{
|
||||
m_Container[i] = new KeyValuePair<string, AssetInfo>(reader.ReadAlignedString(), new AssetInfo(reader));
|
||||
}
|
||||
|
||||
var m_MainAsset = new AssetInfo(reader);
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
|
||||
{
|
||||
var m_RuntimeCompatibility = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
{
|
||||
m_AssetBundleName = reader.ReadAlignedString();
|
||||
|
||||
var m_DependenciesSize = reader.ReadInt32();
|
||||
m_Dependencies = new string[m_DependenciesSize];
|
||||
|
||||
for (var i = 0; i < m_DependenciesSize; i++)
|
||||
{
|
||||
m_Dependencies[i] = reader.ReadAlignedString();
|
||||
}
|
||||
|
||||
m_IsStreamedSceneAssetBundle = reader.ReadBoolean();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace AssetStudio
|
||||
public sealed class AudioClip : NamedObject
|
||||
{
|
||||
public int m_Format;
|
||||
public AudioType m_Type;
|
||||
public FMODSoundType m_Type;
|
||||
public bool m_3D;
|
||||
public bool m_UseHardware;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace AssetStudio
|
||||
if (version[0] < 5)
|
||||
{
|
||||
m_Format = reader.ReadInt32();
|
||||
m_Type = (AudioType)reader.ReadInt32();
|
||||
m_Type = (FMODSoundType)reader.ReadInt32();
|
||||
m_3D = reader.ReadBoolean();
|
||||
m_UseHardware = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
@@ -92,34 +92,51 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
public enum AudioType
|
||||
public enum FMODSoundType
|
||||
{
|
||||
UNKNOWN,
|
||||
ACC,
|
||||
AIFF,
|
||||
UNKNOWN = 0,
|
||||
ACC = 1,
|
||||
AIFF = 2,
|
||||
ASF = 3,
|
||||
AT3 = 4,
|
||||
CDDA = 5,
|
||||
DLS = 6,
|
||||
FLAC = 7,
|
||||
FSB = 8,
|
||||
GCADPCM = 9,
|
||||
IT = 10,
|
||||
MIDI = 11,
|
||||
MOD = 12,
|
||||
MPEG,
|
||||
OGGVORBIS,
|
||||
MPEG = 13,
|
||||
OGGVORBIS = 14,
|
||||
PLAYLIST = 15,
|
||||
RAW = 16,
|
||||
S3M = 17,
|
||||
SF2 = 18,
|
||||
USER = 19,
|
||||
WAV = 20,
|
||||
XM,
|
||||
XMA,
|
||||
VAG,
|
||||
AUDIOQUEUE
|
||||
XM = 21,
|
||||
XMA = 22,
|
||||
VAG = 23,
|
||||
AUDIOQUEUE = 24,
|
||||
XWMA = 25,
|
||||
BCWAV = 26,
|
||||
AT9 = 27,
|
||||
VORBIS = 28,
|
||||
MEDIA_FOUNDATION = 29
|
||||
}
|
||||
|
||||
public enum AudioCompressionFormat
|
||||
{
|
||||
PCM,
|
||||
Vorbis,
|
||||
ADPCM,
|
||||
MP3,
|
||||
VAG,
|
||||
HEVAG,
|
||||
XMA,
|
||||
AAC,
|
||||
GCADPCM,
|
||||
ATRAC9
|
||||
PCM = 0,
|
||||
Vorbis = 1,
|
||||
ADPCM = 2,
|
||||
MP3 = 3,
|
||||
PSMVAG = 4,
|
||||
HEVAG = 5,
|
||||
XMA = 6,
|
||||
AAC = 7,
|
||||
GCADPCM = 8,
|
||||
ATRAC9 = 9
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,9 +74,18 @@ namespace AssetStudio
|
||||
var m_ShaderKeywords = reader.ReadStringArray();
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 3)) //2021.3 and up
|
||||
{
|
||||
var m_ValidKeywords = reader.ReadStringArray();
|
||||
var m_InvalidKeywords = reader.ReadStringArray();
|
||||
}
|
||||
else if (version[0] >= 5) //5.0 ~ 2021.2
|
||||
{
|
||||
var m_ShaderKeywords = reader.ReadAlignedString();
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
{
|
||||
var m_LightmapFlags = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
|
||||
@@ -396,14 +396,14 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
public enum GfxPrimitiveType : int
|
||||
public enum GfxPrimitiveType
|
||||
{
|
||||
kPrimitiveTriangles = 0,
|
||||
kPrimitiveTriangleStrip = 1,
|
||||
kPrimitiveQuads = 2,
|
||||
kPrimitiveLines = 3,
|
||||
kPrimitiveLineStrip = 4,
|
||||
kPrimitivePoints = 5,
|
||||
Triangles = 0,
|
||||
TriangleStrip = 1,
|
||||
Quads = 2,
|
||||
Lines = 3,
|
||||
LineStrip = 4,
|
||||
Points = 5
|
||||
};
|
||||
|
||||
public class SubMesh
|
||||
@@ -651,6 +651,11 @@ namespace AssetStudio
|
||||
|
||||
int m_MeshUsageFlags = reader.ReadInt32();
|
||||
|
||||
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
|
||||
{
|
||||
int m_CookingOptions = reader.ReadInt32();
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
{
|
||||
var m_BakedConvexCollisionMesh = reader.ReadUInt8Array();
|
||||
@@ -729,7 +734,7 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.endian == EndianType.BigEndian && componentByteSize > 1) //swap bytes
|
||||
if (reader.Endian == EndianType.BigEndian && componentByteSize > 1) //swap bytes
|
||||
{
|
||||
for (var i = 0; i < componentBytes.Length / componentByteSize; i++)
|
||||
{
|
||||
@@ -1060,7 +1065,7 @@ namespace AssetStudio
|
||||
}
|
||||
var indexCount = m_SubMesh.indexCount;
|
||||
var topology = m_SubMesh.topology;
|
||||
if (topology == GfxPrimitiveType.kPrimitiveTriangles)
|
||||
if (topology == GfxPrimitiveType.Triangles)
|
||||
{
|
||||
for (int i = 0; i < indexCount; i += 3)
|
||||
{
|
||||
@@ -1069,7 +1074,7 @@ namespace AssetStudio
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + i + 2]);
|
||||
}
|
||||
}
|
||||
else if (version[0] < 4 || topology == GfxPrimitiveType.kPrimitiveTriangleStrip)
|
||||
else if (version[0] < 4 || topology == GfxPrimitiveType.TriangleStrip)
|
||||
{
|
||||
// de-stripify :
|
||||
uint triIndex = 0;
|
||||
@@ -1100,7 +1105,7 @@ namespace AssetStudio
|
||||
//fix indexCount
|
||||
m_SubMesh.indexCount = triIndex;
|
||||
}
|
||||
else if (topology == GfxPrimitiveType.kPrimitiveQuads)
|
||||
else if (topology == GfxPrimitiveType.Quads)
|
||||
{
|
||||
for (int q = 0; q < indexCount; q += 4)
|
||||
{
|
||||
@@ -1193,44 +1198,44 @@ namespace AssetStudio
|
||||
{
|
||||
public enum VertexChannelFormat
|
||||
{
|
||||
kChannelFormatFloat,
|
||||
kChannelFormatFloat16,
|
||||
kChannelFormatColor,
|
||||
kChannelFormatByte,
|
||||
kChannelFormatUInt32
|
||||
Float,
|
||||
Float16,
|
||||
Color,
|
||||
Byte,
|
||||
UInt32
|
||||
}
|
||||
|
||||
public enum VertexFormat2017
|
||||
{
|
||||
kVertexFormatFloat,
|
||||
kVertexFormatFloat16,
|
||||
kVertexFormatColor,
|
||||
kVertexFormatUNorm8,
|
||||
kVertexFormatSNorm8,
|
||||
kVertexFormatUNorm16,
|
||||
kVertexFormatSNorm16,
|
||||
kVertexFormatUInt8,
|
||||
kVertexFormatSInt8,
|
||||
kVertexFormatUInt16,
|
||||
kVertexFormatSInt16,
|
||||
kVertexFormatUInt32,
|
||||
kVertexFormatSInt32
|
||||
Float,
|
||||
Float16,
|
||||
Color,
|
||||
UNorm8,
|
||||
SNorm8,
|
||||
UNorm16,
|
||||
SNorm16,
|
||||
UInt8,
|
||||
SInt8,
|
||||
UInt16,
|
||||
SInt16,
|
||||
UInt32,
|
||||
SInt32
|
||||
}
|
||||
|
||||
public enum VertexFormat
|
||||
{
|
||||
kVertexFormatFloat,
|
||||
kVertexFormatFloat16,
|
||||
kVertexFormatUNorm8,
|
||||
kVertexFormatSNorm8,
|
||||
kVertexFormatUNorm16,
|
||||
kVertexFormatSNorm16,
|
||||
kVertexFormatUInt8,
|
||||
kVertexFormatSInt8,
|
||||
kVertexFormatUInt16,
|
||||
kVertexFormatSInt16,
|
||||
kVertexFormatUInt32,
|
||||
kVertexFormatSInt32
|
||||
Float,
|
||||
Float16,
|
||||
UNorm8,
|
||||
SNorm8,
|
||||
UNorm16,
|
||||
SNorm16,
|
||||
UInt8,
|
||||
SInt8,
|
||||
UInt16,
|
||||
SInt16,
|
||||
UInt32,
|
||||
SInt32
|
||||
}
|
||||
|
||||
public static VertexFormat ToVertexFormat(int format, int[] version)
|
||||
@@ -1239,16 +1244,16 @@ namespace AssetStudio
|
||||
{
|
||||
switch ((VertexChannelFormat)format)
|
||||
{
|
||||
case VertexChannelFormat.kChannelFormatFloat:
|
||||
return VertexFormat.kVertexFormatFloat;
|
||||
case VertexChannelFormat.kChannelFormatFloat16:
|
||||
return VertexFormat.kVertexFormatFloat16;
|
||||
case VertexChannelFormat.kChannelFormatColor: //in 4.x is size 4
|
||||
return VertexFormat.kVertexFormatUNorm8;
|
||||
case VertexChannelFormat.kChannelFormatByte:
|
||||
return VertexFormat.kVertexFormatUInt8;
|
||||
case VertexChannelFormat.kChannelFormatUInt32: //in 5.x
|
||||
return VertexFormat.kVertexFormatUInt32;
|
||||
case VertexChannelFormat.Float:
|
||||
return VertexFormat.Float;
|
||||
case VertexChannelFormat.Float16:
|
||||
return VertexFormat.Float16;
|
||||
case VertexChannelFormat.Color: //in 4.x is size 4
|
||||
return VertexFormat.UNorm8;
|
||||
case VertexChannelFormat.Byte:
|
||||
return VertexFormat.UInt8;
|
||||
case VertexChannelFormat.UInt32: //in 5.x
|
||||
return VertexFormat.UInt32;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(format), format, null);
|
||||
}
|
||||
@@ -1257,31 +1262,31 @@ namespace AssetStudio
|
||||
{
|
||||
switch ((VertexFormat2017)format)
|
||||
{
|
||||
case VertexFormat2017.kVertexFormatFloat:
|
||||
return VertexFormat.kVertexFormatFloat;
|
||||
case VertexFormat2017.kVertexFormatFloat16:
|
||||
return VertexFormat.kVertexFormatFloat16;
|
||||
case VertexFormat2017.kVertexFormatColor:
|
||||
case VertexFormat2017.kVertexFormatUNorm8:
|
||||
return VertexFormat.kVertexFormatUNorm8;
|
||||
case VertexFormat2017.kVertexFormatSNorm8:
|
||||
return VertexFormat.kVertexFormatSNorm8;
|
||||
case VertexFormat2017.kVertexFormatUNorm16:
|
||||
return VertexFormat.kVertexFormatUNorm16;
|
||||
case VertexFormat2017.kVertexFormatSNorm16:
|
||||
return VertexFormat.kVertexFormatSNorm16;
|
||||
case VertexFormat2017.kVertexFormatUInt8:
|
||||
return VertexFormat.kVertexFormatUInt8;
|
||||
case VertexFormat2017.kVertexFormatSInt8:
|
||||
return VertexFormat.kVertexFormatSInt8;
|
||||
case VertexFormat2017.kVertexFormatUInt16:
|
||||
return VertexFormat.kVertexFormatUInt16;
|
||||
case VertexFormat2017.kVertexFormatSInt16:
|
||||
return VertexFormat.kVertexFormatSInt16;
|
||||
case VertexFormat2017.kVertexFormatUInt32:
|
||||
return VertexFormat.kVertexFormatUInt32;
|
||||
case VertexFormat2017.kVertexFormatSInt32:
|
||||
return VertexFormat.kVertexFormatSInt32;
|
||||
case VertexFormat2017.Float:
|
||||
return VertexFormat.Float;
|
||||
case VertexFormat2017.Float16:
|
||||
return VertexFormat.Float16;
|
||||
case VertexFormat2017.Color:
|
||||
case VertexFormat2017.UNorm8:
|
||||
return VertexFormat.UNorm8;
|
||||
case VertexFormat2017.SNorm8:
|
||||
return VertexFormat.SNorm8;
|
||||
case VertexFormat2017.UNorm16:
|
||||
return VertexFormat.UNorm16;
|
||||
case VertexFormat2017.SNorm16:
|
||||
return VertexFormat.SNorm16;
|
||||
case VertexFormat2017.UInt8:
|
||||
return VertexFormat.UInt8;
|
||||
case VertexFormat2017.SInt8:
|
||||
return VertexFormat.SInt8;
|
||||
case VertexFormat2017.UInt16:
|
||||
return VertexFormat.UInt16;
|
||||
case VertexFormat2017.SInt16:
|
||||
return VertexFormat.SInt16;
|
||||
case VertexFormat2017.UInt32:
|
||||
return VertexFormat.UInt32;
|
||||
case VertexFormat2017.SInt32:
|
||||
return VertexFormat.SInt32;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(format), format, null);
|
||||
}
|
||||
@@ -1297,20 +1302,20 @@ namespace AssetStudio
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VertexFormat.kVertexFormatFloat:
|
||||
case VertexFormat.kVertexFormatUInt32:
|
||||
case VertexFormat.kVertexFormatSInt32:
|
||||
case VertexFormat.Float:
|
||||
case VertexFormat.UInt32:
|
||||
case VertexFormat.SInt32:
|
||||
return 4u;
|
||||
case VertexFormat.kVertexFormatFloat16:
|
||||
case VertexFormat.kVertexFormatUNorm16:
|
||||
case VertexFormat.kVertexFormatSNorm16:
|
||||
case VertexFormat.kVertexFormatUInt16:
|
||||
case VertexFormat.kVertexFormatSInt16:
|
||||
case VertexFormat.Float16:
|
||||
case VertexFormat.UNorm16:
|
||||
case VertexFormat.SNorm16:
|
||||
case VertexFormat.UInt16:
|
||||
case VertexFormat.SInt16:
|
||||
return 2u;
|
||||
case VertexFormat.kVertexFormatUNorm8:
|
||||
case VertexFormat.kVertexFormatSNorm8:
|
||||
case VertexFormat.kVertexFormatUInt8:
|
||||
case VertexFormat.kVertexFormatSInt8:
|
||||
case VertexFormat.UNorm8:
|
||||
case VertexFormat.SNorm8:
|
||||
case VertexFormat.UInt8:
|
||||
case VertexFormat.SInt8:
|
||||
return 1u;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(format), format, null);
|
||||
@@ -1319,7 +1324,7 @@ namespace AssetStudio
|
||||
|
||||
public static bool IsIntFormat(VertexFormat format)
|
||||
{
|
||||
return format >= VertexFormat.kVertexFormatUInt8;
|
||||
return format >= VertexFormat.UInt8;
|
||||
}
|
||||
|
||||
public static float[] BytesToFloatArray(byte[] inputBytes, VertexFormat format)
|
||||
@@ -1331,22 +1336,22 @@ namespace AssetStudio
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VertexFormat.kVertexFormatFloat:
|
||||
case VertexFormat.Float:
|
||||
result[i] = BitConverter.ToSingle(inputBytes, i * 4);
|
||||
break;
|
||||
case VertexFormat.kVertexFormatFloat16:
|
||||
case VertexFormat.Float16:
|
||||
result[i] = Half.ToHalf(inputBytes, i * 2);
|
||||
break;
|
||||
case VertexFormat.kVertexFormatUNorm8:
|
||||
case VertexFormat.UNorm8:
|
||||
result[i] = inputBytes[i] / 255f;
|
||||
break;
|
||||
case VertexFormat.kVertexFormatSNorm8:
|
||||
case VertexFormat.SNorm8:
|
||||
result[i] = Math.Max((sbyte)inputBytes[i] / 127f, -1f);
|
||||
break;
|
||||
case VertexFormat.kVertexFormatUNorm16:
|
||||
case VertexFormat.UNorm16:
|
||||
result[i] = BitConverter.ToUInt16(inputBytes, i * 2) / 65535f;
|
||||
break;
|
||||
case VertexFormat.kVertexFormatSNorm16:
|
||||
case VertexFormat.SNorm16:
|
||||
result[i] = Math.Max(BitConverter.ToInt16(inputBytes, i * 2) / 32767f, -1f);
|
||||
break;
|
||||
}
|
||||
@@ -1363,16 +1368,16 @@ namespace AssetStudio
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VertexFormat.kVertexFormatUInt8:
|
||||
case VertexFormat.kVertexFormatSInt8:
|
||||
case VertexFormat.UInt8:
|
||||
case VertexFormat.SInt8:
|
||||
result[i] = inputBytes[i];
|
||||
break;
|
||||
case VertexFormat.kVertexFormatUInt16:
|
||||
case VertexFormat.kVertexFormatSInt16:
|
||||
case VertexFormat.UInt16:
|
||||
case VertexFormat.SInt16:
|
||||
result[i] = BitConverter.ToInt16(inputBytes, i * 2);
|
||||
break;
|
||||
case VertexFormat.kVertexFormatUInt32:
|
||||
case VertexFormat.kVertexFormatSInt32:
|
||||
case VertexFormat.UInt32:
|
||||
case VertexFormat.SInt32:
|
||||
result[i] = BitConverter.ToInt32(inputBytes, i * 4);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace AssetStudio
|
||||
public PPtr(ObjectReader reader)
|
||||
{
|
||||
m_FileID = reader.ReadInt32();
|
||||
m_PathID = reader.m_Version < SerializedFileFormatVersion.kUnknown_14 ? reader.ReadInt32() : reader.ReadInt64();
|
||||
m_PathID = reader.m_Version < SerializedFileFormatVersion.Unknown_14 ? reader.ReadInt32() : reader.ReadInt64();
|
||||
assetsFile = reader.assetsFile;
|
||||
}
|
||||
|
||||
|
||||
35
AssetStudio/Classes/PreloadData.cs
Normal file
35
AssetStudio/Classes/PreloadData.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class PreloadData : NamedObject
|
||||
{
|
||||
public PPtr<Object>[] m_Assets;
|
||||
|
||||
public PreloadData(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var m_PreloadTableSize = reader.ReadInt32();
|
||||
m_Assets = new PPtr<Object>[m_PreloadTableSize];
|
||||
for (var i = 0; i < m_PreloadTableSize; i++)
|
||||
{
|
||||
m_Assets[i] = new PPtr<Object>(reader);
|
||||
}
|
||||
|
||||
/*
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
{
|
||||
var m_DependenciesSize = reader.ReadInt32();
|
||||
var m_Dependencies = new string[m_DependenciesSize];
|
||||
|
||||
for (var i = 0; i < m_DependenciesSize; i++)
|
||||
{
|
||||
m_Dependencies[i] = reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
|
||||
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
|
||||
{
|
||||
var m_ExplicitDataLayout = reader.ReadBoolean();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,15 +56,14 @@ namespace AssetStudio
|
||||
}
|
||||
public enum TextureDimension
|
||||
{
|
||||
kTexDimUnknown = -1,
|
||||
kTexDimNone = 0,
|
||||
kTexDimAny = 1,
|
||||
kTexDim2D = 2,
|
||||
kTexDim3D = 3,
|
||||
kTexDimCUBE = 4,
|
||||
kTexDim2DArray = 5,
|
||||
kTexDimCubeArray = 6,
|
||||
kTexDimForce32Bit = 2147483647
|
||||
Unknown = -1,
|
||||
None = 0,
|
||||
Any = 1,
|
||||
Tex2D = 2,
|
||||
Tex3D = 3,
|
||||
Cube = 4,
|
||||
Tex2DArray = 5,
|
||||
CubeArray = 6
|
||||
};
|
||||
|
||||
public class SerializedTextureProperty
|
||||
@@ -81,11 +80,12 @@ namespace AssetStudio
|
||||
|
||||
public enum SerializedPropertyType
|
||||
{
|
||||
kColor = 0,
|
||||
kVector = 1,
|
||||
kFloat = 2,
|
||||
kRange = 3,
|
||||
kTexture = 4
|
||||
Color = 0,
|
||||
Vector = 1,
|
||||
Float = 2,
|
||||
Range = 3,
|
||||
Texture = 4,
|
||||
Int = 5
|
||||
};
|
||||
|
||||
public class SerializedProperty
|
||||
@@ -195,11 +195,11 @@ namespace AssetStudio
|
||||
|
||||
public enum FogMode
|
||||
{
|
||||
kFogUnknown = -1,
|
||||
kFogDisabled = 0,
|
||||
kFogLinear = 1,
|
||||
kFogExp = 2,
|
||||
kFogExp2 = 3
|
||||
Unknown = -1,
|
||||
Disabled = 0,
|
||||
Linear = 1,
|
||||
Exp = 2,
|
||||
Exp2 = 3
|
||||
};
|
||||
|
||||
public class SerializedShaderState
|
||||
@@ -428,6 +428,7 @@ namespace AssetStudio
|
||||
|
||||
if ((version[0] == 2020 && version[1] > 3) ||
|
||||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
|
||||
(version[0] > 2021) ||
|
||||
(version[0] == 2021 && version[1] > 1) ||
|
||||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
|
||||
{
|
||||
@@ -453,38 +454,39 @@ namespace AssetStudio
|
||||
|
||||
public enum ShaderGpuProgramType
|
||||
{
|
||||
kShaderGpuProgramUnknown = 0,
|
||||
kShaderGpuProgramGLLegacy = 1,
|
||||
kShaderGpuProgramGLES31AEP = 2,
|
||||
kShaderGpuProgramGLES31 = 3,
|
||||
kShaderGpuProgramGLES3 = 4,
|
||||
kShaderGpuProgramGLES = 5,
|
||||
kShaderGpuProgramGLCore32 = 6,
|
||||
kShaderGpuProgramGLCore41 = 7,
|
||||
kShaderGpuProgramGLCore43 = 8,
|
||||
kShaderGpuProgramDX9VertexSM20 = 9,
|
||||
kShaderGpuProgramDX9VertexSM30 = 10,
|
||||
kShaderGpuProgramDX9PixelSM20 = 11,
|
||||
kShaderGpuProgramDX9PixelSM30 = 12,
|
||||
kShaderGpuProgramDX10Level9Vertex = 13,
|
||||
kShaderGpuProgramDX10Level9Pixel = 14,
|
||||
kShaderGpuProgramDX11VertexSM40 = 15,
|
||||
kShaderGpuProgramDX11VertexSM50 = 16,
|
||||
kShaderGpuProgramDX11PixelSM40 = 17,
|
||||
kShaderGpuProgramDX11PixelSM50 = 18,
|
||||
kShaderGpuProgramDX11GeometrySM40 = 19,
|
||||
kShaderGpuProgramDX11GeometrySM50 = 20,
|
||||
kShaderGpuProgramDX11HullSM50 = 21,
|
||||
kShaderGpuProgramDX11DomainSM50 = 22,
|
||||
kShaderGpuProgramMetalVS = 23,
|
||||
kShaderGpuProgramMetalFS = 24,
|
||||
kShaderGpuProgramSPIRV = 25,
|
||||
kShaderGpuProgramConsoleVS = 26,
|
||||
kShaderGpuProgramConsoleFS = 27,
|
||||
kShaderGpuProgramConsoleHS = 28,
|
||||
kShaderGpuProgramConsoleDS = 29,
|
||||
kShaderGpuProgramConsoleGS = 30,
|
||||
kShaderGpuProgramRayTracing = 31,
|
||||
Unknown = 0,
|
||||
GLLegacy = 1,
|
||||
GLES31AEP = 2,
|
||||
GLES31 = 3,
|
||||
GLES3 = 4,
|
||||
GLES = 5,
|
||||
GLCore32 = 6,
|
||||
GLCore41 = 7,
|
||||
GLCore43 = 8,
|
||||
DX9VertexSM20 = 9,
|
||||
DX9VertexSM30 = 10,
|
||||
DX9PixelSM20 = 11,
|
||||
DX9PixelSM30 = 12,
|
||||
DX10Level9Vertex = 13,
|
||||
DX10Level9Pixel = 14,
|
||||
DX11VertexSM40 = 15,
|
||||
DX11VertexSM50 = 16,
|
||||
DX11PixelSM40 = 17,
|
||||
DX11PixelSM50 = 18,
|
||||
DX11GeometrySM40 = 19,
|
||||
DX11GeometrySM50 = 20,
|
||||
DX11HullSM50 = 21,
|
||||
DX11DomainSM50 = 22,
|
||||
MetalVS = 23,
|
||||
MetalFS = 24,
|
||||
SPIRV = 25,
|
||||
ConsoleVS = 26,
|
||||
ConsoleFS = 27,
|
||||
ConsoleHS = 28,
|
||||
ConsoleDS = 29,
|
||||
ConsoleGS = 30,
|
||||
RayTracing = 31,
|
||||
PS5NGGC = 32
|
||||
};
|
||||
|
||||
public class SerializedProgramParameters
|
||||
@@ -604,8 +606,9 @@ namespace AssetStudio
|
||||
|
||||
if ((version[0] == 2020 && version[1] > 3) ||
|
||||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
|
||||
(version[0] > 2021) ||
|
||||
(version[0] == 2021 && version[1] > 1) ||
|
||||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
|
||||
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
|
||||
{
|
||||
m_Parameters = new SerializedProgramParameters(reader);
|
||||
}
|
||||
@@ -689,6 +692,7 @@ namespace AssetStudio
|
||||
{
|
||||
public SerializedSubProgram[] m_SubPrograms;
|
||||
public SerializedProgramParameters m_CommonParameters;
|
||||
public ushort[] m_SerializedKeywordStateMask;
|
||||
|
||||
public SerializedProgram(ObjectReader reader)
|
||||
{
|
||||
@@ -703,19 +707,26 @@ namespace AssetStudio
|
||||
|
||||
if ((version[0] == 2020 && version[1] > 3) ||
|
||||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
|
||||
(version[0] > 2021) ||
|
||||
(version[0] == 2021 && version[1] > 1) ||
|
||||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
|
||||
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
|
||||
{
|
||||
m_CommonParameters = new SerializedProgramParameters(reader);
|
||||
}
|
||||
|
||||
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
|
||||
{
|
||||
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum PassType
|
||||
{
|
||||
kPassTypeNormal = 0,
|
||||
kPassTypeUse = 1,
|
||||
kPassTypeGrab = 2
|
||||
Normal = 0,
|
||||
Use = 1,
|
||||
Grab = 2
|
||||
};
|
||||
|
||||
public class SerializedPass
|
||||
@@ -794,7 +805,7 @@ namespace AssetStudio
|
||||
m_Name = reader.ReadAlignedString();
|
||||
m_TextureName = reader.ReadAlignedString();
|
||||
m_Tags = new SerializedTagMap(reader);
|
||||
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
|
||||
if (version[0] == 2021 && version[1] >= 2) //2021.2 ~2021.x
|
||||
{
|
||||
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
@@ -922,32 +933,32 @@ namespace AssetStudio
|
||||
|
||||
public enum ShaderCompilerPlatform
|
||||
{
|
||||
kShaderCompPlatformNone = -1,
|
||||
kShaderCompPlatformGL = 0,
|
||||
kShaderCompPlatformD3D9 = 1,
|
||||
kShaderCompPlatformXbox360 = 2,
|
||||
kShaderCompPlatformPS3 = 3,
|
||||
kShaderCompPlatformD3D11 = 4,
|
||||
kShaderCompPlatformGLES20 = 5,
|
||||
kShaderCompPlatformNaCl = 6,
|
||||
kShaderCompPlatformFlash = 7,
|
||||
kShaderCompPlatformD3D11_9x = 8,
|
||||
kShaderCompPlatformGLES3Plus = 9,
|
||||
kShaderCompPlatformPSP2 = 10,
|
||||
kShaderCompPlatformPS4 = 11,
|
||||
kShaderCompPlatformXboxOne = 12,
|
||||
kShaderCompPlatformPSM = 13,
|
||||
kShaderCompPlatformMetal = 14,
|
||||
kShaderCompPlatformOpenGLCore = 15,
|
||||
kShaderCompPlatformN3DS = 16,
|
||||
kShaderCompPlatformWiiU = 17,
|
||||
kShaderCompPlatformVulkan = 18,
|
||||
kShaderCompPlatformSwitch = 19,
|
||||
kShaderCompPlatformXboxOneD3D12 = 20,
|
||||
kShaderCompPlatformGameCoreXboxOne = 21,
|
||||
kShaderCompPlatformGameCoreScarlett = 22,
|
||||
kShaderCompPlatformPS5 = 23,
|
||||
kShaderCompPlatformPS5NGGC = 24,
|
||||
None = -1,
|
||||
GL = 0,
|
||||
D3D9 = 1,
|
||||
Xbox360 = 2,
|
||||
PS3 = 3,
|
||||
D3D11 = 4,
|
||||
GLES20 = 5,
|
||||
NaCl = 6,
|
||||
Flash = 7,
|
||||
D3D11_9x = 8,
|
||||
GLES3Plus = 9,
|
||||
PSP2 = 10,
|
||||
PS4 = 11,
|
||||
XboxOne = 12,
|
||||
PSM = 13,
|
||||
Metal = 14,
|
||||
OpenGLCore = 15,
|
||||
N3DS = 16,
|
||||
WiiU = 17,
|
||||
Vulkan = 18,
|
||||
Switch = 19,
|
||||
XboxOneD3D12 = 20,
|
||||
GameCoreXboxOne = 21,
|
||||
GameCoreScarlett = 22,
|
||||
PS5 = 23,
|
||||
PS5NGGC = 24
|
||||
};
|
||||
|
||||
public class Shader : NamedObject
|
||||
@@ -959,9 +970,9 @@ namespace AssetStudio
|
||||
//5.5 and up
|
||||
public SerializedShader m_ParsedForm;
|
||||
public ShaderCompilerPlatform[] platforms;
|
||||
public uint[] offsets;
|
||||
public uint[] compressedLengths;
|
||||
public uint[] decompressedLengths;
|
||||
public uint[][] offsets;
|
||||
public uint[][] compressedLengths;
|
||||
public uint[][] decompressedLengths;
|
||||
public byte[] compressedBlob;
|
||||
|
||||
public Shader(ObjectReader reader) : base(reader)
|
||||
@@ -972,15 +983,15 @@ namespace AssetStudio
|
||||
platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
|
||||
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||
{
|
||||
offsets = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
|
||||
compressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
|
||||
decompressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
|
||||
offsets = reader.ReadUInt32ArrayArray();
|
||||
compressedLengths = reader.ReadUInt32ArrayArray();
|
||||
decompressedLengths = reader.ReadUInt32ArrayArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
offsets = reader.ReadUInt32Array();
|
||||
compressedLengths = reader.ReadUInt32Array();
|
||||
decompressedLengths = reader.ReadUInt32Array();
|
||||
offsets = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
|
||||
compressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
|
||||
decompressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
|
||||
}
|
||||
compressedBlob = reader.ReadUInt8Array();
|
||||
reader.AlignStream();
|
||||
|
||||
@@ -12,29 +12,29 @@ namespace AssetStudio
|
||||
public SecondarySpriteTexture(ObjectReader reader)
|
||||
{
|
||||
texture = new PPtr<Texture2D>(reader);
|
||||
name = reader.ReadStringToNull();
|
||||
name = reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum SpritePackingRotation
|
||||
{
|
||||
kSPRNone = 0,
|
||||
kSPRFlipHorizontal = 1,
|
||||
kSPRFlipVertical = 2,
|
||||
kSPRRotate180 = 3,
|
||||
kSPRRotate90 = 4
|
||||
None = 0,
|
||||
FlipHorizontal = 1,
|
||||
FlipVertical = 2,
|
||||
Rotate180 = 3,
|
||||
Rotate90 = 4
|
||||
};
|
||||
|
||||
public enum SpritePackingMode
|
||||
{
|
||||
kSPMTight = 0,
|
||||
kSPMRectangle
|
||||
Tight = 0,
|
||||
Rectangle
|
||||
};
|
||||
|
||||
public enum SpriteMeshType
|
||||
{
|
||||
kSpriteMeshTypeFullRect,
|
||||
kSpriteMeshTypeTight
|
||||
FullRect,
|
||||
Tight
|
||||
};
|
||||
|
||||
public class SpriteSettings
|
||||
@@ -182,6 +182,13 @@ namespace AssetStudio
|
||||
public float width;
|
||||
public float height;
|
||||
|
||||
public Rectf(float x, float y, float w, float h) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
public Rectf(BinaryReader reader)
|
||||
{
|
||||
x = reader.ReadSingle();
|
||||
@@ -197,7 +204,7 @@ namespace AssetStudio
|
||||
public Vector2 m_Offset;
|
||||
public Vector4 m_Border;
|
||||
public float m_PixelsToUnits;
|
||||
public Vector2 m_Pivot;
|
||||
public Vector2 m_Pivot = new Vector2(0.5f, 0.5f);
|
||||
public uint m_Extrude;
|
||||
public bool m_IsPolygon;
|
||||
public KeyValuePair<Guid, long> m_RenderDataKey;
|
||||
@@ -205,6 +212,7 @@ namespace AssetStudio
|
||||
public PPtr<SpriteAtlas> m_SpriteAtlas;
|
||||
public SpriteRenderData m_RD;
|
||||
public Vector2[][] m_PhysicsShape;
|
||||
public bool akSplitAlpha;
|
||||
|
||||
public Sprite(ObjectReader reader) : base(reader)
|
||||
{
|
||||
@@ -254,6 +262,8 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
akSplitAlpha = false;
|
||||
|
||||
//vector m_Bones 2018 and up
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace AssetStudio
|
||||
{
|
||||
public PPtr<Sprite>[] m_PackedSprites;
|
||||
public Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> m_RenderDataMap;
|
||||
public bool m_IsVariant;
|
||||
|
||||
public SpriteAtlas(ObjectReader reader) : base(reader)
|
||||
{
|
||||
@@ -67,8 +68,9 @@ namespace AssetStudio
|
||||
var value = new SpriteAtlasData(reader);
|
||||
m_RenderDataMap.Add(new KeyValuePair<Guid, long>(first, second), value);
|
||||
}
|
||||
//string m_Tag
|
||||
//bool m_IsVariant
|
||||
var m_Tag = reader.ReadAlignedString();
|
||||
m_IsVariant = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,9 +90,16 @@ namespace AssetStudio
|
||||
var m_IsPreProcessed = reader.ReadBoolean();
|
||||
}
|
||||
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||
{
|
||||
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] < 5 || (version[0] == 5 && version[1] <= 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();
|
||||
@@ -151,10 +163,13 @@ namespace AssetStudio
|
||||
RGB24,
|
||||
RGBA32,
|
||||
ARGB32,
|
||||
RGB565 = 7,
|
||||
R16 = 9,
|
||||
ARGBFloat,
|
||||
RGB565,
|
||||
BGR24,
|
||||
R16,
|
||||
DXT1,
|
||||
DXT5 = 12,
|
||||
DXT3,
|
||||
DXT5,
|
||||
RGBA4444,
|
||||
BGRA32,
|
||||
RHalf,
|
||||
@@ -165,11 +180,12 @@ namespace AssetStudio
|
||||
RGBAFloat,
|
||||
YUY2,
|
||||
RGB9e5Float,
|
||||
BC4 = 26,
|
||||
BC5,
|
||||
BC6H = 24,
|
||||
RGBFloat,
|
||||
BC6H,
|
||||
BC7,
|
||||
DXT1Crunched = 28,
|
||||
BC4,
|
||||
BC5,
|
||||
DXT1Crunched,
|
||||
DXT5Crunched,
|
||||
PVRTC_RGB2,
|
||||
PVRTC_RGBA2,
|
||||
|
||||
@@ -21,22 +21,27 @@ namespace AssetStudio
|
||||
public ResourceReader m_VideoData;
|
||||
public string m_OriginalPath;
|
||||
public StreamedResource m_ExternalResources;
|
||||
public uint Width;
|
||||
public uint Height;
|
||||
public double m_FrameRate;
|
||||
public int m_Format;
|
||||
public bool m_HasSplitAlpha;
|
||||
|
||||
public VideoClip(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_OriginalPath = reader.ReadAlignedString();
|
||||
var m_ProxyWidth = reader.ReadUInt32();
|
||||
var m_ProxyHeight = reader.ReadUInt32();
|
||||
var Width = reader.ReadUInt32();
|
||||
var Height = reader.ReadUInt32();
|
||||
Width = reader.ReadUInt32();
|
||||
Height = reader.ReadUInt32();
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||
{
|
||||
var m_PixelAspecRatioNum = reader.ReadUInt32();
|
||||
var m_PixelAspecRatioDen = reader.ReadUInt32();
|
||||
}
|
||||
var m_FrameRate = reader.ReadDouble();
|
||||
m_FrameRate = reader.ReadDouble();
|
||||
var m_FrameCount = reader.ReadUInt64();
|
||||
var m_Format = reader.ReadInt32();
|
||||
m_Format = reader.ReadInt32();
|
||||
var m_AudioChannelCount = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
var m_AudioSampleRate = reader.ReadUInt32Array();
|
||||
@@ -51,7 +56,7 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
m_ExternalResources = new StreamedResource(reader);
|
||||
var m_HasSplitAlpha = reader.ReadBoolean();
|
||||
m_HasSplitAlpha = reader.ReadBoolean();
|
||||
if (version[0] >= 2020) //2020.1 and up
|
||||
{
|
||||
var m_sRGB = reader.ReadBoolean();
|
||||
|
||||
49
AssetStudio/ColorConsole.cs
Normal file
49
AssetStudio/ColorConsole.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
// Represents set with 16 base colors using ANSI escape codes, which should be supported in most terminals
|
||||
// (well, except for windows editions before windows 10)
|
||||
public static class ColorConsole
|
||||
{
|
||||
public static readonly string
|
||||
Black = "\u001b[30m",
|
||||
Red = "\u001b[31m",
|
||||
Green = "\u001b[32m",
|
||||
Yellow = "\u001b[33m", //remapped to ~BrightWhite in Windows PowerShell 6
|
||||
Blue = "\u001b[34m",
|
||||
Magenta = "\u001b[35m", //remapped to ~Blue in Windows PowerShell 6
|
||||
Cyan = "\u001b[36m",
|
||||
White = "\u001b[37m",
|
||||
BrightBlack = "\u001b[30;1m",
|
||||
BrightRed = "\u001b[31;1m",
|
||||
BrightGreen = "\u001b[32;1m",
|
||||
BrightYellow = "\u001b[33;1m",
|
||||
BrightBlue = "\u001b[34;1m",
|
||||
BrightMagenta = "\u001b[35;1m",
|
||||
BrightCyan = "\u001b[36;1m",
|
||||
BrightWhite = "\u001b[37;1m";
|
||||
private static readonly string Reset = "\u001b[0m";
|
||||
|
||||
public static string Color(this string str, string ansiColor)
|
||||
{
|
||||
if (!ColorConsoleHelper.isAnsiCodesSupported)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
return $"{ansiColor}{str}{Reset}";
|
||||
}
|
||||
|
||||
public static void AnsiCodesTest()
|
||||
{
|
||||
Console.WriteLine("ANSI escape codes test");
|
||||
Console.WriteLine($"Supported: {ColorConsoleHelper.isAnsiCodesSupported}");
|
||||
Console.WriteLine("\u001b[30m A \u001b[31m B \u001b[32m C \u001b[33m D \u001b[0m");
|
||||
Console.WriteLine("\u001b[34m E \u001b[35m F \u001b[36m G \u001b[37m H \u001b[0m");
|
||||
Console.WriteLine("\u001b[30;1m A \u001b[31;1m B \u001b[32;1m C \u001b[33;1m D \u001b[0m");
|
||||
Console.WriteLine("\u001b[34;1m E \u001b[35;1m F \u001b[36;1m G \u001b[37;1m H \u001b[0m");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
57
AssetStudio/ColorConsoleHelper.cs
Normal file
57
AssetStudio/ColorConsoleHelper.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
// Based on code by tomzorz (https://gist.github.com/tomzorz/6142d69852f831fb5393654c90a1f22e)
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
internal static class ColorConsoleHelper
|
||||
{
|
||||
public static readonly bool isAnsiCodesSupported;
|
||||
private const int STD_OUTPUT_HANDLE = -11;
|
||||
private const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern IntPtr GetStdHandle(int nStdHandle);
|
||||
|
||||
static ColorConsoleHelper()
|
||||
{
|
||||
var isWin = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
if (isWin)
|
||||
{
|
||||
isAnsiCodesSupported = TryEnableVTMode();
|
||||
if (!isAnsiCodesSupported)
|
||||
{
|
||||
//Check for bash terminal emulator. E.g., Git Bash, Cmder
|
||||
isAnsiCodesSupported = Environment.GetEnvironmentVariable("TERM") != null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isAnsiCodesSupported = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable support for ANSI escape codes
|
||||
// (but probably only suitable for windows 10+)
|
||||
// https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
|
||||
private static bool TryEnableVTMode()
|
||||
{
|
||||
var iStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
if (!GetConsoleMode(iStdOut, out uint outConsoleMode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
outConsoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
|
||||
return SetConsoleMode(iStdOut, outConsoleMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Buffers.Binary;
|
||||
using System.IO;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum EndianType
|
||||
{
|
||||
LittleEndian,
|
||||
BigEndian
|
||||
}
|
||||
|
||||
public class EndianBinaryReader : BinaryReader
|
||||
{
|
||||
public EndianType endian;
|
||||
private readonly byte[] buffer;
|
||||
|
||||
public EndianType Endian;
|
||||
|
||||
public EndianBinaryReader(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream)
|
||||
{
|
||||
this.endian = endian;
|
||||
Endian = endian;
|
||||
buffer = new byte[8];
|
||||
}
|
||||
|
||||
public long Position
|
||||
@@ -28,88 +24,82 @@ namespace AssetStudio
|
||||
|
||||
public override short ReadInt16()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(2);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToInt16(buff, 0);
|
||||
Read(buffer, 0, 2);
|
||||
return BinaryPrimitives.ReadInt16BigEndian(buffer);
|
||||
}
|
||||
return base.ReadInt16();
|
||||
}
|
||||
|
||||
public override int ReadInt32()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(4);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToInt32(buff, 0);
|
||||
Read(buffer, 0, 4);
|
||||
return BinaryPrimitives.ReadInt32BigEndian(buffer);
|
||||
}
|
||||
return base.ReadInt32();
|
||||
}
|
||||
|
||||
public override long ReadInt64()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(8);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToInt64(buff, 0);
|
||||
Read(buffer, 0, 8);
|
||||
return BinaryPrimitives.ReadInt64BigEndian(buffer);
|
||||
}
|
||||
return base.ReadInt64();
|
||||
}
|
||||
|
||||
public override ushort ReadUInt16()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(2);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt16(buff, 0);
|
||||
Read(buffer, 0, 2);
|
||||
return BinaryPrimitives.ReadUInt16BigEndian(buffer);
|
||||
}
|
||||
return base.ReadUInt16();
|
||||
}
|
||||
|
||||
public override uint ReadUInt32()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(4);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt32(buff, 0);
|
||||
Read(buffer, 0, 4);
|
||||
return BinaryPrimitives.ReadUInt32BigEndian(buffer);
|
||||
}
|
||||
return base.ReadUInt32();
|
||||
}
|
||||
|
||||
public override ulong ReadUInt64()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(8);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt64(buff, 0);
|
||||
Read(buffer, 0, 8);
|
||||
return BinaryPrimitives.ReadUInt64BigEndian(buffer);
|
||||
}
|
||||
return base.ReadUInt64();
|
||||
}
|
||||
|
||||
public override float ReadSingle()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(4);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToSingle(buff, 0);
|
||||
Read(buffer, 0, 4);
|
||||
Array.Reverse(buffer, 0, 4);
|
||||
return BitConverter.ToSingle(buffer, 0);
|
||||
}
|
||||
return base.ReadSingle();
|
||||
}
|
||||
|
||||
public override double ReadDouble()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(8);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt64(buff, 0);
|
||||
Read(buffer, 0, 8);
|
||||
Array.Reverse(buffer);
|
||||
return BitConverter.ToDouble(buffer, 0);
|
||||
}
|
||||
return base.ReadDouble();
|
||||
}
|
||||
|
||||
14
AssetStudio/EndianType.cs
Normal file
14
AssetStudio/EndianType.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum EndianType
|
||||
{
|
||||
LittleEndian,
|
||||
BigEndian
|
||||
}
|
||||
}
|
||||
@@ -35,10 +35,13 @@ namespace AssetStudio
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string ReadStringToNull(this BinaryReader reader, int maxLength = 32767)
|
||||
public static string ReadStringToNull(this BinaryReader reader, int maxLength = 32767, Encoding encoding = null)
|
||||
{
|
||||
if (encoding?.CodePage == 1200) //Unicode (UTF-16LE)
|
||||
return reader.ReadUnicodeStringToNull(maxLength * 2);
|
||||
|
||||
var bytes = new List<byte>();
|
||||
int count = 0;
|
||||
var count = 0;
|
||||
while (reader.BaseStream.Position != reader.BaseStream.Length && count < maxLength)
|
||||
{
|
||||
var b = reader.ReadByte();
|
||||
@@ -49,7 +52,24 @@ namespace AssetStudio
|
||||
bytes.Add(b);
|
||||
count++;
|
||||
}
|
||||
return Encoding.UTF8.GetString(bytes.ToArray());
|
||||
return encoding?.GetString(bytes.ToArray()) ?? Encoding.UTF8.GetString(bytes.ToArray());
|
||||
}
|
||||
|
||||
private static string ReadUnicodeStringToNull(this BinaryReader reader, int maxLength)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
var count = 0;
|
||||
while (reader.BaseStream.Position != reader.BaseStream.Length && count < maxLength)
|
||||
{
|
||||
var b = reader.ReadBytes(2);
|
||||
if (b.Length < 2 || (b[0] == 0 && b[1] == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
bytes.AddRange(b);
|
||||
count += 2;
|
||||
}
|
||||
return Encoding.Unicode.GetString(bytes.ToArray());
|
||||
}
|
||||
|
||||
public static Quaternion ReadQuaternion(this BinaryReader reader)
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace AssetStudio
|
||||
|
||||
private static readonly byte[] gzipMagic = { 0x1f, 0x8b };
|
||||
private static readonly byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
|
||||
private static readonly byte[] zipMagic = { 0x50, 0x4B, 0x03, 0x04 };
|
||||
private static readonly byte[] zipSpannedMagic = { 0x50, 0x4B, 0x07, 0x08 };
|
||||
|
||||
public FileReader(string path) : this(path, File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { }
|
||||
|
||||
@@ -36,7 +38,7 @@ namespace AssetStudio
|
||||
return FileType.WebFile;
|
||||
default:
|
||||
{
|
||||
var magic = ReadBytes(2);
|
||||
byte[] magic = ReadBytes(2);
|
||||
Position = 0;
|
||||
if (gzipMagic.SequenceEqual(magic))
|
||||
{
|
||||
@@ -53,13 +55,14 @@ namespace AssetStudio
|
||||
{
|
||||
return FileType.AssetsFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
magic = ReadBytes(4);
|
||||
Position = 0;
|
||||
if (zipMagic.SequenceEqual(magic) || zipSpannedMagic.SequenceEqual(magic))
|
||||
return FileType.ZipFile;
|
||||
return FileType.ResourceFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsSerializedFile()
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace AssetStudio
|
||||
WebFile,
|
||||
ResourceFile,
|
||||
GZipFile,
|
||||
BrotliFile
|
||||
BrotliFile,
|
||||
ZipFile
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,28 @@ namespace AssetStudio
|
||||
return null;
|
||||
}
|
||||
|
||||
public ImportedFrame FindRelativeFrameWithPath(string path)
|
||||
{
|
||||
var subs = path.Split(new[] { '/' }, 2);
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (child.Name == subs[0])
|
||||
{
|
||||
if (subs.Length == 1)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = child.FindRelativeFrameWithPath(subs[1]);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ImportedFrame FindFrame(string name)
|
||||
{
|
||||
if (Name == name)
|
||||
|
||||
@@ -16,11 +16,11 @@ namespace AssetStudio
|
||||
|
||||
public interface ILogger
|
||||
{
|
||||
void Log(LoggerEvent loggerEvent, string message);
|
||||
void Log(LoggerEvent loggerEvent, string message, bool ignoreLevel = false);
|
||||
}
|
||||
|
||||
public sealed class DummyLogger : ILogger
|
||||
{
|
||||
public void Log(LoggerEvent loggerEvent, string message) { }
|
||||
public void Log(LoggerEvent loggerEvent, string message, bool ignoreLevel) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public interface IProgress
|
||||
{
|
||||
void Report(int value);
|
||||
}
|
||||
|
||||
public sealed class DummyProgress : IProgress
|
||||
{
|
||||
public void Report(int value) { }
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,8 @@ namespace AssetStudio
|
||||
}
|
||||
|
||||
public static FileReader DecompressGZip(FileReader reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (reader)
|
||||
{
|
||||
@@ -64,6 +66,13 @@ namespace AssetStudio
|
||||
return new FileReader(reader.FullPath, stream);
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Logger.Warning($"Error while decompressing gzip file {reader.FullPath}\r\n{e}");
|
||||
reader.Dispose();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static FileReader DecompressBrotli(FileReader reader)
|
||||
{
|
||||
|
||||
75
AssetStudio/LZ4/LZ4.cs
Normal file
75
AssetStudio/LZ4/LZ4.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class LZ4
|
||||
{
|
||||
public static LZ4 Instance => new LZ4();
|
||||
|
||||
public virtual int Decompress(ReadOnlySpan<byte> cmp, Span<byte> dec)
|
||||
{
|
||||
int cmpPos = 0;
|
||||
int decPos = 0;
|
||||
|
||||
do
|
||||
{
|
||||
var (encCount, litCount) = GetLiteralToken(cmp, ref cmpPos);
|
||||
|
||||
//Copy literal chunk
|
||||
litCount = GetLength(litCount, cmp, ref cmpPos);
|
||||
|
||||
cmp.Slice(cmpPos, litCount).CopyTo(dec.Slice(decPos));
|
||||
|
||||
cmpPos += litCount;
|
||||
decPos += litCount;
|
||||
|
||||
if (cmpPos >= cmp.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//Copy compressed chunk
|
||||
int back = GetChunkEnd(cmp, ref cmpPos);
|
||||
|
||||
encCount = GetLength(encCount, cmp, ref cmpPos) + 4;
|
||||
|
||||
int encPos = decPos - back;
|
||||
|
||||
if (encCount <= back)
|
||||
{
|
||||
dec.Slice(encPos, encCount).CopyTo(dec.Slice(decPos));
|
||||
decPos += encCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (encCount-- > 0)
|
||||
{
|
||||
dec[decPos++] = dec[encPos++];
|
||||
}
|
||||
}
|
||||
} while (cmpPos < cmp.Length && decPos < dec.Length);
|
||||
|
||||
return decPos;
|
||||
}
|
||||
|
||||
protected virtual (int encCount, int litCount) GetLiteralToken(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
|
||||
((cmp[cmpPos] >> 0) & 0xf, (cmp[cmpPos++] >> 4) & 0xf);
|
||||
|
||||
protected virtual int GetChunkEnd(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
|
||||
cmp[cmpPos++] << 0 | cmp[cmpPos++] << 8;
|
||||
|
||||
protected virtual int GetLength(int length, ReadOnlySpan<byte> cmp, ref int cmpPos)
|
||||
{
|
||||
byte sum;
|
||||
|
||||
if (length == 0xf)
|
||||
{
|
||||
do
|
||||
{
|
||||
length += sum = cmp[cmpPos++];
|
||||
} while (sum == 0xff);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
AssetStudio/LZ4/LZ4Inv.cs
Normal file
15
AssetStudio/LZ4/LZ4Inv.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class LZ4Inv : LZ4
|
||||
{
|
||||
public new static LZ4Inv Instance => new LZ4Inv();
|
||||
|
||||
protected override (int encCount, int litCount) GetLiteralToken(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
|
||||
((cmp[cmpPos] >> 4) & 0xf, (cmp[cmpPos++] >> 0) & 0xf);
|
||||
|
||||
protected override int GetChunkEnd(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
|
||||
cmp[cmpPos++] << 8 | cmp[cmpPos++] << 0;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ namespace AssetStudio
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(message);
|
||||
sb.AppendLine();
|
||||
sb.AppendLine(e.ToString());
|
||||
Default.Log(LoggerEvent.Error, sb.ToString());
|
||||
}
|
||||
|
||||
@@ -1,540 +0,0 @@
|
||||
#define CHECK_ARGS
|
||||
#define CHECK_EOF
|
||||
//#define LOCAL_SHADOW
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Lz4
|
||||
{
|
||||
public class Lz4DecoderStream : Stream
|
||||
{
|
||||
public Lz4DecoderStream(Stream input, long inputLength = long.MaxValue)
|
||||
{
|
||||
Reset(input, inputLength);
|
||||
}
|
||||
|
||||
private void Reset(Stream input, long inputLength = long.MaxValue)
|
||||
{
|
||||
this.inputLength = inputLength;
|
||||
this.input = input;
|
||||
|
||||
phase = DecodePhase.ReadToken;
|
||||
|
||||
decodeBufferPos = 0;
|
||||
|
||||
litLen = 0;
|
||||
matLen = 0;
|
||||
matDst = 0;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing && input != null)
|
||||
{
|
||||
input.Close();
|
||||
}
|
||||
input = null;
|
||||
decodeBuffer = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
private long inputLength;
|
||||
private Stream input;
|
||||
|
||||
//because we might not be able to match back across invocations,
|
||||
//we have to keep the last window's worth of bytes around for reuse
|
||||
//we use a circular buffer for this - every time we write into this
|
||||
//buffer, we also write the same into our output buffer
|
||||
|
||||
private const int DecBufLen = 0x10000;
|
||||
private const int DecBufMask = 0xFFFF;
|
||||
|
||||
private const int InBufLen = 128;
|
||||
|
||||
private byte[] decodeBuffer = new byte[DecBufLen + InBufLen];
|
||||
private int decodeBufferPos, inBufPos, inBufEnd;
|
||||
|
||||
//we keep track of which phase we're in so that we can jump right back
|
||||
//into the correct part of decoding
|
||||
|
||||
private DecodePhase phase;
|
||||
|
||||
private enum DecodePhase
|
||||
{
|
||||
ReadToken,
|
||||
ReadExLiteralLength,
|
||||
CopyLiteral,
|
||||
ReadOffset,
|
||||
ReadExMatchLength,
|
||||
CopyMatch,
|
||||
}
|
||||
|
||||
//state within interruptable phases and across phase boundaries is
|
||||
//kept here - again, so that we can punt out and restart freely
|
||||
|
||||
private int litLen, matLen, matDst;
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
#if CHECK_ARGS
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
if (offset < 0 || count < 0 || buffer.Length - count < offset)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
if (input == null)
|
||||
throw new InvalidOperationException();
|
||||
#endif
|
||||
int nRead, nToRead = count;
|
||||
|
||||
var decBuf = decodeBuffer;
|
||||
|
||||
//the stringy gotos are obnoxious, but their purpose is to
|
||||
//make it *blindingly* obvious how the state machine transitions
|
||||
//back and forth as it reads - remember, we can yield out of
|
||||
//this routine in several places, and we must be able to re-enter
|
||||
//and pick up where we left off!
|
||||
|
||||
#if LOCAL_SHADOW
|
||||
var phase = this.phase;
|
||||
var inBufPos = this.inBufPos;
|
||||
var inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
switch (phase)
|
||||
{
|
||||
case DecodePhase.ReadToken:
|
||||
goto readToken;
|
||||
|
||||
case DecodePhase.ReadExLiteralLength:
|
||||
goto readExLiteralLength;
|
||||
|
||||
case DecodePhase.CopyLiteral:
|
||||
goto copyLiteral;
|
||||
|
||||
case DecodePhase.ReadOffset:
|
||||
goto readOffset;
|
||||
|
||||
case DecodePhase.ReadExMatchLength:
|
||||
goto readExMatchLength;
|
||||
|
||||
case DecodePhase.CopyMatch:
|
||||
goto copyMatch;
|
||||
}
|
||||
|
||||
readToken:
|
||||
int tok;
|
||||
if (inBufPos < inBufEnd)
|
||||
{
|
||||
tok = decBuf[inBufPos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
|
||||
tok = ReadByteCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if (tok == -1)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
litLen = tok >> 4;
|
||||
matLen = (tok & 0xF) + 4;
|
||||
|
||||
switch (litLen)
|
||||
{
|
||||
case 0:
|
||||
phase = DecodePhase.ReadOffset;
|
||||
goto readOffset;
|
||||
|
||||
case 0xF:
|
||||
phase = DecodePhase.ReadExLiteralLength;
|
||||
goto readExLiteralLength;
|
||||
|
||||
default:
|
||||
phase = DecodePhase.CopyLiteral;
|
||||
goto copyLiteral;
|
||||
}
|
||||
|
||||
readExLiteralLength:
|
||||
int exLitLen;
|
||||
if (inBufPos < inBufEnd)
|
||||
{
|
||||
exLitLen = decBuf[inBufPos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
exLitLen = ReadByteCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
|
||||
#if CHECK_EOF
|
||||
if (exLitLen == -1)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
litLen += exLitLen;
|
||||
if (exLitLen == 255)
|
||||
goto readExLiteralLength;
|
||||
|
||||
phase = DecodePhase.CopyLiteral;
|
||||
goto copyLiteral;
|
||||
|
||||
copyLiteral:
|
||||
int nReadLit = litLen < nToRead ? litLen : nToRead;
|
||||
if (nReadLit != 0)
|
||||
{
|
||||
if (inBufPos + nReadLit <= inBufEnd)
|
||||
{
|
||||
int ofs = offset;
|
||||
|
||||
for (int c = nReadLit; c-- != 0;)
|
||||
buffer[ofs++] = decBuf[inBufPos++];
|
||||
|
||||
nRead = nReadLit;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
nRead = ReadCore(buffer, offset, nReadLit);
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if (nRead == 0)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
offset += nRead;
|
||||
nToRead -= nRead;
|
||||
|
||||
litLen -= nRead;
|
||||
|
||||
if (litLen != 0)
|
||||
goto copyLiteral;
|
||||
}
|
||||
|
||||
if (nToRead == 0)
|
||||
goto finish;
|
||||
|
||||
phase = DecodePhase.ReadOffset;
|
||||
goto readOffset;
|
||||
|
||||
readOffset:
|
||||
if (inBufPos + 1 < inBufEnd)
|
||||
{
|
||||
matDst = (decBuf[inBufPos + 1] << 8) | decBuf[inBufPos];
|
||||
inBufPos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
matDst = ReadOffsetCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if (matDst == -1)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (matLen == 15 + 4)
|
||||
{
|
||||
phase = DecodePhase.ReadExMatchLength;
|
||||
goto readExMatchLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
phase = DecodePhase.CopyMatch;
|
||||
goto copyMatch;
|
||||
}
|
||||
|
||||
readExMatchLength:
|
||||
int exMatLen;
|
||||
if (inBufPos < inBufEnd)
|
||||
{
|
||||
exMatLen = decBuf[inBufPos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
exMatLen = ReadByteCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if (exMatLen == -1)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
matLen += exMatLen;
|
||||
if (exMatLen == 255)
|
||||
goto readExMatchLength;
|
||||
|
||||
phase = DecodePhase.CopyMatch;
|
||||
goto copyMatch;
|
||||
|
||||
copyMatch:
|
||||
int nCpyMat = matLen < nToRead ? matLen : nToRead;
|
||||
if (nCpyMat != 0)
|
||||
{
|
||||
nRead = count - nToRead;
|
||||
|
||||
int bufDst = matDst - nRead;
|
||||
if (bufDst > 0)
|
||||
{
|
||||
//offset is fairly far back, we need to pull from the buffer
|
||||
|
||||
int bufSrc = decodeBufferPos - bufDst;
|
||||
if (bufSrc < 0)
|
||||
bufSrc += DecBufLen;
|
||||
int bufCnt = bufDst < nCpyMat ? bufDst : nCpyMat;
|
||||
|
||||
for (int c = bufCnt; c-- != 0;)
|
||||
buffer[offset++] = decBuf[bufSrc++ & DecBufMask];
|
||||
}
|
||||
else
|
||||
{
|
||||
bufDst = 0;
|
||||
}
|
||||
|
||||
int sOfs = offset - matDst;
|
||||
for (int i = bufDst; i < nCpyMat; i++)
|
||||
buffer[offset++] = buffer[sOfs++];
|
||||
|
||||
nToRead -= nCpyMat;
|
||||
matLen -= nCpyMat;
|
||||
}
|
||||
|
||||
if (nToRead == 0)
|
||||
goto finish;
|
||||
|
||||
phase = DecodePhase.ReadToken;
|
||||
goto readToken;
|
||||
|
||||
finish:
|
||||
nRead = count - nToRead;
|
||||
|
||||
int nToBuf = nRead < DecBufLen ? nRead : DecBufLen;
|
||||
int repPos = offset - nToBuf;
|
||||
|
||||
if (nToBuf == DecBufLen)
|
||||
{
|
||||
Buffer.BlockCopy(buffer, repPos, decBuf, 0, DecBufLen);
|
||||
decodeBufferPos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int decPos = decodeBufferPos;
|
||||
|
||||
while (nToBuf-- != 0)
|
||||
decBuf[decPos++ & DecBufMask] = buffer[repPos++];
|
||||
|
||||
decodeBufferPos = decPos & DecBufMask;
|
||||
}
|
||||
|
||||
#if LOCAL_SHADOW
|
||||
this.phase = phase;
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
return nRead;
|
||||
}
|
||||
|
||||
private int ReadByteCore()
|
||||
{
|
||||
var buf = decodeBuffer;
|
||||
|
||||
if (inBufPos == inBufEnd)
|
||||
{
|
||||
int nRead = input.Read(buf, DecBufLen,
|
||||
InBufLen < inputLength ? InBufLen : (int)inputLength);
|
||||
|
||||
#if CHECK_EOF
|
||||
if (nRead == 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
inputLength -= nRead;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead;
|
||||
}
|
||||
|
||||
return buf[inBufPos++];
|
||||
}
|
||||
|
||||
private int ReadOffsetCore()
|
||||
{
|
||||
var buf = decodeBuffer;
|
||||
|
||||
if (inBufPos == inBufEnd)
|
||||
{
|
||||
int nRead = input.Read(buf, DecBufLen,
|
||||
InBufLen < inputLength ? InBufLen : (int)inputLength);
|
||||
|
||||
#if CHECK_EOF
|
||||
if (nRead == 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
inputLength -= nRead;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead;
|
||||
}
|
||||
|
||||
if (inBufEnd - inBufPos == 1)
|
||||
{
|
||||
buf[DecBufLen] = buf[inBufPos];
|
||||
|
||||
int nRead = input.Read(buf, DecBufLen + 1,
|
||||
InBufLen - 1 < inputLength ? InBufLen - 1 : (int)inputLength);
|
||||
|
||||
#if CHECK_EOF
|
||||
if (nRead == 0)
|
||||
{
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + 1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
inputLength -= nRead;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead + 1;
|
||||
}
|
||||
|
||||
int ret = (buf[inBufPos + 1] << 8) | buf[inBufPos];
|
||||
inBufPos += 2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int ReadCore(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int nToRead = count;
|
||||
|
||||
var buf = decodeBuffer;
|
||||
int inBufLen = inBufEnd - inBufPos;
|
||||
|
||||
int fromBuf = nToRead < inBufLen ? nToRead : inBufLen;
|
||||
if (fromBuf != 0)
|
||||
{
|
||||
var bufPos = inBufPos;
|
||||
|
||||
for (int c = fromBuf; c-- != 0;)
|
||||
buffer[offset++] = buf[bufPos++];
|
||||
|
||||
inBufPos = bufPos;
|
||||
nToRead -= fromBuf;
|
||||
}
|
||||
|
||||
if (nToRead != 0)
|
||||
{
|
||||
int nRead;
|
||||
|
||||
if (nToRead >= InBufLen)
|
||||
{
|
||||
nRead = input.Read(buffer, offset,
|
||||
nToRead < inputLength ? nToRead : (int)inputLength);
|
||||
nToRead -= nRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
nRead = input.Read(buf, DecBufLen,
|
||||
InBufLen < inputLength ? InBufLen : (int)inputLength);
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead;
|
||||
|
||||
fromBuf = nToRead < nRead ? nToRead : nRead;
|
||||
|
||||
var bufPos = inBufPos;
|
||||
|
||||
for (int c = fromBuf; c-- != 0;)
|
||||
buffer[offset++] = buf[bufPos++];
|
||||
|
||||
inBufPos = bufPos;
|
||||
nToRead -= fromBuf;
|
||||
}
|
||||
|
||||
inputLength -= nRead;
|
||||
}
|
||||
|
||||
return count - nToRead;
|
||||
}
|
||||
|
||||
#region Stream internals
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override bool CanSeek => false;
|
||||
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
public override long Length => throw new NotSupportedException();
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get => throw new NotSupportedException();
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ namespace AssetStudio
|
||||
public int[] version => assetsFile.version;
|
||||
public BuildType buildType => assetsFile.buildType;
|
||||
|
||||
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.endian)
|
||||
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.Endian)
|
||||
{
|
||||
this.assetsFile = assetsFile;
|
||||
m_PathID = objectInfo.m_PathID;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
namespace AssetStudio
|
||||
using System;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static class Progress
|
||||
{
|
||||
public static IProgress Default = new DummyProgress();
|
||||
public static IProgress<int> Default = new Progress<int>();
|
||||
private static int preValue;
|
||||
|
||||
public static void Reset()
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace AssetStudio
|
||||
private long size;
|
||||
private BinaryReader reader;
|
||||
|
||||
public int Size { get => (int)size; }
|
||||
|
||||
public ResourceReader(string path, SerializedFile assetsFile, long offset, long size)
|
||||
{
|
||||
needSearch = true;
|
||||
@@ -69,6 +71,13 @@ namespace AssetStudio
|
||||
return binaryReader.ReadBytes((int)size);
|
||||
}
|
||||
|
||||
public void GetData(byte[] buff)
|
||||
{
|
||||
var binaryReader = GetReader();
|
||||
binaryReader.BaseStream.Position = offset;
|
||||
binaryReader.Read(buff, 0, (int)size);
|
||||
}
|
||||
|
||||
public void WriteData(string path)
|
||||
{
|
||||
var binaryReader = GetReader();
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace AssetStudio
|
||||
header.m_Version = (SerializedFileFormatVersion)reader.ReadUInt32();
|
||||
header.m_DataOffset = reader.ReadUInt32();
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_9)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_9)
|
||||
{
|
||||
header.m_Endianess = reader.ReadByte();
|
||||
header.m_Reserved = reader.ReadBytes(3);
|
||||
@@ -57,7 +57,7 @@ namespace AssetStudio
|
||||
m_FileEndianess = reader.ReadByte();
|
||||
}
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kLargeFilesSupport)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.LargeFilesSupport)
|
||||
{
|
||||
header.m_MetadataSize = reader.ReadUInt32();
|
||||
header.m_FileSize = reader.ReadInt64();
|
||||
@@ -68,14 +68,14 @@ namespace AssetStudio
|
||||
// ReadMetadata
|
||||
if (m_FileEndianess == 0)
|
||||
{
|
||||
reader.endian = EndianType.LittleEndian;
|
||||
reader.Endian = EndianType.LittleEndian;
|
||||
}
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_7)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_7)
|
||||
{
|
||||
unityVersion = reader.ReadStringToNull();
|
||||
SetVersion(unityVersion);
|
||||
}
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_8)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_8)
|
||||
{
|
||||
m_TargetPlatform = (BuildTarget)reader.ReadInt32();
|
||||
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
|
||||
@@ -83,7 +83,7 @@ namespace AssetStudio
|
||||
m_TargetPlatform = BuildTarget.UnknownPlatform;
|
||||
}
|
||||
}
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kHasTypeTreeHashes)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.HasTypeTreeHashes)
|
||||
{
|
||||
m_EnableTypeTree = reader.ReadBoolean();
|
||||
}
|
||||
@@ -96,7 +96,7 @@ namespace AssetStudio
|
||||
m_Types.Add(ReadSerializedType(false));
|
||||
}
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_7 && header.m_Version < SerializedFileFormatVersion.kUnknown_14)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_7 && header.m_Version < SerializedFileFormatVersion.Unknown_14)
|
||||
{
|
||||
bigIDEnabled = reader.ReadInt32();
|
||||
}
|
||||
@@ -113,7 +113,7 @@ namespace AssetStudio
|
||||
{
|
||||
objectInfo.m_PathID = reader.ReadInt64();
|
||||
}
|
||||
else if (header.m_Version < SerializedFileFormatVersion.kUnknown_14)
|
||||
else if (header.m_Version < SerializedFileFormatVersion.Unknown_14)
|
||||
{
|
||||
objectInfo.m_PathID = reader.ReadInt32();
|
||||
}
|
||||
@@ -123,7 +123,7 @@ namespace AssetStudio
|
||||
objectInfo.m_PathID = reader.ReadInt64();
|
||||
}
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kLargeFilesSupport)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.LargeFilesSupport)
|
||||
objectInfo.byteStart = reader.ReadInt64();
|
||||
else
|
||||
objectInfo.byteStart = reader.ReadUInt32();
|
||||
@@ -131,7 +131,7 @@ namespace AssetStudio
|
||||
objectInfo.byteStart += header.m_DataOffset;
|
||||
objectInfo.byteSize = reader.ReadUInt32();
|
||||
objectInfo.typeID = reader.ReadInt32();
|
||||
if (header.m_Version < SerializedFileFormatVersion.kRefactoredClassId)
|
||||
if (header.m_Version < SerializedFileFormatVersion.RefactoredClassId)
|
||||
{
|
||||
objectInfo.classID = reader.ReadUInt16();
|
||||
objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
|
||||
@@ -142,24 +142,24 @@ namespace AssetStudio
|
||||
objectInfo.serializedType = type;
|
||||
objectInfo.classID = type.classID;
|
||||
}
|
||||
if (header.m_Version < SerializedFileFormatVersion.kHasScriptTypeIndex)
|
||||
if (header.m_Version < SerializedFileFormatVersion.HasScriptTypeIndex)
|
||||
{
|
||||
objectInfo.isDestroyed = reader.ReadUInt16();
|
||||
}
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kHasScriptTypeIndex && header.m_Version < SerializedFileFormatVersion.kRefactorTypeData)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.HasScriptTypeIndex && header.m_Version < SerializedFileFormatVersion.RefactorTypeData)
|
||||
{
|
||||
var m_ScriptTypeIndex = reader.ReadInt16();
|
||||
if (objectInfo.serializedType != null)
|
||||
objectInfo.serializedType.m_ScriptTypeIndex = m_ScriptTypeIndex;
|
||||
}
|
||||
if (header.m_Version == SerializedFileFormatVersion.kSupportsStrippedObject || header.m_Version == SerializedFileFormatVersion.kRefactoredClassId)
|
||||
if (header.m_Version == SerializedFileFormatVersion.SupportsStrippedObject || header.m_Version == SerializedFileFormatVersion.RefactoredClassId)
|
||||
{
|
||||
objectInfo.stripped = reader.ReadByte();
|
||||
}
|
||||
m_Objects.Add(objectInfo);
|
||||
}
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kHasScriptTypeIndex)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.HasScriptTypeIndex)
|
||||
{
|
||||
int scriptCount = reader.ReadInt32();
|
||||
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount);
|
||||
@@ -167,7 +167,7 @@ namespace AssetStudio
|
||||
{
|
||||
var m_ScriptType = new LocalSerializedObjectIdentifier();
|
||||
m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
|
||||
if (header.m_Version < SerializedFileFormatVersion.kUnknown_14)
|
||||
if (header.m_Version < SerializedFileFormatVersion.Unknown_14)
|
||||
{
|
||||
m_ScriptType.localIdentifierInFile = reader.ReadInt32();
|
||||
}
|
||||
@@ -185,11 +185,11 @@ namespace AssetStudio
|
||||
for (int i = 0; i < externalsCount; i++)
|
||||
{
|
||||
var m_External = new FileIdentifier();
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_6)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_6)
|
||||
{
|
||||
var tempEmpty = reader.ReadStringToNull();
|
||||
}
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_5)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_5)
|
||||
{
|
||||
m_External.guid = new Guid(reader.ReadBytes(16));
|
||||
m_External.type = reader.ReadInt32();
|
||||
@@ -199,7 +199,7 @@ namespace AssetStudio
|
||||
m_Externals.Add(m_External);
|
||||
}
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kSupportsRefObject)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.SupportsRefObject)
|
||||
{
|
||||
int refTypesCount = reader.ReadInt32();
|
||||
m_RefTypes = new List<SerializedType>(refTypesCount);
|
||||
@@ -209,7 +209,7 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_5)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_5)
|
||||
{
|
||||
userInformation = reader.ReadStringToNull();
|
||||
}
|
||||
@@ -223,6 +223,10 @@ namespace AssetStudio
|
||||
{
|
||||
unityVersion = stringVersion;
|
||||
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (buildSplit.Length == 0)
|
||||
throw new NotSupportedException("Specified Unity version is not in a correct format.\n" +
|
||||
"Specify full Unity version, including letters at the end.\n" +
|
||||
"Example: 2017.4.39f1");
|
||||
buildType = new BuildType(buildSplit[0]);
|
||||
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
||||
version = versionSplit.Select(int.Parse).ToArray();
|
||||
@@ -235,23 +239,23 @@ namespace AssetStudio
|
||||
|
||||
type.classID = reader.ReadInt32();
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kRefactoredClassId)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.RefactoredClassId)
|
||||
{
|
||||
type.m_IsStrippedType = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kRefactorTypeData)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.RefactorTypeData)
|
||||
{
|
||||
type.m_ScriptTypeIndex = reader.ReadInt16();
|
||||
}
|
||||
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kHasTypeTreeHashes)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.HasTypeTreeHashes)
|
||||
{
|
||||
if (isRefType && type.m_ScriptTypeIndex >= 0)
|
||||
{
|
||||
type.m_ScriptID = reader.ReadBytes(16);
|
||||
}
|
||||
else if ((header.m_Version < SerializedFileFormatVersion.kRefactoredClassId && type.classID < 0) || (header.m_Version >= SerializedFileFormatVersion.kRefactoredClassId && type.classID == 114))
|
||||
else if ((header.m_Version < SerializedFileFormatVersion.RefactoredClassId && type.classID < 0) || (header.m_Version >= SerializedFileFormatVersion.RefactoredClassId && type.classID == 114))
|
||||
{
|
||||
type.m_ScriptID = reader.ReadBytes(16);
|
||||
}
|
||||
@@ -262,7 +266,7 @@ namespace AssetStudio
|
||||
{
|
||||
type.m_Type = new TypeTree();
|
||||
type.m_Type.m_Nodes = new List<TypeTreeNode>();
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_12 || header.m_Version == SerializedFileFormatVersion.kUnknown_10)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_12 || header.m_Version == SerializedFileFormatVersion.Unknown_10)
|
||||
{
|
||||
TypeTreeBlobRead(type.m_Type);
|
||||
}
|
||||
@@ -270,7 +274,7 @@ namespace AssetStudio
|
||||
{
|
||||
ReadTypeTree(type.m_Type);
|
||||
}
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kStoresTypeDependencies)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.StoresTypeDependencies)
|
||||
{
|
||||
if (isRefType)
|
||||
{
|
||||
@@ -296,17 +300,17 @@ namespace AssetStudio
|
||||
typeTreeNode.m_Type = reader.ReadStringToNull();
|
||||
typeTreeNode.m_Name = reader.ReadStringToNull();
|
||||
typeTreeNode.m_ByteSize = reader.ReadInt32();
|
||||
if (header.m_Version == SerializedFileFormatVersion.kUnknown_2)
|
||||
if (header.m_Version == SerializedFileFormatVersion.Unknown_2)
|
||||
{
|
||||
var variableCount = reader.ReadInt32();
|
||||
}
|
||||
if (header.m_Version != SerializedFileFormatVersion.kUnknown_3)
|
||||
if (header.m_Version != SerializedFileFormatVersion.Unknown_3)
|
||||
{
|
||||
typeTreeNode.m_Index = reader.ReadInt32();
|
||||
}
|
||||
typeTreeNode.m_TypeFlags = reader.ReadInt32();
|
||||
typeTreeNode.m_Version = reader.ReadInt32();
|
||||
if (header.m_Version != SerializedFileFormatVersion.kUnknown_3)
|
||||
if (header.m_Version != SerializedFileFormatVersion.Unknown_3)
|
||||
{
|
||||
typeTreeNode.m_MetaFlag = reader.ReadInt32();
|
||||
}
|
||||
@@ -334,7 +338,7 @@ namespace AssetStudio
|
||||
typeTreeNode.m_ByteSize = reader.ReadInt32();
|
||||
typeTreeNode.m_Index = reader.ReadInt32();
|
||||
typeTreeNode.m_MetaFlag = reader.ReadInt32();
|
||||
if (header.m_Version >= SerializedFileFormatVersion.kTypeTreeNodeWithTypeFlags)
|
||||
if (header.m_Version >= SerializedFileFormatVersion.TypeTreeNodeWithTypeFlags)
|
||||
{
|
||||
typeTreeNode.m_RefTypeHash = reader.ReadUInt64();
|
||||
}
|
||||
|
||||
@@ -8,80 +8,80 @@ namespace AssetStudio
|
||||
{
|
||||
public enum SerializedFileFormatVersion
|
||||
{
|
||||
kUnsupported = 1,
|
||||
kUnknown_2 = 2,
|
||||
kUnknown_3 = 3,
|
||||
Unsupported = 1,
|
||||
Unknown_2 = 2,
|
||||
Unknown_3 = 3,
|
||||
/// <summary>
|
||||
/// 1.2.0 to 2.0.0
|
||||
/// </summary>
|
||||
kUnknown_5 = 5,
|
||||
Unknown_5 = 5,
|
||||
/// <summary>
|
||||
/// 2.1.0 to 2.6.1
|
||||
/// </summary>
|
||||
kUnknown_6 = 6,
|
||||
Unknown_6 = 6,
|
||||
/// <summary>
|
||||
/// 3.0.0b
|
||||
/// </summary>
|
||||
kUnknown_7 = 7,
|
||||
Unknown_7 = 7,
|
||||
/// <summary>
|
||||
/// 3.0.0 to 3.4.2
|
||||
/// </summary>
|
||||
kUnknown_8 = 8,
|
||||
Unknown_8 = 8,
|
||||
/// <summary>
|
||||
/// 3.5.0 to 4.7.2
|
||||
/// </summary>
|
||||
kUnknown_9 = 9,
|
||||
Unknown_9 = 9,
|
||||
/// <summary>
|
||||
/// 5.0.0aunk1
|
||||
/// </summary>
|
||||
kUnknown_10 = 10,
|
||||
Unknown_10 = 10,
|
||||
/// <summary>
|
||||
/// 5.0.0aunk2
|
||||
/// </summary>
|
||||
kHasScriptTypeIndex = 11,
|
||||
HasScriptTypeIndex = 11,
|
||||
/// <summary>
|
||||
/// 5.0.0aunk3
|
||||
/// </summary>
|
||||
kUnknown_12 = 12,
|
||||
Unknown_12 = 12,
|
||||
/// <summary>
|
||||
/// 5.0.0aunk4
|
||||
/// </summary>
|
||||
kHasTypeTreeHashes = 13,
|
||||
HasTypeTreeHashes = 13,
|
||||
/// <summary>
|
||||
/// 5.0.0unk
|
||||
/// </summary>
|
||||
kUnknown_14 = 14,
|
||||
Unknown_14 = 14,
|
||||
/// <summary>
|
||||
/// 5.0.1 to 5.4.0
|
||||
/// </summary>
|
||||
kSupportsStrippedObject = 15,
|
||||
SupportsStrippedObject = 15,
|
||||
/// <summary>
|
||||
/// 5.5.0a
|
||||
/// </summary>
|
||||
kRefactoredClassId = 16,
|
||||
RefactoredClassId = 16,
|
||||
/// <summary>
|
||||
/// 5.5.0unk to 2018.4
|
||||
/// </summary>
|
||||
kRefactorTypeData = 17,
|
||||
RefactorTypeData = 17,
|
||||
/// <summary>
|
||||
/// 2019.1a
|
||||
/// </summary>
|
||||
kRefactorShareableTypeTreeData = 18,
|
||||
RefactorShareableTypeTreeData = 18,
|
||||
/// <summary>
|
||||
/// 2019.1unk
|
||||
/// </summary>
|
||||
kTypeTreeNodeWithTypeFlags = 19,
|
||||
TypeTreeNodeWithTypeFlags = 19,
|
||||
/// <summary>
|
||||
/// 2019.2
|
||||
/// </summary>
|
||||
kSupportsRefObject = 20,
|
||||
SupportsRefObject = 20,
|
||||
/// <summary>
|
||||
/// 2019.3 to 2019.4
|
||||
/// </summary>
|
||||
kStoresTypeDependencies = 21,
|
||||
StoresTypeDependencies = 21,
|
||||
/// <summary>
|
||||
/// 2020.1 to x
|
||||
/// </summary>
|
||||
kLargeFilesSupport = 22
|
||||
LargeFilesSupport = 22
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
@@ -39,9 +40,11 @@ namespace AssetStudio
|
||||
value = reader.ReadSByte();
|
||||
break;
|
||||
case "UInt8":
|
||||
case "char":
|
||||
value = reader.ReadByte();
|
||||
break;
|
||||
case "char":
|
||||
value = BitConverter.ToChar(reader.ReadBytes(2), 0);
|
||||
break;
|
||||
case "short":
|
||||
case "SInt16":
|
||||
value = reader.ReadInt16();
|
||||
@@ -81,7 +84,8 @@ namespace AssetStudio
|
||||
append = false;
|
||||
var str = reader.ReadAlignedString();
|
||||
sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str);
|
||||
i += 3;
|
||||
var toSkip = GetNodes(m_Nodes, i);
|
||||
i += toSkip.Count - 1;
|
||||
break;
|
||||
case "map":
|
||||
{
|
||||
@@ -190,9 +194,11 @@ namespace AssetStudio
|
||||
value = reader.ReadSByte();
|
||||
break;
|
||||
case "UInt8":
|
||||
case "char":
|
||||
value = reader.ReadByte();
|
||||
break;
|
||||
case "char":
|
||||
value = BitConverter.ToChar(reader.ReadBytes(2), 0);
|
||||
break;
|
||||
case "short":
|
||||
case "SInt16":
|
||||
value = reader.ReadInt16();
|
||||
@@ -230,7 +236,8 @@ namespace AssetStudio
|
||||
break;
|
||||
case "string":
|
||||
value = reader.ReadAlignedString();
|
||||
i += 3;
|
||||
var toSkip = GetNodes(m_Nodes, i);
|
||||
i += toSkip.Count - 1;
|
||||
break;
|
||||
case "map":
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace AssetStudio
|
||||
|
||||
public WebFile(EndianBinaryReader reader)
|
||||
{
|
||||
reader.endian = EndianType.LittleEndian;
|
||||
reader.Endian = EndianType.LittleEndian;
|
||||
var signature = reader.ReadStringToNull();
|
||||
var headLength = reader.ReadInt32();
|
||||
var dataList = new List<WebData>();
|
||||
|
||||
114
AssetStudioCLI/AssetStudioCLI.csproj
Normal file
114
AssetStudioCLI/AssetStudioCLI.csproj
Normal file
@@ -0,0 +1,114 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net472;net6.0;net7.0;net8.0</TargetFrameworks>
|
||||
<AssemblyTitle>ArknightsStudio by aelurum</AssemblyTitle>
|
||||
<AssemblyName>ArknightsStudioCLI</AssemblyName>
|
||||
<Version>1.2.0</Version>
|
||||
<Copyright>Copyright © Perfare; Copyright © aelurum 2025</Copyright>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj" />
|
||||
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Use local compiled win-x86 and win-x64 Texture2DDecoder libs, because libs from Kyaru.Texture2DDecoder.Windows were compiled with /MD flag -->
|
||||
|
||||
<Target Name="CopyExtraFilesPortable" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == '' ">
|
||||
<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\x64\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(ProjectDir)Libraries\win-x86\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(ProjectDir)Libraries\win-x64\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyExtraFilesPortableNet" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == '' AND '$(TargetFramework)' != 'net472' ">
|
||||
<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-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-arm64\libfmod.dylib" DestinationFolder="$(TargetDir)runtimes\osx-arm64\native" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Publishing an app as framework-dependent produces a cross-platform binary as a dll file, and a platform-specific executable that targets your current platform.
|
||||
The dll is cross-platform while the executable isn't -->
|
||||
<Target Name="PublishExtraFilesPortable" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == '' ">
|
||||
<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-x64\native\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(TargetDir)runtimes\win-x86\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishExtraFilesPortableNet" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == '' AND '$(TargetFramework)' != 'net472' ">
|
||||
<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-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-arm64\native\libfmod.dylib" DestinationFolder="$(PublishDir)runtimes\osx-arm64\native" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyExtraFilesWin86" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-x86' ">
|
||||
<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="$(ProjectDir)Libraries\win-x86\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyExtraFilesWin64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-x64' ">
|
||||
<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="$(ProjectDir)Libraries\win-x64\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishExtraFilesWin" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('win-x')) ">
|
||||
<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)\fmod.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyExtraFilesLinux64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'linux-x64' ">
|
||||
<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" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishExtraFilesLinux64" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == 'linux-x64' ">
|
||||
<Message Text="Publishing extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
|
||||
<Copy SourceFiles="$(TargetDir)\libAssetStudioFBXNative.so" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(TargetDir)\libfmod.so" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyExtraFilesMac" AfterTargets="AfterBuild" Condition=" $(RuntimeIdentifier.Contains('osx-')) ">
|
||||
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
|
||||
<Copy SourceFiles="$(ProjectDir)Libraries\$(RuntimeIdentifier)\libAssetStudioFBXNative.dylib" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(ProjectDir)Libraries\$(RuntimeIdentifier)\libfmod.dylib" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishExtraFilesMac" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('osx-')) ">
|
||||
<Message Text="Publishing extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
|
||||
<Copy SourceFiles="$(TargetDir)\libAssetStudioFBXNative.dylib" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(TargetDir)\libfmod.dylib" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
119
AssetStudioCLI/CLILogger.cs
Normal file
119
AssetStudioCLI/CLILogger.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using AssetStudio;
|
||||
using AssetStudioCLI.Options;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace AssetStudioCLI
|
||||
{
|
||||
internal enum LogOutputMode
|
||||
{
|
||||
Console,
|
||||
File,
|
||||
Both,
|
||||
}
|
||||
|
||||
internal class CLILogger : ILogger
|
||||
{
|
||||
private readonly LogOutputMode logOutput;
|
||||
private readonly LoggerEvent logMinLevel;
|
||||
public string LogName;
|
||||
public string LogPath;
|
||||
|
||||
public CLILogger()
|
||||
{
|
||||
logOutput = CLIOptions.o_logOutput.Value;
|
||||
logMinLevel = CLIOptions.o_logLevel.Value;
|
||||
var appAssembly = typeof(Program).Assembly.GetName();
|
||||
LogName = $"{appAssembly.Name}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log";
|
||||
LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LogName);
|
||||
var arch = Environment.Is64BitProcess ? "x64" : "x32";
|
||||
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||
|
||||
LogToFile(LoggerEvent.Verbose, $"---{appAssembly.Name} v{appAssembly.Version} [{arch}] | Logger launched---\n" +
|
||||
$"CMD Args: {string.Join(" ", CLIOptions.cliArgs)}");
|
||||
}
|
||||
|
||||
private static string ColorLogLevel(LoggerEvent logLevel)
|
||||
{
|
||||
var formattedLevel = $"[{logLevel}]";
|
||||
switch (logLevel)
|
||||
{
|
||||
case LoggerEvent.Info:
|
||||
return $"{formattedLevel.Color(ColorConsole.BrightCyan)}";
|
||||
case LoggerEvent.Warning:
|
||||
return $"{formattedLevel.Color(ColorConsole.BrightYellow)}";
|
||||
case LoggerEvent.Error:
|
||||
return $"{formattedLevel.Color(ColorConsole.BrightRed)}";
|
||||
default:
|
||||
return formattedLevel;
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatMessage(LoggerEvent logMsgLevel, string message, bool consoleMode = false)
|
||||
{
|
||||
var curTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
message = message.TrimEnd();
|
||||
var multiLine = message.Contains('\n');
|
||||
|
||||
string formattedMessage;
|
||||
if (consoleMode)
|
||||
{
|
||||
var colorLogLevel = ColorLogLevel(logMsgLevel);
|
||||
formattedMessage = $"{colorLogLevel} {message}";
|
||||
if (multiLine)
|
||||
{
|
||||
formattedMessage = formattedMessage.Replace("\n", $"\n{colorLogLevel} ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
message = Regex.Replace(message, @"\e\[[0-9;]*m(?:\e\[K)?", ""); //Delete ANSI colors
|
||||
var logLevel = $"{logMsgLevel.ToString().ToUpper(),-7}";
|
||||
formattedMessage = $"{curTime} | {logLevel} | {message}";
|
||||
if (multiLine)
|
||||
{
|
||||
formattedMessage = formattedMessage.Replace("\n", $"\n{curTime} | {logLevel} | ");
|
||||
}
|
||||
}
|
||||
return formattedMessage;
|
||||
}
|
||||
|
||||
public void LogToConsole(LoggerEvent logMsgLevel, string message)
|
||||
{
|
||||
if (logOutput != LogOutputMode.File)
|
||||
{
|
||||
Console.WriteLine(FormatMessage(logMsgLevel, message, consoleMode: true));
|
||||
}
|
||||
}
|
||||
|
||||
public async void LogToFile(LoggerEvent logMsgLevel, string message)
|
||||
{
|
||||
if (logOutput != LogOutputMode.Console)
|
||||
{
|
||||
using (var sw = new StreamWriter(LogPath, append: true, System.Text.Encoding.UTF8))
|
||||
{
|
||||
await sw.WriteLineAsync(FormatMessage(logMsgLevel, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(LoggerEvent logMsgLevel, string message, bool ignoreLevel)
|
||||
{
|
||||
if ((logMsgLevel < logMinLevel && !ignoreLevel) || string.IsNullOrEmpty(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (logOutput != LogOutputMode.File)
|
||||
{
|
||||
LogToConsole(logMsgLevel, message);
|
||||
}
|
||||
if (logOutput != LogOutputMode.Console)
|
||||
{
|
||||
LogToFile(logMsgLevel, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
231
AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs
Normal file
231
AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
using Arknights.PortraitSpriteMono;
|
||||
using AssetStudio;
|
||||
using AssetStudioCLI;
|
||||
using AssetStudioCLI.Options;
|
||||
using Newtonsoft.Json;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Arknights
|
||||
{
|
||||
internal static class AkSpriteHelper
|
||||
{
|
||||
public static Texture2D TryFindAlphaTex(AssetItem assetItem, AvgSprite avgSprite, bool isAvgSprite)
|
||||
{
|
||||
Sprite m_Sprite = (Sprite)assetItem.Asset;
|
||||
var imgType = "arts/characters";
|
||||
if (m_Sprite.m_RD.alphaTexture.m_PathID == 0)
|
||||
{
|
||||
if (isAvgSprite)
|
||||
{
|
||||
if (avgSprite?.FullAlphaTexture != null)
|
||||
return avgSprite.FullAlphaTexture;
|
||||
|
||||
imgType = "avg/characters"; //since the avg hub was not found for some reason, let's try to find alpha tex by name
|
||||
}
|
||||
var spriteFullName = Path.GetFileNameWithoutExtension(assetItem.Container);
|
||||
foreach (var item in Studio.loadedAssetsList)
|
||||
{
|
||||
if (item.Type == ClassIDType.Texture2D)
|
||||
{
|
||||
if (item.Container.Contains(imgType) && item.Container.Contains($"illust_{m_Sprite.m_Name}_material") && item.Text.Contains("[alpha]"))
|
||||
return (Texture2D)item.Asset;
|
||||
if (item.Container.Contains(imgType) && item.Container.Contains(spriteFullName) && item.Text == $"{m_Sprite.m_Name}[alpha]")
|
||||
return (Texture2D)item.Asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Image<Bgra32> AkGetImage(this Sprite m_Sprite, AvgSprite avgSprite = null, SpriteMaskMode spriteMaskMode = SpriteMaskMode.On)
|
||||
{
|
||||
if (m_Sprite.m_RD.texture.TryGet(out var m_Texture2D) && m_Sprite.m_RD.alphaTexture.TryGet(out var m_AlphaTexture2D) && spriteMaskMode != SpriteMaskMode.Off)
|
||||
{
|
||||
Image<Bgra32> tex;
|
||||
Image<Bgra32> alphaTex;
|
||||
|
||||
if (avgSprite != null && avgSprite.IsHubParsed)
|
||||
{
|
||||
alphaTex = m_AlphaTexture2D.ConvertToImage(true);
|
||||
if (avgSprite.IsFaceSprite)
|
||||
{
|
||||
var faceImage = m_Texture2D.ConvertToImage(true);
|
||||
var faceAlpha = avgSprite.FaceSpriteAlphaTexture.ConvertToImage(true);
|
||||
if (new Size(faceImage.Width, faceImage.Height) != avgSprite.FaceSize)
|
||||
{
|
||||
faceImage.Mutate(x => x.Resize(new ResizeOptions { Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||
faceAlpha.Mutate(x => x.Resize(new ResizeOptions { Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||
}
|
||||
tex = avgSprite.FullTexture.ConvertToImage(true);
|
||||
tex.Mutate(x => x.DrawImage(faceImage, avgSprite.FacePos, opacity: 1f));
|
||||
alphaTex.Mutate(x => x.DrawImage(faceAlpha, avgSprite.FacePos, opacity: 1f));
|
||||
}
|
||||
else
|
||||
{
|
||||
tex = m_Texture2D.ConvertToImage(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tex = CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||
alphaTex = CutImage(m_AlphaTexture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||
}
|
||||
tex.ApplyRGBMask(alphaTex);
|
||||
return tex;
|
||||
}
|
||||
else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D) && avgSprite != null && avgSprite.IsHubParsed)
|
||||
{
|
||||
if (!avgSprite.IsFaceSprite)
|
||||
{
|
||||
return m_Texture2D.ConvertToImage(true);
|
||||
}
|
||||
|
||||
var faceImage = m_Texture2D.ConvertToImage(true);
|
||||
var tex = avgSprite.FullTexture.ConvertToImage(true);
|
||||
if (new Size(faceImage.Width, faceImage.Height) != avgSprite.FaceSize)
|
||||
{
|
||||
faceImage.Mutate(x => x.Resize(new ResizeOptions { Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||
}
|
||||
tex.Mutate(x => x.DrawImage(faceImage, avgSprite.FacePos, opacity: 1f));
|
||||
|
||||
return tex;
|
||||
}
|
||||
else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D))
|
||||
{
|
||||
return CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Image<Bgra32> AkGetImage(this PortraitSprite portraitSprite, SpriteMaskMode spriteMaskMode = SpriteMaskMode.On)
|
||||
{
|
||||
if (portraitSprite.Texture != null && portraitSprite.AlphaTexture != null)
|
||||
{
|
||||
var tex = CutImage(portraitSprite.Texture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||
|
||||
if (spriteMaskMode == SpriteMaskMode.Off)
|
||||
{
|
||||
return tex;
|
||||
}
|
||||
else
|
||||
{
|
||||
var alphaTex = CutImage(portraitSprite.AlphaTexture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||
tex.ApplyRGBMask(alphaTex);
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<PortraitSprite> GeneratePortraits(AssetItem asset)
|
||||
{
|
||||
var portraits = new List<PortraitSprite>();
|
||||
|
||||
var portraitsDict = ((MonoBehaviour)asset.Asset).ToType();
|
||||
if (portraitsDict == null)
|
||||
{
|
||||
Logger.Warning("Portraits MonoBehaviour is not readable.");
|
||||
return portraits;
|
||||
}
|
||||
var portraitsJson = JsonConvert.SerializeObject(portraitsDict);
|
||||
var portraitsData = JsonConvert.DeserializeObject<PortraitSpriteConfig>(portraitsJson);
|
||||
|
||||
if (portraitsData._sprites.Length == 0)
|
||||
return portraits;
|
||||
|
||||
var atlasTex = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == portraitsData._atlas.Texture.m_PathID).Asset;
|
||||
var atlasAlpha = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == portraitsData._atlas.Alpha.m_PathID).Asset;
|
||||
|
||||
foreach (var portraitData in portraitsData._sprites)
|
||||
{
|
||||
var portraitSprite = new PortraitSprite()
|
||||
{
|
||||
Name = portraitData.Name,
|
||||
AssetsFile = atlasTex.assetsFile,
|
||||
Container = asset.Container,
|
||||
Texture = atlasTex,
|
||||
AlphaTexture = atlasAlpha,
|
||||
TextureRect = new Rectf(portraitData.Rect.X, portraitData.Rect.Y, portraitData.Rect.W, portraitData.Rect.H),
|
||||
Rotate = portraitData.Rotate,
|
||||
};
|
||||
portraits.Add(portraitSprite);
|
||||
}
|
||||
|
||||
return portraits;
|
||||
}
|
||||
|
||||
private static void ApplyRGBMask(this Image<Bgra32> tex, Image<Bgra32> texMask)
|
||||
{
|
||||
using (texMask)
|
||||
{
|
||||
bool resized = false;
|
||||
if (tex.Width != texMask.Width || tex.Height != texMask.Height)
|
||||
{
|
||||
texMask.Mutate(x => x.Resize(tex.Width, tex.Height, CLIOptions.o_akAlphaTexResampler.Value));
|
||||
resized = true;
|
||||
}
|
||||
|
||||
var invGamma = 1.0 / (1.0 + CLIOptions.o_akShadowGamma.Value / 10.0);
|
||||
if (CLIOptions.akResizedOnly && !resized)
|
||||
{
|
||||
invGamma = 1.0;
|
||||
}
|
||||
|
||||
tex.ProcessPixelRows(texMask, (sourceTex, targetTexMask) =>
|
||||
{
|
||||
for (int y = 0; y < texMask.Height; y++)
|
||||
{
|
||||
var texRow = sourceTex.GetRowSpan(y);
|
||||
var maskRow = targetTexMask.GetRowSpan(y);
|
||||
for (int x = 0; x < maskRow.Length; x++)
|
||||
{
|
||||
var grayscale = (maskRow[x].R + maskRow[x].G + maskRow[x].B) / 3.0;
|
||||
if (invGamma != 1.0)
|
||||
{
|
||||
grayscale = 255 - Math.Pow((255 - grayscale) / 255, invGamma) * 255;
|
||||
}
|
||||
texRow[x].A = (byte)grayscale;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static Image<Bgra32> CutImage(Image<Bgra32> originalImage, Rectf textureRect, float downscaleMultiplier, bool rotate = false)
|
||||
{
|
||||
if (originalImage != null)
|
||||
{
|
||||
if (downscaleMultiplier > 0f && downscaleMultiplier != 1f)
|
||||
{
|
||||
var newSize = (Size)(new Size(originalImage.Width, originalImage.Height) / downscaleMultiplier);
|
||||
originalImage.Mutate(x => x.Resize(newSize, KnownResamplers.Lanczos3, compand: true));
|
||||
}
|
||||
var rectX = (int)Math.Floor(textureRect.x);
|
||||
var rectY = (int)Math.Floor(textureRect.y);
|
||||
var rectRight = (int)Math.Ceiling(textureRect.x + textureRect.width);
|
||||
var rectBottom = (int)Math.Ceiling(textureRect.y + textureRect.height);
|
||||
rectRight = Math.Min(rectRight, originalImage.Width);
|
||||
rectBottom = Math.Min(rectBottom, originalImage.Height);
|
||||
var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY);
|
||||
var spriteImage = originalImage.Clone(x => x.Crop(rect));
|
||||
originalImage.Dispose();
|
||||
if (rotate)
|
||||
{
|
||||
spriteImage.Mutate(x => x.Rotate(RotateMode.Rotate270));
|
||||
}
|
||||
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
|
||||
|
||||
return spriteImage;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
149
AssetStudioCLI/Components/Arknights/AvgSprite.cs
Normal file
149
AssetStudioCLI/Components/Arknights/AvgSprite.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using Arknights.AvgCharHubMono;
|
||||
using AssetStudio;
|
||||
using AssetStudioCLI;
|
||||
using SixLabors.ImageSharp;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Arknights
|
||||
{
|
||||
internal class AvgSprite
|
||||
{
|
||||
public Texture2D FaceSpriteAlphaTexture { get; }
|
||||
public Texture2D FullTexture { get; }
|
||||
public Texture2D FullAlphaTexture { get; }
|
||||
public Point FacePos { get; }
|
||||
public Size FaceSize { get; }
|
||||
public string Alias { get; }
|
||||
public bool IsWholeBodySprite { get; }
|
||||
public bool IsFaceSprite { get; }
|
||||
public bool IsHubParsed { get; }
|
||||
|
||||
private AvgSpriteConfig GetCurSpriteGroup(AvgSpriteConfigGroup spriteHubDataGrouped, long spriteItemID, string spriteName)
|
||||
{
|
||||
if (spriteHubDataGrouped.SpriteGroups.Length > 1)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(spriteName))
|
||||
{
|
||||
var groupFromName = int.TryParse(spriteName?.Substring(spriteName.IndexOf('$') + 1, 1), out int groupIndex);
|
||||
if (groupFromName)
|
||||
{
|
||||
return spriteHubDataGrouped.SpriteGroups[groupIndex - 1];
|
||||
}
|
||||
}
|
||||
return spriteHubDataGrouped.SpriteGroups.FirstOrDefault(x => x.Sprites.Any(y => y.Sprite.m_PathID == spriteItemID));
|
||||
}
|
||||
else
|
||||
{
|
||||
return spriteHubDataGrouped.SpriteGroups[0];
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryGetSpriteHub(AssetItem assetItem, out AvgSpriteConfig spriteHubData)
|
||||
{
|
||||
spriteHubData = null;
|
||||
var scriptAssets = Studio.loadedAssetsList.FindAll(x =>
|
||||
x.Type == ClassIDType.MonoBehaviour
|
||||
&& x.Container == assetItem.Container);
|
||||
if (scriptAssets.Count == 0)
|
||||
{
|
||||
Logger.Warning("No MonoBehaviours were found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
OrderedDictionary spriteHubDict = null;
|
||||
var isGrouped = false;
|
||||
foreach (var scriptAsset in scriptAssets)
|
||||
{
|
||||
var scriptAssetDict = ((MonoBehaviour)scriptAsset.Asset).ToType();
|
||||
if (scriptAssetDict == null)
|
||||
{
|
||||
Logger.Warning("MonoBehaviour is not readable.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scriptAssetDict.Contains("spriteGroups"))
|
||||
{
|
||||
spriteHubDict = scriptAssetDict;
|
||||
isGrouped = true;
|
||||
break;
|
||||
}
|
||||
if (scriptAssetDict.Contains("sprites"))
|
||||
{
|
||||
spriteHubDict = scriptAssetDict;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spriteHubDict == null)
|
||||
{
|
||||
Logger.Warning("AVGCharacterSpriteHub is not readable.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var spriteHubJson = JsonConvert.SerializeObject(spriteHubDict);
|
||||
if (isGrouped)
|
||||
{
|
||||
var groupedSpriteHub = JsonConvert.DeserializeObject<AvgSpriteConfigGroup>(spriteHubJson);
|
||||
spriteHubData = GetCurSpriteGroup(groupedSpriteHub, assetItem.m_PathID, assetItem.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteHubData = JsonConvert.DeserializeObject<AvgSpriteConfig>(spriteHubJson);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public AvgSprite(AssetItem assetItem)
|
||||
{
|
||||
if (TryGetSpriteHub(assetItem, out var spriteHubData))
|
||||
{
|
||||
IsHubParsed = spriteHubData?.Sprites.Length > 0;
|
||||
}
|
||||
if (IsHubParsed)
|
||||
{
|
||||
var curSpriteData = spriteHubData.Sprites.FirstOrDefault(x => x.Sprite.m_PathID == assetItem.m_PathID);
|
||||
|
||||
if (curSpriteData == null)
|
||||
{
|
||||
Logger.Warning($"Sprite \"{assetItem.Text}\" was not found in the avg sprite hub");
|
||||
return;
|
||||
}
|
||||
|
||||
Alias = curSpriteData.Alias;
|
||||
IsWholeBodySprite = curSpriteData.IsWholeBody;
|
||||
|
||||
if (spriteHubData.FaceSize.X > 0 && spriteHubData.FaceSize.Y > 0) //If face data exist
|
||||
{
|
||||
var fullTexSpriteData = spriteHubData.Sprites.Last(); //Last sprite item in the list usually contains PathID of Sprite with full texture
|
||||
|
||||
var curSprite = (Sprite)assetItem.Asset;
|
||||
IsFaceSprite = curSprite.m_Rect.width <= 256 && curSprite.m_Rect.height <= 256 && curSprite.m_PathID != fullTexSpriteData.Sprite.m_PathID;
|
||||
|
||||
var curSpriteAlphaID = curSpriteData.AlphaTex.m_PathID;
|
||||
var curSpriteAlphaTex = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == curSpriteAlphaID)?.Asset;
|
||||
if (curSpriteAlphaTex != null)
|
||||
{
|
||||
FaceSpriteAlphaTexture = IsFaceSprite ? curSpriteAlphaTex : null;
|
||||
fullTexSpriteData = IsFaceSprite ? fullTexSpriteData : curSpriteData;
|
||||
}
|
||||
var fullTexSpriteID = fullTexSpriteData.Sprite.m_PathID;
|
||||
var fullTexAlphaID = fullTexSpriteData.AlphaTex.m_PathID;
|
||||
var fullTexSprite = (Sprite)Studio.loadedAssetsList.Find(x => x.m_PathID == fullTexSpriteID).Asset;
|
||||
|
||||
FullTexture = fullTexSprite.m_RD.texture.TryGet(out var fullTex) ? fullTex : null;
|
||||
FullAlphaTexture = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == fullTexAlphaID)?.Asset;
|
||||
FacePos = new Point((int)Math.Round(spriteHubData.FacePos.X), (int)Math.Round(spriteHubData.FacePos.Y));
|
||||
FaceSize = new Size((int)Math.Round(spriteHubData.FaceSize.X), (int)Math.Round(spriteHubData.FaceSize.Y));
|
||||
}
|
||||
else
|
||||
{
|
||||
FullAlphaTexture = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == curSpriteData.AlphaTex.m_PathID).Asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
AssetStudioCLI/Components/Arknights/AvgSpriteConfig.cs
Normal file
30
AssetStudioCLI/Components/Arknights/AvgSpriteConfig.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using AssetStudio;
|
||||
|
||||
namespace Arknights.AvgCharHubMono
|
||||
{
|
||||
internal class AvgAssetIDs
|
||||
{
|
||||
public int m_FileID { get; set; }
|
||||
public long m_PathID { get; set; }
|
||||
}
|
||||
|
||||
internal class AvgSpriteData
|
||||
{
|
||||
public AvgAssetIDs Sprite { get; set; }
|
||||
public AvgAssetIDs AlphaTex { get; set; }
|
||||
public string Alias { get; set; }
|
||||
public bool IsWholeBody { get; set; }
|
||||
}
|
||||
|
||||
internal class AvgSpriteConfig
|
||||
{
|
||||
public AvgSpriteData[] Sprites { get; set; }
|
||||
public Vector2 FaceSize { get; set; }
|
||||
public Vector3 FacePos { get; set; }
|
||||
}
|
||||
|
||||
internal class AvgSpriteConfigGroup
|
||||
{
|
||||
public AvgSpriteConfig[] SpriteGroups { get; set; }
|
||||
}
|
||||
}
|
||||
24
AssetStudioCLI/Components/Arknights/PortraitSprite.cs
Normal file
24
AssetStudioCLI/Components/Arknights/PortraitSprite.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using AssetStudio;
|
||||
|
||||
|
||||
namespace Arknights
|
||||
{
|
||||
internal class PortraitSprite
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public ClassIDType Type { get; }
|
||||
public SerializedFile AssetsFile { get; set; }
|
||||
public string Container { get; set; }
|
||||
public Texture2D Texture { get; set; }
|
||||
public Texture2D AlphaTexture { get; set; }
|
||||
public Rectf TextureRect { get; set; }
|
||||
public bool Rotate { get; set; }
|
||||
public float DownscaleMultiplier { get; }
|
||||
|
||||
public PortraitSprite()
|
||||
{
|
||||
Type = ClassIDType.AkPortraitSprite;
|
||||
DownscaleMultiplier = 1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
AssetStudioCLI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
41
AssetStudioCLI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
namespace Arknights.PortraitSpriteMono
|
||||
{
|
||||
internal class PortraitRect
|
||||
{
|
||||
public float X { get; set; }
|
||||
public float Y { get; set; }
|
||||
public float W { get; set; }
|
||||
public float H { get; set; }
|
||||
}
|
||||
|
||||
internal class AtlasSprite
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Guid { get; set; }
|
||||
public int Atlas { get; set; }
|
||||
public PortraitRect Rect { get; set; }
|
||||
public bool Rotate { get; set; }
|
||||
}
|
||||
|
||||
internal class TextureIDs
|
||||
{
|
||||
public int m_FileID { get; set; }
|
||||
public long m_PathID { get; set; }
|
||||
}
|
||||
|
||||
internal class AtlasInfo
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public TextureIDs Texture { get; set; }
|
||||
public TextureIDs Alpha { get; set; }
|
||||
public int Size { get; set; }
|
||||
}
|
||||
|
||||
internal class PortraitSpriteConfig
|
||||
{
|
||||
public string m_Name { get; set; }
|
||||
public AtlasSprite[] _sprites { get; set; }
|
||||
public AtlasInfo _atlas { get; set; }
|
||||
public int _index { get; set; }
|
||||
}
|
||||
}
|
||||
42
AssetStudioCLI/Components/AssetItem.cs
Normal file
42
AssetStudioCLI/Components/AssetItem.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using Arknights;
|
||||
using AssetStudio;
|
||||
|
||||
namespace AssetStudioCLI
|
||||
{
|
||||
internal class AssetItem
|
||||
{
|
||||
public Object Asset;
|
||||
public SerializedFile SourceFile;
|
||||
public string Container = string.Empty;
|
||||
public string TypeString;
|
||||
public long m_PathID;
|
||||
public long FullSize;
|
||||
public ClassIDType Type;
|
||||
public string Text;
|
||||
public string UniqueID;
|
||||
public GameObjectNode Node;
|
||||
public PortraitSprite AkPortraitSprite;
|
||||
|
||||
public AssetItem(Object asset)
|
||||
{
|
||||
Asset = asset;
|
||||
SourceFile = asset.assetsFile;
|
||||
Type = asset.type;
|
||||
TypeString = Type.ToString();
|
||||
m_PathID = asset.m_PathID;
|
||||
FullSize = asset.byteSize;
|
||||
}
|
||||
|
||||
public AssetItem(PortraitSprite akPortraitSprite)
|
||||
{
|
||||
Asset = null;
|
||||
SourceFile = akPortraitSprite.AssetsFile;
|
||||
Container = akPortraitSprite.Container;
|
||||
Type = akPortraitSprite.Type;
|
||||
TypeString = Type.ToString();
|
||||
Text = akPortraitSprite.Name;
|
||||
m_PathID = -1;
|
||||
AkPortraitSprite = akPortraitSprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
AssetStudioCLI/Components/BaseNode.cs
Normal file
16
AssetStudioCLI/Components/BaseNode.cs
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
16
AssetStudioCLI/Components/GameObjectNode.cs
Normal file
16
AssetStudioCLI/Components/GameObjectNode.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
550
AssetStudioCLI/Exporter.cs
Normal file
550
AssetStudioCLI/Exporter.cs
Normal file
@@ -0,0 +1,550 @@
|
||||
using Arknights;
|
||||
using AssetStudio;
|
||||
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;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace AssetStudioCLI
|
||||
{
|
||||
internal static class Exporter
|
||||
{
|
||||
public static bool ExportTexture2D(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_Texture2D = (Texture2D)item.Asset;
|
||||
if (CLIOptions.convertTexture)
|
||||
{
|
||||
var type = CLIOptions.o_imageFormat.Value;
|
||||
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
||||
return false;
|
||||
|
||||
if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"Converting \"{m_Texture2D.m_Name}\" to {type}..");
|
||||
sb.AppendLine($"Width: {m_Texture2D.m_Width}");
|
||||
sb.AppendLine($"Height: {m_Texture2D.m_Height}");
|
||||
sb.AppendLine($"Format: {m_Texture2D.m_TextureFormat}");
|
||||
switch (m_Texture2D.m_TextureSettings.m_FilterMode)
|
||||
{
|
||||
case 0: sb.AppendLine("Filter Mode: Point "); break;
|
||||
case 1: sb.AppendLine("Filter Mode: Bilinear "); break;
|
||||
case 2: sb.AppendLine("Filter Mode: Trilinear "); break;
|
||||
}
|
||||
sb.AppendLine($"Anisotropic level: {m_Texture2D.m_TextureSettings.m_Aniso}");
|
||||
sb.AppendLine($"Mip map bias: {m_Texture2D.m_TextureSettings.m_MipBias}");
|
||||
switch (m_Texture2D.m_TextureSettings.m_WrapMode)
|
||||
{
|
||||
case 0: sb.AppendLine($"Wrap mode: Repeat"); break;
|
||||
case 1: sb.AppendLine($"Wrap mode: Clamp"); break;
|
||||
}
|
||||
Logger.Debug(sb.ToString());
|
||||
}
|
||||
|
||||
var image = m_Texture2D.ConvertToImage(flip: true);
|
||||
if (image == null)
|
||||
{
|
||||
Logger.Error($"Export error. Failed to convert texture \"{m_Texture2D.m_Name}\" into image");
|
||||
return false;
|
||||
}
|
||||
using (image)
|
||||
{
|
||||
using (var file = File.OpenWrite(exportFullPath))
|
||||
{
|
||||
image.WriteToStream(file, type);
|
||||
}
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData());
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ExportAudioClip(AssetItem item, string exportPath)
|
||||
{
|
||||
string exportFullPath;
|
||||
var m_AudioClip = (AudioClip)item.Asset;
|
||||
var m_AudioData = m_AudioClip.m_AudioData.GetData();
|
||||
if (m_AudioData == null || m_AudioData.Length == 0)
|
||||
{
|
||||
Logger.Error($"Export error. \"{item.Text}\": AudioData was not found");
|
||||
return false;
|
||||
}
|
||||
var converter = new AudioClipConverter(m_AudioClip);
|
||||
if (CLIOptions.o_audioFormat.Value != AudioFormat.None && converter.IsSupport)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".wav", out exportFullPath))
|
||||
return false;
|
||||
|
||||
if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"Converting \"{m_AudioClip.m_Name}\" to wav..");
|
||||
sb.AppendLine(m_AudioClip.version[0] < 5 ? $"AudioClip type: {m_AudioClip.m_Type}" : $"AudioClip compression format: {m_AudioClip.m_CompressionFormat}");
|
||||
sb.AppendLine($"AudioClip channel count: {m_AudioClip.m_Channels}");
|
||||
sb.AppendLine($"AudioClip sample rate: {m_AudioClip.m_Frequency}");
|
||||
sb.AppendLine($"AudioClip bit depth: {m_AudioClip.m_BitsPerSample}");
|
||||
Logger.Debug(sb.ToString());
|
||||
}
|
||||
|
||||
var buffer = converter.ConvertToWav(m_AudioData);
|
||||
if (buffer == null)
|
||||
{
|
||||
Logger.Error($"Export error. \"{item.Text}\": Failed to convert to Wav");
|
||||
return false;
|
||||
}
|
||||
File.WriteAllBytes(exportFullPath, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, converter.GetExtensionName(), out exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_AudioData);
|
||||
}
|
||||
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportVideoClip(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_VideoClip = (VideoClip)item.Asset;
|
||||
if (m_VideoClip.m_ExternalResources.m_Size > 0)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath))
|
||||
return false;
|
||||
|
||||
if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"VideoClip format: {m_VideoClip.m_Format}");
|
||||
sb.AppendLine($"VideoClip width: {m_VideoClip.Width}");
|
||||
sb.AppendLine($"VideoClip height: {m_VideoClip.Height}");
|
||||
sb.AppendLine($"VideoClip frame rate: {m_VideoClip.m_FrameRate:.0##}");
|
||||
sb.AppendLine($"VideoClip split alpha: {m_VideoClip.m_HasSplitAlpha}");
|
||||
Logger.Debug(sb.ToString());
|
||||
}
|
||||
|
||||
m_VideoClip.m_VideoData.WriteData(exportFullPath);
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportMovieTexture(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_MovieTexture = (MovieTexture)item.Asset;
|
||||
if (!TryExportFile(exportPath, item, ".ogv", out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_MovieTexture.m_MovieData);
|
||||
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportShader(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath))
|
||||
return false;
|
||||
var m_Shader = (Shader)item.Asset;
|
||||
var str = m_Shader.Convert();
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportTextAsset(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_TextAsset = (TextAsset)item.Asset;
|
||||
var extension = ".txt";
|
||||
var assetExtension = Path.GetExtension(m_TextAsset.m_Name);
|
||||
if (!CLIOptions.f_notRestoreExtensionName.Value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(assetExtension))
|
||||
{
|
||||
extension = "";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(item.Container))
|
||||
{
|
||||
var ext = Path.GetExtension(item.Container);
|
||||
if (!string.IsNullOrEmpty(item.Container))
|
||||
{
|
||||
extension = ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!TryExportFile(exportPath, item, extension, out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_TextAsset.m_Script);
|
||||
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportMonoBehaviour(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".json", out var exportFullPath))
|
||||
return false;
|
||||
var m_MonoBehaviour = (MonoBehaviour)item.Asset;
|
||||
var type = m_MonoBehaviour.ToType();
|
||||
if (type == null)
|
||||
{
|
||||
var m_Type = m_MonoBehaviour.ConvertToTypeTree(Studio.assemblyLoader);
|
||||
type = m_MonoBehaviour.ToType(m_Type);
|
||||
}
|
||||
if (type != null)
|
||||
{
|
||||
var str = JsonConvert.SerializeObject(type, Formatting.Indented);
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportFont(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_Font = (Font)item.Asset;
|
||||
if (m_Font.m_FontData != null)
|
||||
{
|
||||
var extension = ".ttf";
|
||||
if (m_Font.m_FontData[0] == 79 && m_Font.m_FontData[1] == 84 && m_Font.m_FontData[2] == 84 && m_Font.m_FontData[3] == 79)
|
||||
{
|
||||
extension = ".otf";
|
||||
}
|
||||
if (!TryExportFile(exportPath, item, extension, out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_Font.m_FontData);
|
||||
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportSprite(AssetItem item, string exportPath)
|
||||
{
|
||||
Image<Bgra32> image;
|
||||
AvgSprite avgSprite = null;
|
||||
var alias = "";
|
||||
var m_Sprite = (Sprite)item.Asset;
|
||||
var type = CLIOptions.o_imageFormat.Value;
|
||||
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");
|
||||
|
||||
if (isCharAvgSprite)
|
||||
{
|
||||
avgSprite = new AvgSprite(item);
|
||||
|
||||
if (CLIOptions.f_akAddAliases.Value && !string.IsNullOrEmpty(avgSprite.Alias))
|
||||
{
|
||||
alias = $"_{avgSprite.Alias}";
|
||||
}
|
||||
|
||||
if (!CLIOptions.f_akOriginalAvgNames.Value)
|
||||
{
|
||||
var groupedPattern = new Regex(@"^\d{1,2}\$\d{1,2}$"); // "spriteIndex$groupIndex"
|
||||
var notGroupedPattern = new Regex(@"^\d{1,2}$"); // "spriteIndex"
|
||||
if (groupedPattern.IsMatch(m_Sprite.m_Name) || notGroupedPattern.IsMatch(m_Sprite.m_Name))
|
||||
{
|
||||
var fullName = Path.GetFileNameWithoutExtension(item.Container);
|
||||
item.Text = $"{fullName}#{m_Sprite.m_Name}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath, alias))
|
||||
return false;
|
||||
|
||||
if (CLIOptions.o_akSpriteAlphaMode.Value == AkSpriteAlphaMode.SearchExternal && (isCharAvgSprite || isCharArt))
|
||||
{
|
||||
if (m_Sprite.m_RD.alphaTexture.IsNull)
|
||||
{
|
||||
var charAlphaAtlas = AkSpriteHelper.TryFindAlphaTex(item, avgSprite, isCharAvgSprite);
|
||||
if (charAlphaAtlas != null)
|
||||
{
|
||||
m_Sprite.m_RD.alphaTexture.Set(charAlphaAtlas);
|
||||
m_Sprite.akSplitAlpha = true;
|
||||
}
|
||||
}
|
||||
image = m_Sprite.AkGetImage(avgSprite, spriteMaskMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
image = m_Sprite.GetImage(spriteMaskMode);
|
||||
}
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
using (image)
|
||||
{
|
||||
using (var file = File.OpenWrite(exportFullPath))
|
||||
{
|
||||
image.WriteToStream(file, type);
|
||||
}
|
||||
Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportPortraitSprite(AssetItem item, string exportPath)
|
||||
{
|
||||
var type = CLIOptions.o_imageFormat.Value;
|
||||
var spriteMaskMode = CLIOptions.o_akSpriteAlphaMode.Value != AkSpriteAlphaMode.None ? SpriteMaskMode.Export : SpriteMaskMode.Off;
|
||||
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
||||
return false;
|
||||
|
||||
var image = item.AkPortraitSprite.AkGetImage(spriteMaskMode: spriteMaskMode);
|
||||
if (image != null)
|
||||
{
|
||||
using (image)
|
||||
{
|
||||
using (var file = File.OpenWrite(exportFullPath))
|
||||
{
|
||||
image.WriteToStream(file, type);
|
||||
}
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportRawFile(AssetItem item, string exportPath)
|
||||
{
|
||||
if (item.Asset == null)
|
||||
{
|
||||
Logger.Warning($"Raw export is not supported for \"{item.Text}\" ({item.TypeString}) file");
|
||||
return false;
|
||||
}
|
||||
if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
|
||||
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
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)
|
||||
{
|
||||
if (item.Asset == null)
|
||||
{
|
||||
Logger.Warning($"Dump is not supported for \"{item.Text}\" ({item.TypeString}) file");
|
||||
return false;
|
||||
}
|
||||
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
|
||||
return false;
|
||||
var str = item.Asset.Dump();
|
||||
if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour)
|
||||
{
|
||||
var m_Type = m_MonoBehaviour.ConvertToTypeTree(Studio.assemblyLoader);
|
||||
str = m_MonoBehaviour.Dump(m_Type);
|
||||
}
|
||||
if (str != null)
|
||||
{
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" saved to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath, string alias = "")
|
||||
{
|
||||
var fileName = FixFileName(item.Text) + alias;
|
||||
fullPath = Path.Combine(dir, fileName + extension);
|
||||
if (!File.Exists(fullPath))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
return true;
|
||||
}
|
||||
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
|
||||
if (!File.Exists(fullPath))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
return true;
|
||||
}
|
||||
Logger.Error($"Export error. File \"{fullPath.Color(ColorConsole.BrightRed)}\" already exist");
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool ExportMesh(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_Mesh = (Mesh)item.Asset;
|
||||
if (m_Mesh.m_VertexCount <= 0)
|
||||
return false;
|
||||
if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath))
|
||||
return false;
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("g " + m_Mesh.m_Name);
|
||||
|
||||
#region Vertices
|
||||
|
||||
if (m_Mesh.m_Vertices == null || m_Mesh.m_Vertices.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int c = 3;
|
||||
if (m_Mesh.m_Vertices.Length == m_Mesh.m_VertexCount * 4)
|
||||
{
|
||||
c = 4;
|
||||
}
|
||||
|
||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||
{
|
||||
sb.Append($"v {-m_Mesh.m_Vertices[v * c]} {m_Mesh.m_Vertices[v * c + 1]} {m_Mesh.m_Vertices[v * c + 2]}\r\n");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UV
|
||||
|
||||
if (m_Mesh.m_UV0?.Length > 0)
|
||||
{
|
||||
c = 4;
|
||||
if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 2)
|
||||
{
|
||||
c = 2;
|
||||
}
|
||||
else if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 3)
|
||||
{
|
||||
c = 3;
|
||||
}
|
||||
|
||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||
{
|
||||
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV0[v * c], m_Mesh.m_UV0[v * c + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Normals
|
||||
|
||||
if (m_Mesh.m_Normals?.Length > 0)
|
||||
{
|
||||
if (m_Mesh.m_Normals.Length == m_Mesh.m_VertexCount * 3)
|
||||
{
|
||||
c = 3;
|
||||
}
|
||||
else if (m_Mesh.m_Normals.Length == m_Mesh.m_VertexCount * 4)
|
||||
{
|
||||
c = 4;
|
||||
}
|
||||
|
||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||
{
|
||||
sb.AppendFormat("vn {0} {1} {2}\r\n", -m_Mesh.m_Normals[v * c], m_Mesh.m_Normals[v * c + 1], m_Mesh.m_Normals[v * c + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Face
|
||||
|
||||
int sum = 0;
|
||||
for (var i = 0; i < m_Mesh.m_SubMeshes.Length; i++)
|
||||
{
|
||||
sb.AppendLine($"g {m_Mesh.m_Name}_{i}");
|
||||
int indexCount = (int)m_Mesh.m_SubMeshes[i].indexCount;
|
||||
var end = sum + indexCount / 3;
|
||||
for (int f = sum; f < end; f++)
|
||||
{
|
||||
sb.AppendFormat("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\r\n", m_Mesh.m_Indices[f * 3 + 2] + 1, m_Mesh.m_Indices[f * 3 + 1] + 1, m_Mesh.m_Indices[f * 3] + 1);
|
||||
}
|
||||
|
||||
sum = end;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
sb.Replace("NaN", "0");
|
||||
File.WriteAllText(exportFullPath, sb.ToString());
|
||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportConvertFile(AssetItem item, string exportPath)
|
||||
{
|
||||
switch (item.Type)
|
||||
{
|
||||
case ClassIDType.Texture2D:
|
||||
return ExportTexture2D(item, exportPath);
|
||||
case ClassIDType.AudioClip:
|
||||
return ExportAudioClip(item, exportPath);
|
||||
case ClassIDType.VideoClip:
|
||||
return ExportVideoClip(item, exportPath);
|
||||
case ClassIDType.MovieTexture:
|
||||
return ExportMovieTexture(item, exportPath);
|
||||
case ClassIDType.Shader:
|
||||
return ExportShader(item, exportPath);
|
||||
case ClassIDType.TextAsset:
|
||||
return ExportTextAsset(item, exportPath);
|
||||
case ClassIDType.MonoBehaviour:
|
||||
return ExportMonoBehaviour(item, exportPath);
|
||||
case ClassIDType.Font:
|
||||
return ExportFont(item, exportPath);
|
||||
case ClassIDType.Sprite:
|
||||
return ExportSprite(item, exportPath);
|
||||
case ClassIDType.AkPortraitSprite:
|
||||
return ExportPortraitSprite(item, exportPath);
|
||||
case ClassIDType.Mesh:
|
||||
return ExportMesh(item, exportPath);
|
||||
default:
|
||||
return ExportRawFile(item, exportPath);
|
||||
}
|
||||
}
|
||||
|
||||
public static string FixFileName(string str)
|
||||
{
|
||||
if (str.Length >= 260) return Path.GetRandomFileName();
|
||||
return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
AssetStudioCLI/Libraries/linux-x64/libAssetStudioFBXNative.so
Normal file
BIN
AssetStudioCLI/Libraries/linux-x64/libAssetStudioFBXNative.so
Normal file
Binary file not shown.
BIN
AssetStudioCLI/Libraries/linux-x64/libTexture2DDecoderNative.so
Normal file
BIN
AssetStudioCLI/Libraries/linux-x64/libTexture2DDecoderNative.so
Normal file
Binary file not shown.
BIN
AssetStudioCLI/Libraries/linux-x64/libfmod.so
Normal file
BIN
AssetStudioCLI/Libraries/linux-x64/libfmod.so
Normal file
Binary file not shown.
BIN
AssetStudioCLI/Libraries/linux-x86/libfmod.so
Normal file
BIN
AssetStudioCLI/Libraries/linux-x86/libfmod.so
Normal file
Binary file not shown.
BIN
AssetStudioCLI/Libraries/osx-arm64/libAssetStudioFBXNative.dylib
Normal file
BIN
AssetStudioCLI/Libraries/osx-arm64/libAssetStudioFBXNative.dylib
Normal file
Binary file not shown.
Binary file not shown.
BIN
AssetStudioCLI/Libraries/osx-arm64/libfmod.dylib
Normal file
BIN
AssetStudioCLI/Libraries/osx-arm64/libfmod.dylib
Normal file
Binary file not shown.
BIN
AssetStudioCLI/Libraries/osx-x64/libAssetStudioFBXNative.dylib
Normal file
BIN
AssetStudioCLI/Libraries/osx-x64/libAssetStudioFBXNative.dylib
Normal file
Binary file not shown.
BIN
AssetStudioCLI/Libraries/osx-x64/libTexture2DDecoderNative.dylib
Normal file
BIN
AssetStudioCLI/Libraries/osx-x64/libTexture2DDecoderNative.dylib
Normal file
Binary file not shown.
BIN
AssetStudioCLI/Libraries/osx-x64/libfmod.dylib
Normal file
BIN
AssetStudioCLI/Libraries/osx-x64/libfmod.dylib
Normal file
Binary file not shown.
BIN
AssetStudioCLI/Libraries/win-x64/fmod.dll
Normal file
BIN
AssetStudioCLI/Libraries/win-x64/fmod.dll
Normal file
Binary file not shown.
BIN
AssetStudioCLI/Libraries/win-x86/fmod.dll
Normal file
BIN
AssetStudioCLI/Libraries/win-x86/fmod.dll
Normal file
Binary file not shown.
1211
AssetStudioCLI/Options/CLIOptions.cs
Normal file
1211
AssetStudioCLI/Options/CLIOptions.cs
Normal file
File diff suppressed because it is too large
Load Diff
27
AssetStudioCLI/Options/Option.cs
Normal file
27
AssetStudioCLI/Options/Option.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace AssetStudioCLI.Options
|
||||
{
|
||||
internal class Option<T>
|
||||
{
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
public T Value { get; set; }
|
||||
public T DefaultValue { get; }
|
||||
public HelpGroups HelpGroup { get; }
|
||||
public bool IsFlag { get; }
|
||||
|
||||
public Option(T optionDefaultValue, string optionName, string optionDescription, HelpGroups optionHelpGroup, bool isFlag)
|
||||
{
|
||||
Name = optionName;
|
||||
Description = optionDescription;
|
||||
DefaultValue = optionDefaultValue;
|
||||
Value = DefaultValue;
|
||||
HelpGroup = optionHelpGroup;
|
||||
IsFlag = isFlag;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value != null ? Value.ToString() : string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
AssetStudioCLI/Options/OptionExtensions.cs
Normal file
17
AssetStudioCLI/Options/OptionExtensions.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace AssetStudioCLI.Options
|
||||
{
|
||||
internal static class OptionExtensions
|
||||
{
|
||||
public static Action<string, string, HelpGroups, bool> OptionGrouping = (name, desc, group, isFlag) => { };
|
||||
}
|
||||
|
||||
internal class GroupedOption<T> : Option<T>
|
||||
{
|
||||
public GroupedOption(T optionDefaultValue, string optionName, string optionDescription, HelpGroups optionHelpGroup, bool isFlag = false) : base(optionDefaultValue, optionName, optionDescription, optionHelpGroup, isFlag)
|
||||
{
|
||||
OptionExtensions.OptionGrouping(optionName, optionDescription, optionHelpGroup, isFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
73
AssetStudioCLI/Program.cs
Normal file
73
AssetStudioCLI/Program.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using AssetStudio;
|
||||
using AssetStudioCLI.Options;
|
||||
using System;
|
||||
|
||||
namespace AssetStudioCLI
|
||||
{
|
||||
class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CLIOptions.ParseArgs(args);
|
||||
if (CLIOptions.isParsed)
|
||||
{
|
||||
CLIRun();
|
||||
}
|
||||
else if (CLIOptions.showHelp)
|
||||
{
|
||||
CLIOptions.ShowHelp();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine();
|
||||
CLIOptions.ShowHelp(showUsageOnly: true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CLIRun()
|
||||
{
|
||||
var cliLogger = new CLILogger();
|
||||
Logger.Default = cliLogger;
|
||||
CLIOptions.ShowCurrentOptions();
|
||||
|
||||
try
|
||||
{
|
||||
if (Studio.LoadAssets())
|
||||
{
|
||||
Studio.ParseAssets();
|
||||
if (CLIOptions.filterBy != FilterBy.None)
|
||||
{
|
||||
Studio.Filter();
|
||||
}
|
||||
if (CLIOptions.o_exportAssetList.Value != ExportListType.None)
|
||||
{
|
||||
Studio.ExportAssetList();
|
||||
}
|
||||
switch (CLIOptions.o_workMode.Value)
|
||||
{
|
||||
case WorkMode.Info:
|
||||
Studio.ShowExportableAssetsInfo();
|
||||
break;
|
||||
case WorkMode.ExportLive2D:
|
||||
Studio.ExportLive2D();
|
||||
break;
|
||||
case WorkMode.SplitObjects:
|
||||
Studio.ExportSplitObjects();
|
||||
break;
|
||||
default:
|
||||
Studio.ExportAssets();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
cliLogger.LogToFile(LoggerEvent.Verbose, "---Program ended---");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
159
AssetStudioCLI/ReadMe.md
Normal file
159
AssetStudioCLI/ReadMe.md
Normal file
@@ -0,0 +1,159 @@
|
||||
## ArknightsStudioCLI
|
||||
CLI version of ArknightsStudio.
|
||||
- Supported asset types for export: `Texture2D`, `Sprite`, `AkPortraitSprite`, `TextAsset`, `MonoBehaviour`, `Font`, `Shader`, `MovieTexture`, `AudioClip`, `VideoClip`, `Mesh`.
|
||||
- *There are no plans to add support for `AnimationClip`, `Animator` for now.*
|
||||
|
||||
### Usage
|
||||
```
|
||||
ArknightsStudioCLI <input path to asset file/folder> [-m, --mode <value>]
|
||||
[-t, --asset-type <value(s)>] [-g, --group-option <value>]
|
||||
[-o, --output <path>] [-h, --help]
|
||||
[--log-level <value>] [--log-output <value>]
|
||||
[--image-format <value>] [--audio-format <value>]
|
||||
[--l2d-motion-mode <value>] [--l2d-force-bezier]
|
||||
[--fbx-scale-factor <value>] [--fbx-bone-size <value>]
|
||||
[--filter-by-name <text>] [--filter-by-container <text>]
|
||||
[--filter-by-pathid <text>] [--filter-by-text <text>]
|
||||
[--spritealpha-mode <value>] [--alphatex-resampler <value>]
|
||||
[--shadow-gamma <value>] [--original-avg-names]
|
||||
[--add-aliases] [--export-asset-list <value>]
|
||||
[--assembly-folder <path>] [--unity-version <text>]
|
||||
[--not-restore-extension] [--load-all]
|
||||
|
||||
|
||||
General Options:
|
||||
-m, --mode <value> Specify working mode
|
||||
<Value: export(default) | exportRaw | dump | info | live2d | splitObjects>
|
||||
Export - Exports converted assets
|
||||
ExportRaw - Exports raw data
|
||||
Dump - Makes asset dumps
|
||||
Info - Loads file(s), shows the number of available for export assets and exits
|
||||
Live2D - Exports Live2D Cubism 3 models
|
||||
SplitObjects - Exports split objects (fbx)
|
||||
Example: "-m info"
|
||||
|
||||
-t, --asset-type <value(s)> Specify asset type(s) to export
|
||||
<Value(s): tex2d, sprite, akPortrait, textAsset, monoBehaviour, font, shader,
|
||||
movieTexture, audio, video, mesh | all(default)>
|
||||
All - export all asset types, which are listed in the values
|
||||
*To specify multiple asset types, write them separated by ',' or ';' without spaces
|
||||
Examples: "-t sprite" or "-t tex2d,sprite,audio" or "-t tex2d;sprite;font"
|
||||
|
||||
-g, --group-option <value> Specify the way in which exported assets should be grouped
|
||||
<Value: none | type | container(default) | containerFull | filename>
|
||||
None - Do not group exported assets
|
||||
Type - Group exported assets by type name
|
||||
Container - Group exported assets by container path
|
||||
ContainerFull - Group exported assets by full container path (e.g. with prefab name)
|
||||
Filename - Group exported assets by source file name
|
||||
Example: "-g container"
|
||||
|
||||
-o, --output <path> Specify path to the output folder
|
||||
If path isn't specified, 'ASExport' folder will be created in the program's work folder
|
||||
|
||||
-h, --help Display help and exit
|
||||
|
||||
Logger Options:
|
||||
--log-level <value> Specify the log level
|
||||
<Value: verbose | debug | info(default) | warning | error>
|
||||
Example: "--log-level warning"
|
||||
|
||||
--log-output <value> Specify the log output
|
||||
<Value: console(default) | file | both>
|
||||
Example: "--log-output both"
|
||||
|
||||
Convert Options:
|
||||
--image-format <value> Specify the format for converting image assets
|
||||
<Value: none | jpg | png(default) | bmp | tga | webp>
|
||||
None - Do not convert images and export them as texture data (.tex)
|
||||
Example: "--image-format jpg"
|
||||
|
||||
--audio-format <value> Specify the format for converting audio assets
|
||||
<Value: none | wav(default)>
|
||||
None - Do not convert audios and export them in their own format
|
||||
Example: "--audio-format wav"
|
||||
|
||||
Live2D Options:
|
||||
--l2d-motion-mode <value> Specify Live2D motion export mode
|
||||
<Value: monoBehaviour(default) | animationClip>
|
||||
MonoBehaviour - Try to export motions from MonoBehaviour Fade motions
|
||||
If no Fade motions are found, the AnimationClip method will be used
|
||||
AnimationClip - Try to export motions using AnimationClip assets
|
||||
Example: "--l2d-motion-mode animationClip"
|
||||
|
||||
--l2d-force-bezier (Flag) If specified, Linear motion segments will be calculated as Bezier segments
|
||||
(May help if the exported motions look jerky/not smooth enough)
|
||||
|
||||
FBX Options:
|
||||
--fbx-scale-factor <value> Specify the FBX Scale Factor
|
||||
<Value: float number from 0 to 100 (default=1)
|
||||
Example: "--fbx-scale-factor 50"
|
||||
|
||||
--fbx-bone-size <value> Specify the FBX Bone Size
|
||||
<Value: integer number from 0 to 100 (default=10)
|
||||
Example: "--fbx-bone-size 10"
|
||||
|
||||
Filter Options:
|
||||
--filter-by-name <text> Specify the name by which assets should be filtered
|
||||
*To specify multiple names write them separated by ',' or ';' without spaces
|
||||
Example: "--filter-by-name char" or "--filter-by-name char,bg"
|
||||
|
||||
--filter-by-container <text> Specify the container by which assets should be filtered
|
||||
*To specify multiple containers write them separated by ',' or ';' without spaces
|
||||
Example: "--filter-by-container arts" or "--filter-by-container arts,icons"
|
||||
|
||||
--filter-by-pathid <text> Specify the PathID by which assets should be filtered
|
||||
*To specify multiple PathIDs write them separated by ',' or ';' without spaces
|
||||
Example: "--filter-by-pathid 7238605633795851352,-2430306240205277265"
|
||||
|
||||
--filter-by-text <text> Specify the text by which assets should be filtered
|
||||
Looks for assets that contain the specified text in their names or containers
|
||||
*To specify multiple values write them separated by ',' or ';' without spaces
|
||||
Example: "--filter-by-text portrait" or "--filter-by-text portrait,art"
|
||||
|
||||
|
||||
Arknights Options:
|
||||
--spritealpha-mode <value> Specify the mode in which you want to export sprites with alpha texture
|
||||
<Value: none | internalOnly | searchExternal(default)>
|
||||
None - Export sprites without alpha texture applied
|
||||
InternalOnly - Export sprites with internal alpha texture applied (if exist)
|
||||
SearchExternal - Export sprites with internal alpha texture applied,
|
||||
and in case it doesn't exist, Studio will try to find an external alpha texture
|
||||
Example: "--spritealpha-mode internalOnly"
|
||||
|
||||
--alphatex-resampler <value> Specify the alpha texture upscale algorithm for 2048x2048 sprites
|
||||
<Value: nearest | bilinear | bicubic | mitchell(default) | spline | welch>
|
||||
Mitchell - Mitchell Netravali algorithm. Yields good equilibrium between
|
||||
sharpness and smoothness (produces less artifacts than bicubic in the current use case)
|
||||
Spline - Similar to Mitchell Netravali but yielding smoother results
|
||||
Welch - A high speed algorithm that delivers very sharpened results
|
||||
Example: "--alphatex-resampler bicubic"
|
||||
|
||||
--shadow-gamma <value> Specify the gamma correction of semi-transparent shadow for 2048x2048 sprites
|
||||
<Value: integer number from -5 to 5 (default=2)>
|
||||
<0 - Make the shadow darker
|
||||
0 - Do not change the brightness of the shadow
|
||||
>0 - Make the shadow lighter
|
||||
Example: "--shadow-gamma 0"
|
||||
|
||||
--original-avg-names (Flag) If specified, names of avg character sprites will not be restored
|
||||
|
||||
--add-aliases (Flag) If specified, aliases will be added to avg character sprite names (if exist)
|
||||
|
||||
Advanced Options:
|
||||
--export-asset-list <value> Specify the format in which you want to export asset list
|
||||
<Value: none(default) | xml>
|
||||
None - Do not export asset list
|
||||
Example: "--export-asset-list xml"
|
||||
|
||||
--assembly-folder <path> Specify the path to the assembly folder
|
||||
|
||||
--unity-version <text> Specify Unity version
|
||||
Example: "--unity-version 2017.4.39f1"
|
||||
|
||||
--not-restore-extension (Flag) If specified, Studio will not try to use/restore original TextAsset
|
||||
extension name, and will just export all TextAssets with the ".txt" extension
|
||||
|
||||
--load-all (Flag) If specified, Studio will load assets of all types
|
||||
(Only for Dump, Info and ExportRaw modes)
|
||||
```
|
||||
721
AssetStudioCLI/Studio.cs
Normal file
721
AssetStudioCLI/Studio.cs
Normal file
@@ -0,0 +1,721 @@
|
||||
using AssetStudio;
|
||||
using AssetStudioCLI.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using static AssetStudioCLI.Exporter;
|
||||
using static CubismLive2DExtractor.Live2DExtractor;
|
||||
using Ansi = AssetStudio.ColorConsole;
|
||||
|
||||
namespace AssetStudioCLI
|
||||
{
|
||||
internal static class Studio
|
||||
{
|
||||
public static AssetsManager assetsManager = new AssetsManager();
|
||||
public static List<AssetItem> exportableAssetsList = 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();
|
||||
private static Dictionary<AssetStudio.Object, string> containers = new Dictionary<AssetStudio.Object, string>();
|
||||
|
||||
static Studio()
|
||||
{
|
||||
Progress.Default = new Progress<int>(ShowCurProgressValue);
|
||||
}
|
||||
|
||||
private static void ShowCurProgressValue(int value)
|
||||
{
|
||||
Console.Write($"[{value:000}%]\r");
|
||||
}
|
||||
|
||||
public static bool LoadAssets()
|
||||
{
|
||||
var isLoaded = false;
|
||||
assetsManager.SpecifyUnityVersion = CLIOptions.o_unityVersion.Value;
|
||||
if (!CLIOptions.f_loadAllAssets.Value)
|
||||
{
|
||||
assetsManager.SetAssetFilter(CLIOptions.o_exportAssetTypes.Value);
|
||||
}
|
||||
assetsManager.LoadFilesAndFolders(CLIOptions.inputPath);
|
||||
if (assetsManager.assetsFileList.Count == 0)
|
||||
{
|
||||
Logger.Warning("No Unity file can be loaded.");
|
||||
}
|
||||
else
|
||||
{
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
return isLoaded;
|
||||
}
|
||||
|
||||
public static void ParseAssets()
|
||||
{
|
||||
Logger.Info("Parse assets...");
|
||||
|
||||
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
||||
var objectAssetItemDic = new Dictionary<AssetStudio.Object, AssetItem>(objectCount);
|
||||
|
||||
Progress.Reset();
|
||||
var i = 0;
|
||||
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||
{
|
||||
var preloadTable = Array.Empty<PPtr<AssetStudio.Object>>();
|
||||
foreach (var asset in assetsFile.Objects)
|
||||
{
|
||||
var assetItem = new AssetItem(asset);
|
||||
objectAssetItemDic.Add(asset, assetItem);
|
||||
assetItem.UniqueID = "_#" + i;
|
||||
var isExportable = false;
|
||||
switch (asset)
|
||||
{
|
||||
case PreloadData m_PreloadData:
|
||||
preloadTable = m_PreloadData.m_Assets;
|
||||
break;
|
||||
case AssetBundle m_AssetBundle:
|
||||
var isStreamedSceneAssetBundle = m_AssetBundle.m_IsStreamedSceneAssetBundle;
|
||||
if (!isStreamedSceneAssetBundle)
|
||||
{
|
||||
preloadTable = m_AssetBundle.m_PreloadTable;
|
||||
}
|
||||
assetItem.Text = string.IsNullOrEmpty(m_AssetBundle.m_AssetBundleName) ? m_AssetBundle.m_Name : m_AssetBundle.m_AssetBundleName;
|
||||
|
||||
foreach (var m_Container in m_AssetBundle.m_Container)
|
||||
{
|
||||
var preloadIndex = m_Container.Value.preloadIndex;
|
||||
var preloadSize = isStreamedSceneAssetBundle ? preloadTable.Length : m_Container.Value.preloadSize;
|
||||
var preloadEnd = preloadIndex + preloadSize;
|
||||
for (var k = preloadIndex; k < preloadEnd; k++)
|
||||
{
|
||||
var pptr = preloadTable[k];
|
||||
if (pptr.TryGet(out var obj))
|
||||
{
|
||||
containers[obj] = m_Container.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ResourceManager m_ResourceManager:
|
||||
foreach (var m_Container in m_ResourceManager.m_Container)
|
||||
{
|
||||
if (m_Container.Value.TryGet(out var obj))
|
||||
{
|
||||
containers[obj] = m_Container.Key;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Texture2D m_Texture2D:
|
||||
if (!string.IsNullOrEmpty(m_Texture2D.m_StreamData?.path))
|
||||
assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size;
|
||||
assetItem.Text = m_Texture2D.m_Name;
|
||||
break;
|
||||
case AudioClip m_AudioClip:
|
||||
if (!string.IsNullOrEmpty(m_AudioClip.m_Source))
|
||||
assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size;
|
||||
assetItem.Text = m_AudioClip.m_Name;
|
||||
break;
|
||||
case VideoClip m_VideoClip:
|
||||
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 Shader m_Shader:
|
||||
assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
|
||||
break;
|
||||
case MonoBehaviour m_MonoBehaviour:
|
||||
if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
||||
{
|
||||
assetItem.Text = m_Script.m_ClassName;
|
||||
}
|
||||
else
|
||||
{
|
||||
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 (string.IsNullOrEmpty(assetItem.Text))
|
||||
{
|
||||
assetItem.Text = assetItem.TypeString + assetItem.UniqueID;
|
||||
}
|
||||
|
||||
loadedAssetsList.Add(assetItem);
|
||||
isExportable = CLIOptions.o_exportAssetTypes.Value.Contains(asset.type);
|
||||
if (isExportable || (CLIOptions.f_loadAllAssets.Value && CLIOptions.o_exportAssetTypes.Value == CLIOptions.o_exportAssetTypes.DefaultValue))
|
||||
{
|
||||
exportableAssetsList.Add(assetItem);
|
||||
}
|
||||
|
||||
Progress.Report(++i, objectCount);
|
||||
}
|
||||
foreach (var asset in loadedAssetsList)
|
||||
{
|
||||
if (containers.TryGetValue(asset.Asset, out var container))
|
||||
{
|
||||
asset.Container = container;
|
||||
|
||||
if (asset.Type == ClassIDType.MonoBehaviour && container.Contains("/arts/charportraits/portraits"))
|
||||
{
|
||||
var portraitsList = Arknights.AkSpriteHelper.GeneratePortraits(asset);
|
||||
foreach (var portrait in portraitsList)
|
||||
{
|
||||
exportableAssetsList.Add(new AssetItem(portrait));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CLIOptions.o_workMode.Value != WorkMode.ExportLive2D)
|
||||
{
|
||||
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;
|
||||
if (unityVer[0] > 2020)
|
||||
{
|
||||
m_ObjectsCount = assetsManager.assetsFileList.Sum(x => x.m_Objects.LongCount(y =>
|
||||
y.classID != (int)ClassIDType.Shader
|
||||
&& CLIOptions.o_exportAssetTypes.Value.Any(k => (int)k == y.classID))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ObjectsCount = assetsManager.assetsFileList.Sum(x => x.m_Objects.LongCount(y => CLIOptions.o_exportAssetTypes.Value.Any(k => (int)k == y.classID)));
|
||||
}
|
||||
var objectsCount = assetsManager.assetsFileList.Sum(x => x.Objects.LongCount(y => CLIOptions.o_exportAssetTypes.Value.Any(k => k == y.type)));
|
||||
if (m_ObjectsCount != objectsCount)
|
||||
{
|
||||
log += $" and {m_ObjectsCount - objectsCount} assets failed to read";
|
||||
}
|
||||
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()
|
||||
{
|
||||
var exportableAssetsCountDict = new Dictionary<ClassIDType, int>();
|
||||
string info = "";
|
||||
if (exportableAssetsList.Count > 0)
|
||||
{
|
||||
foreach (var asset in exportableAssetsList)
|
||||
{
|
||||
if (exportableAssetsCountDict.ContainsKey(asset.Type))
|
||||
{
|
||||
exportableAssetsCountDict[asset.Type] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
exportableAssetsCountDict.Add(asset.Type, 1);
|
||||
}
|
||||
}
|
||||
|
||||
info += "\n[Exportable Assets Count]\n";
|
||||
foreach (var assetType in exportableAssetsCountDict.Keys)
|
||||
{
|
||||
info += $"# {assetType}: {exportableAssetsCountDict[assetType]}\n";
|
||||
}
|
||||
if (exportableAssetsCountDict.Count > 1)
|
||||
{
|
||||
info += $"#\n# Total: {exportableAssetsList.Count} assets";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info += "No exportable assets found.";
|
||||
}
|
||||
|
||||
if (CLIOptions.o_logLevel.Value > LoggerEvent.Info)
|
||||
{
|
||||
Console.WriteLine(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info(info);
|
||||
}
|
||||
}
|
||||
|
||||
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<AssetItem>();
|
||||
|
||||
switch(CLIOptions.filterBy)
|
||||
{
|
||||
case FilterBy.Name:
|
||||
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.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."
|
||||
);
|
||||
break;
|
||||
case FilterBy.PathID:
|
||||
filteredAssets = exportableAssetsList.FindAll(x => CLIOptions.o_filterByPathID.Value.Any(y => x.m_PathID.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0));
|
||||
Logger.Info(
|
||||
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
|
||||
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByPathID.Value)}\"".Color(Ansi.BrightYellow)} in their PathIDs."
|
||||
);
|
||||
break;
|
||||
case FilterBy.NameOrContainer:
|
||||
filteredAssets = exportableAssetsList.FindAll(x =>
|
||||
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) " +
|
||||
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByText.Value)}\"".Color(Ansi.BrightYellow)} in their Names or Contaniers."
|
||||
);
|
||||
break;
|
||||
case FilterBy.NameAndContainer:
|
||||
filteredAssets = exportableAssetsList.FindAll(x =>
|
||||
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) " +
|
||||
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByContainer.Value)}\"".Color(Ansi.BrightYellow)} in their Containers " +
|
||||
$"and {$"\"{string.Join("\", \"", CLIOptions.o_filterByName.Value)}\"".Color(Ansi.BrightYellow)} in their Names."
|
||||
);
|
||||
break;
|
||||
}
|
||||
exportableAssetsList.Clear();
|
||||
exportableAssetsList = filteredAssets;
|
||||
}
|
||||
|
||||
public static void ExportAssets()
|
||||
{
|
||||
var savePath = CLIOptions.o_outputFolder.Value;
|
||||
var toExportCount = exportableAssetsList.Count;
|
||||
var exportedCount = 0;
|
||||
|
||||
var groupOption = CLIOptions.o_groupAssetsBy.Value;
|
||||
foreach (var asset in exportableAssetsList)
|
||||
{
|
||||
string exportPath;
|
||||
switch (groupOption)
|
||||
{
|
||||
case AssetGroupOption.TypeName:
|
||||
exportPath = Path.Combine(savePath, asset.TypeString);
|
||||
break;
|
||||
case AssetGroupOption.ContainerPath:
|
||||
case AssetGroupOption.ContainerPathFull:
|
||||
if (!string.IsNullOrEmpty(asset.Container))
|
||||
{
|
||||
exportPath = Path.Combine(savePath, Path.GetDirectoryName(asset.Container));
|
||||
if (groupOption == AssetGroupOption.ContainerPathFull)
|
||||
{
|
||||
exportPath = Path.Combine(exportPath, Path.GetFileNameWithoutExtension(asset.Container));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exportPath = savePath;
|
||||
}
|
||||
break;
|
||||
case AssetGroupOption.SourceFileName:
|
||||
if (string.IsNullOrEmpty(asset.SourceFile.originalPath))
|
||||
{
|
||||
exportPath = Path.Combine(savePath, asset.SourceFile.fileName + "_export");
|
||||
}
|
||||
else
|
||||
{
|
||||
exportPath = Path.Combine(savePath, Path.GetFileName(asset.SourceFile.originalPath) + "_export", asset.SourceFile.fileName);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
exportPath = savePath;
|
||||
break;
|
||||
}
|
||||
|
||||
exportPath += Path.DirectorySeparatorChar;
|
||||
try
|
||||
{
|
||||
switch (CLIOptions.o_workMode.Value)
|
||||
{
|
||||
case WorkMode.ExportRaw:
|
||||
Logger.Debug($"{CLIOptions.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
|
||||
if (ExportRawFile(asset, exportPath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case WorkMode.Dump:
|
||||
Logger.Debug($"{CLIOptions.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
|
||||
if (ExportDumpFile(asset, exportPath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case WorkMode.Export:
|
||||
Logger.Debug($"{CLIOptions.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
|
||||
if (ExportConvertFile(asset, exportPath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"{asset.SourceFile.originalPath}: [{$"{asset.Type}: {asset.Text}".Color(Ansi.BrightRed)}] : Export error\n{ex}");
|
||||
}
|
||||
Console.Write($"Exported [{exportedCount}/{toExportCount}]\r");
|
||||
}
|
||||
Console.WriteLine("");
|
||||
|
||||
if (exportedCount == 0)
|
||||
{
|
||||
Logger.Default.Log(LoggerEvent.Info, "Nothing exported.", ignoreLevel: true);
|
||||
}
|
||||
else if (toExportCount > exportedCount)
|
||||
{
|
||||
Logger.Default.Log(LoggerEvent.Info, $"Finished exporting {exportedCount} asset(s) to \"{CLIOptions.o_outputFolder.Value.Color(Ansi.BrightYellow)}\".", ignoreLevel: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Default.Log(LoggerEvent.Info, $"Finished exporting {exportedCount} asset(s) to \"{CLIOptions.o_outputFolder.Value.Color(Ansi.BrightGreen)}\".", ignoreLevel: true);
|
||||
}
|
||||
|
||||
if (toExportCount > exportedCount)
|
||||
{
|
||||
Logger.Default.Log(LoggerEvent.Info, $"{toExportCount - exportedCount} asset(s) skipped (not extractable or file(s) already exist).", ignoreLevel: true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExportAssetList()
|
||||
{
|
||||
var savePath = CLIOptions.o_outputFolder.Value;
|
||||
|
||||
switch (CLIOptions.o_exportAssetList.Value)
|
||||
{
|
||||
case ExportListType.XML:
|
||||
var filename = Path.Combine(savePath, "assets.xml");
|
||||
var doc = new XDocument(
|
||||
new XElement("Assets",
|
||||
new XAttribute("filename", filename),
|
||||
new XAttribute("createdAt", DateTime.UtcNow.ToString("s")),
|
||||
exportableAssetsList.Select(
|
||||
asset => new XElement("Asset",
|
||||
new XElement("Name", asset.Text),
|
||||
new XElement("Container", asset.Container),
|
||||
new XElement("Type", new XAttribute("id", (int)asset.Type), asset.TypeString),
|
||||
new XElement("PathID", asset.m_PathID),
|
||||
new XElement("Source", asset.SourceFile.fullName),
|
||||
new XElement("Size", asset.FullSize)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
doc.Save(filename);
|
||||
|
||||
break;
|
||||
}
|
||||
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()
|
||||
{
|
||||
var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput");
|
||||
var useFullContainerPath = false;
|
||||
var motionMode = CLIOptions.o_l2dMotionMode.Value;
|
||||
var forceBezier = CLIOptions.f_l2dForceBezier.Value;
|
||||
|
||||
Progress.Reset();
|
||||
Logger.Info($"Searching for Live2D files...");
|
||||
|
||||
var cubismMocs = exportableAssetsList.Where(x =>
|
||||
{
|
||||
if (x.Type == ClassIDType.MonoBehaviour)
|
||||
{
|
||||
((MonoBehaviour)x.Asset).m_Script.TryGet(out var m_Script);
|
||||
return m_Script?.m_ClassName == "CubismMoc";
|
||||
}
|
||||
return false;
|
||||
}).Select(x => x.Asset).ToArray();
|
||||
|
||||
if (cubismMocs.Length == 0)
|
||||
{
|
||||
Logger.Default.Log(LoggerEvent.Info, "Live2D Cubism models were not found.", ignoreLevel: true);
|
||||
return;
|
||||
}
|
||||
if (cubismMocs.Length > 1)
|
||||
{
|
||||
var basePathSet = cubismMocs.Select(x =>
|
||||
{
|
||||
var pathLen = containers.TryGetValue(x, out var itemContainer) ? itemContainer.LastIndexOf("/") : 0;
|
||||
pathLen = pathLen < 0 ? containers[x].Length : pathLen;
|
||||
return itemContainer?.Substring(0, pathLen);
|
||||
}).ToHashSet();
|
||||
|
||||
if (basePathSet.All(x => x == null))
|
||||
{
|
||||
Logger.Error($"Live2D Cubism export error: Cannot find any model related files.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (basePathSet.Count != cubismMocs.Length)
|
||||
{
|
||||
useFullContainerPath = true;
|
||||
Logger.Debug($"useFullContainerPath: {useFullContainerPath}");
|
||||
}
|
||||
}
|
||||
|
||||
var basePathList = cubismMocs.Select(x =>
|
||||
{
|
||||
containers.TryGetValue(x, out var container);
|
||||
container = useFullContainerPath
|
||||
? container
|
||||
: container?.Substring(0, container.LastIndexOf("/"));
|
||||
return container;
|
||||
}).Where(x => x != null).ToList();
|
||||
|
||||
var lookup = containers.ToLookup(
|
||||
x => basePathList.Find(b => x.Value.Contains(b) && x.Value.Split('/').Any(y => y == b.Substring(b.LastIndexOf("/") + 1))),
|
||||
x => x.Key
|
||||
);
|
||||
|
||||
var totalModelCount = lookup.LongCount(x => x.Key != null);
|
||||
Logger.Info($"Found {totalModelCount} model(s).");
|
||||
var modelCounter = 0;
|
||||
foreach (var assets in lookup)
|
||||
{
|
||||
var srcContainer = assets.Key;
|
||||
if (srcContainer == null)
|
||||
continue;
|
||||
var container = srcContainer;
|
||||
|
||||
Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D: \"{srcContainer.Color(Ansi.BrightCyan)}\"");
|
||||
try
|
||||
{
|
||||
var modelName = useFullContainerPath ? Path.GetFileNameWithoutExtension(container) : container.Substring(container.LastIndexOf('/') + 1);
|
||||
container = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") : container;
|
||||
var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar;
|
||||
|
||||
ExtractLive2D(assets, destPath, modelName, assemblyLoader, motionMode, forceBezier);
|
||||
modelCounter++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Live2D model export error: \"{srcContainer}\"", ex);
|
||||
}
|
||||
Progress.Report(modelCounter, (int)totalModelCount);
|
||||
}
|
||||
|
||||
var status = modelCounter > 0 ?
|
||||
$"Finished exporting [{modelCounter}/{totalModelCount}] Live2D model(s) to \"{CLIOptions.o_outputFolder.Value.Color(Ansi.BrightCyan)}\"" :
|
||||
"Nothing exported.";
|
||||
Logger.Default.Log(LoggerEvent.Info, status, ignoreLevel: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,26 +29,26 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -100,14 +100,14 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_AS_DLL;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x86\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x86\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -119,7 +119,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_AS_DLL;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
@@ -129,7 +129,7 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -138,14 +138,14 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_AS_DLL;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x64\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x64\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -157,7 +157,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_AS_DLL;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
@@ -167,7 +167,7 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
22
AssetStudioFBXNative/CMakeLists.txt
Normal file
22
AssetStudioFBXNative/CMakeLists.txt
Normal 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)
|
||||
@@ -1,17 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Version>0.16.8.1</Version>
|
||||
<AssemblyVersion>0.16.8.1</AssemblyVersion>
|
||||
<FileVersion>0.16.8.1</FileVersion>
|
||||
<Copyright>Copyright © Perfare 2018-2021; Copyright © hozuki 2020</Copyright>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net472|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<Version>1.2.0</Version>
|
||||
<Copyright>Copyright © Perfare 2018-2022; Copyright © hozuki 2020</Copyright>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
using AssetStudio.FbxInterop;
|
||||
using AssetStudio.PInvoke;
|
||||
using System.IO;
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using AssetStudio.PInvoke;
|
||||
#endif
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static partial class Fbx
|
||||
{
|
||||
|
||||
#if NETFRAMEWORK
|
||||
static Fbx()
|
||||
{
|
||||
DllLoader.PreloadDll(FbxDll.DllName);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static Vector3 QuaternionToEuler(Quaternion q)
|
||||
{
|
||||
|
||||
503
AssetStudioGUI/AboutForm.Designer.cs
generated
Normal file
503
AssetStudioGUI/AboutForm.Designer.cs
generated
Normal file
@@ -0,0 +1,503 @@
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
partial class AboutForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm));
|
||||
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.textBox2 = new System.Windows.Forms.TextBox();
|
||||
this.label11 = new System.Windows.Forms.Label();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label16 = new System.Windows.Forms.Label();
|
||||
this.label17 = new System.Windows.Forms.Label();
|
||||
this.gitPerfareLinkLabel = new System.Windows.Forms.LinkLabel();
|
||||
this.label18 = new System.Windows.Forms.Label();
|
||||
this.label19 = new System.Windows.Forms.Label();
|
||||
this.gitAelurumLinkLabel = new System.Windows.Forms.LinkLabel();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.productNamelabel = new System.Windows.Forms.Label();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.modVersionLabel = new System.Windows.Forms.Label();
|
||||
this.label4 = 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();
|
||||
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||
this.productTitleLabel = new System.Windows.Forms.Label();
|
||||
this.CloseButton = new System.Windows.Forms.Button();
|
||||
this.productVersionLabel = new System.Windows.Forms.Label();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.panel3 = new System.Windows.Forms.Panel();
|
||||
this.tabControl1.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.tabPage2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||
this.panel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tabControl1
|
||||
//
|
||||
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tabControl1.Controls.Add(this.tabPage1);
|
||||
this.tabControl1.Controls.Add(this.tabPage2);
|
||||
this.tabControl1.Location = new System.Drawing.Point(8, 103);
|
||||
this.tabControl1.Name = "tabControl1";
|
||||
this.tabControl1.SelectedIndex = 0;
|
||||
this.tabControl1.Size = new System.Drawing.Size(370, 315);
|
||||
this.tabControl1.TabIndex = 0;
|
||||
//
|
||||
// tabPage1
|
||||
//
|
||||
this.tabPage1.BackColor = System.Drawing.Color.White;
|
||||
this.tabPage1.Controls.Add(this.panel1);
|
||||
this.tabPage1.Controls.Add(this.textBox2);
|
||||
this.tabPage1.Controls.Add(this.label11);
|
||||
this.tabPage1.Controls.Add(this.label10);
|
||||
this.tabPage1.Controls.Add(this.tableLayoutPanel2);
|
||||
this.tabPage1.Controls.Add(this.tableLayoutPanel1);
|
||||
this.tabPage1.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabPage1.Name = "tabPage1";
|
||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage1.Size = new System.Drawing.Size(362, 289);
|
||||
this.tabPage1.TabIndex = 0;
|
||||
this.tabPage1.Text = "Info";
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panel1.BackColor = System.Drawing.Color.White;
|
||||
this.panel1.Controls.Add(this.label2);
|
||||
this.panel1.Location = new System.Drawing.Point(9, 16);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(347, 46);
|
||||
this.panel1.TabIndex = 21;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label2.Location = new System.Drawing.Point(0, 0);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(347, 46);
|
||||
this.label2.TabIndex = 0;
|
||||
this.label2.Text = "ArknightsStudio is a modified version of AssetStudio designed for Arknights.";
|
||||
this.label2.UseCompatibleTextRendering = true;
|
||||
//
|
||||
// textBox2
|
||||
//
|
||||
this.textBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.textBox2.BackColor = System.Drawing.SystemColors.Window;
|
||||
this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.textBox2.Cursor = System.Windows.Forms.Cursors.Default;
|
||||
this.textBox2.Enabled = false;
|
||||
this.textBox2.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
this.textBox2.Location = new System.Drawing.Point(9, 232);
|
||||
this.textBox2.Multiline = true;
|
||||
this.textBox2.Name = "textBox2";
|
||||
this.textBox2.ReadOnly = true;
|
||||
this.textBox2.Size = new System.Drawing.Size(347, 51);
|
||||
this.textBox2.TabIndex = 20;
|
||||
this.textBox2.TabStop = false;
|
||||
this.textBox2.Text = "* Neither the repository, nor the tool, nor the author of the tool, nor the autho" +
|
||||
"r of the modification is affiliated with, sponsored, or authorized by Unity Tech" +
|
||||
"nologies or its affiliates.";
|
||||
//
|
||||
// label11
|
||||
//
|
||||
this.label11.AutoSize = true;
|
||||
this.label11.Location = new System.Drawing.Point(6, 150);
|
||||
this.label11.Name = "label11";
|
||||
this.label11.Size = new System.Drawing.Size(43, 13);
|
||||
this.label11.TabIndex = 17;
|
||||
this.label11.Text = "Authors";
|
||||
//
|
||||
// label10
|
||||
//
|
||||
this.label10.AutoSize = true;
|
||||
this.label10.Location = new System.Drawing.Point(8, 65);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(42, 13);
|
||||
this.label10.TabIndex = 16;
|
||||
this.label10.Text = "Version";
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.BackColor = System.Drawing.Color.WhiteSmoke;
|
||||
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, 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);
|
||||
this.tableLayoutPanel2.Controls.Add(this.label18, 0, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.label19, 1, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.gitAelurumLinkLabel, 2, 1);
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(6, 165);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.Padding = new System.Windows.Forms.Padding(2);
|
||||
this.tableLayoutPanel2.RowCount = 2;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(350, 40);
|
||||
this.tableLayoutPanel2.TabIndex = 15;
|
||||
//
|
||||
// label16
|
||||
//
|
||||
this.label16.AutoSize = true;
|
||||
this.label16.BackColor = System.Drawing.Color.Transparent;
|
||||
this.label16.Location = new System.Drawing.Point(5, 2);
|
||||
this.label16.Name = "label16";
|
||||
this.label16.Size = new System.Drawing.Size(78, 13);
|
||||
this.label16.TabIndex = 9;
|
||||
this.label16.Text = "Original author:";
|
||||
//
|
||||
// label17
|
||||
//
|
||||
this.label17.AutoSize = true;
|
||||
this.label17.BackColor = System.Drawing.Color.Transparent;
|
||||
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;
|
||||
this.label17.Text = "Perfare (c) 2016-2022";
|
||||
//
|
||||
// gitPerfareLinkLabel
|
||||
//
|
||||
this.gitPerfareLinkLabel.AutoSize = true;
|
||||
this.gitPerfareLinkLabel.BackColor = System.Drawing.Color.Transparent;
|
||||
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;
|
||||
this.gitPerfareLinkLabel.TabStop = true;
|
||||
this.gitPerfareLinkLabel.Text = "GitHub page";
|
||||
this.gitPerfareLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.gitPerfareLinkLabel_LinkClicked);
|
||||
//
|
||||
// label18
|
||||
//
|
||||
this.label18.AutoSize = true;
|
||||
this.label18.BackColor = System.Drawing.Color.Transparent;
|
||||
this.label18.Location = new System.Drawing.Point(5, 20);
|
||||
this.label18.Name = "label18";
|
||||
this.label18.Size = new System.Drawing.Size(76, 13);
|
||||
this.label18.TabIndex = 12;
|
||||
this.label18.Text = "Author of mod:";
|
||||
//
|
||||
// label19
|
||||
//
|
||||
this.label19.AutoSize = true;
|
||||
this.label19.BackColor = System.Drawing.Color.Transparent;
|
||||
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;
|
||||
this.label19.Text = "aelurum (c) 2021-2023";
|
||||
//
|
||||
// gitAelurumLinkLabel
|
||||
//
|
||||
this.gitAelurumLinkLabel.AutoSize = true;
|
||||
this.gitAelurumLinkLabel.BackColor = System.Drawing.Color.Transparent;
|
||||
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;
|
||||
this.gitAelurumLinkLabel.TabStop = true;
|
||||
this.gitAelurumLinkLabel.Text = "GitHub page";
|
||||
this.gitAelurumLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.gitAelurumLinkLabel_LinkClicked);
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.BackColor = System.Drawing.Color.WhiteSmoke;
|
||||
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, 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.basedOnLabel, 1, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.checkUpdatesLinkLabel, 2, 1);
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(6, 80);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(2);
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33334F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(350, 60);
|
||||
this.tableLayoutPanel1.TabIndex = 5;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.BackColor = System.Drawing.Color.Transparent;
|
||||
this.label5.Location = new System.Drawing.Point(5, 2);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(76, 13);
|
||||
this.label5.TabIndex = 0;
|
||||
this.label5.Text = "Product name:";
|
||||
//
|
||||
// productNamelabel
|
||||
//
|
||||
this.productNamelabel.AutoSize = true;
|
||||
this.productNamelabel.BackColor = System.Drawing.Color.Transparent;
|
||||
this.productNamelabel.Location = new System.Drawing.Point(101, 2);
|
||||
this.productNamelabel.Name = "productNamelabel";
|
||||
this.productNamelabel.Size = new System.Drawing.Size(100, 13);
|
||||
this.productNamelabel.TabIndex = 1;
|
||||
this.productNamelabel.Text = "ArknightsStudioGUI";
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
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(45, 13);
|
||||
this.label7.TabIndex = 2;
|
||||
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(101, 20);
|
||||
this.modVersionLabel.Name = "modVersionLabel";
|
||||
this.modVersionLabel.Size = new System.Drawing.Size(52, 13);
|
||||
this.modVersionLabel.TabIndex = 3;
|
||||
this.modVersionLabel.Text = "0.16.48.1";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.BackColor = System.Drawing.Color.Transparent;
|
||||
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.label4.Location = new System.Drawing.Point(5, 38);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(55, 13);
|
||||
this.label4.TabIndex = 4;
|
||||
this.label4.Text = "Based on:";
|
||||
//
|
||||
// basedOnLabel
|
||||
//
|
||||
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(237, 20);
|
||||
this.checkUpdatesLinkLabel.Name = "checkUpdatesLinkLabel";
|
||||
this.checkUpdatesLinkLabel.Size = new System.Drawing.Size(96, 13);
|
||||
this.checkUpdatesLinkLabel.TabIndex = 6;
|
||||
this.checkUpdatesLinkLabel.TabStop = true;
|
||||
this.checkUpdatesLinkLabel.Text = "Check for Updates";
|
||||
this.checkUpdatesLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.checkUpdatesLinkLabel_LinkClicked);
|
||||
//
|
||||
// tabPage2
|
||||
//
|
||||
this.tabPage2.Controls.Add(this.licenseRichTextBox);
|
||||
this.tabPage2.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabPage2.Name = "tabPage2";
|
||||
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage2.Size = new System.Drawing.Size(362, 289);
|
||||
this.tabPage2.TabIndex = 1;
|
||||
this.tabPage2.Text = "License";
|
||||
this.tabPage2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// licenseRichTextBox
|
||||
//
|
||||
this.licenseRichTextBox.BackColor = System.Drawing.Color.White;
|
||||
this.licenseRichTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.licenseRichTextBox.DetectUrls = false;
|
||||
this.licenseRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.licenseRichTextBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.licenseRichTextBox.Name = "licenseRichTextBox";
|
||||
this.licenseRichTextBox.ReadOnly = true;
|
||||
this.licenseRichTextBox.Size = new System.Drawing.Size(356, 283);
|
||||
this.licenseRichTextBox.TabIndex = 0;
|
||||
this.licenseRichTextBox.Text = "MIT License";
|
||||
this.licenseRichTextBox.ZoomFactor = 1.1F;
|
||||
//
|
||||
// pictureBox1
|
||||
//
|
||||
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
|
||||
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.pictureBox1.Image = global::AssetStudioGUI.Properties.Resources.as_logo;
|
||||
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
|
||||
this.pictureBox1.Name = "pictureBox1";
|
||||
this.pictureBox1.Size = new System.Drawing.Size(384, 50);
|
||||
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
this.pictureBox1.TabIndex = 0;
|
||||
this.pictureBox1.TabStop = false;
|
||||
//
|
||||
// productTitleLabel
|
||||
//
|
||||
this.productTitleLabel.BackColor = System.Drawing.Color.Transparent;
|
||||
this.productTitleLabel.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.productTitleLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.productTitleLabel.Location = new System.Drawing.Point(0, 52);
|
||||
this.productTitleLabel.Name = "productTitleLabel";
|
||||
this.productTitleLabel.Size = new System.Drawing.Size(384, 30);
|
||||
this.productTitleLabel.TabIndex = 1;
|
||||
this.productTitleLabel.Text = "ArknightsStudioGUI";
|
||||
this.productTitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// CloseButton
|
||||
//
|
||||
this.CloseButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.CloseButton.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.CloseButton.Location = new System.Drawing.Point(0, 422);
|
||||
this.CloseButton.Name = "CloseButton";
|
||||
this.CloseButton.Size = new System.Drawing.Size(384, 39);
|
||||
this.CloseButton.TabIndex = 1;
|
||||
this.CloseButton.Text = "Close";
|
||||
this.CloseButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// productVersionLabel
|
||||
//
|
||||
this.productVersionLabel.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.productVersionLabel.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
this.productVersionLabel.Location = new System.Drawing.Point(0, 82);
|
||||
this.productVersionLabel.Name = "productVersionLabel";
|
||||
this.productVersionLabel.Padding = new System.Windows.Forms.Padding(0, 0, 5, 0);
|
||||
this.productVersionLabel.Size = new System.Drawing.Size(384, 13);
|
||||
this.productVersionLabel.TabIndex = 2;
|
||||
this.productVersionLabel.Text = "v0.16.48.1 [x64]";
|
||||
this.productVersionLabel.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.Controls.Add(this.productTitleLabel);
|
||||
this.panel2.Controls.Add(this.pictureBox1);
|
||||
this.panel2.Controls.Add(this.productVersionLabel);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel2.Location = new System.Drawing.Point(0, 5);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(384, 95);
|
||||
this.panel2.TabIndex = 3;
|
||||
//
|
||||
// panel3
|
||||
//
|
||||
this.panel3.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel3.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel3.Name = "panel3";
|
||||
this.panel3.Size = new System.Drawing.Size(384, 5);
|
||||
this.panel3.TabIndex = 3;
|
||||
//
|
||||
// AboutForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.CloseButton;
|
||||
this.ClientSize = new System.Drawing.Size(384, 461);
|
||||
this.Controls.Add(this.panel2);
|
||||
this.Controls.Add(this.panel3);
|
||||
this.Controls.Add(this.CloseButton);
|
||||
this.Controls.Add(this.tabControl1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "AboutForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "About";
|
||||
this.tabControl1.ResumeLayout(false);
|
||||
this.tabPage1.ResumeLayout(false);
|
||||
this.tabPage1.PerformLayout();
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.PerformLayout();
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.tabPage2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||
this.panel2.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TabControl tabControl1;
|
||||
private System.Windows.Forms.PictureBox pictureBox1;
|
||||
private System.Windows.Forms.TabPage tabPage2;
|
||||
private System.Windows.Forms.Label productTitleLabel;
|
||||
private System.Windows.Forms.Button CloseButton;
|
||||
private System.Windows.Forms.Label productVersionLabel;
|
||||
private System.Windows.Forms.TabPage tabPage1;
|
||||
private System.Windows.Forms.Label label11;
|
||||
private System.Windows.Forms.Label label10;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.Label label16;
|
||||
private System.Windows.Forms.Label label17;
|
||||
private System.Windows.Forms.LinkLabel gitPerfareLinkLabel;
|
||||
private System.Windows.Forms.Label label18;
|
||||
private System.Windows.Forms.Label label19;
|
||||
private System.Windows.Forms.LinkLabel gitAelurumLinkLabel;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Label productNamelabel;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.Label modVersionLabel;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label basedOnLabel;
|
||||
private System.Windows.Forms.LinkLabel checkUpdatesLinkLabel;
|
||||
private System.Windows.Forms.RichTextBox licenseRichTextBox;
|
||||
private System.Windows.Forms.TextBox textBox2;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
private System.Windows.Forms.Panel panel3;
|
||||
}
|
||||
}
|
||||
72
AssetStudioGUI/AboutForm.cs
Normal file
72
AssetStudioGUI/AboutForm.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
public partial class AboutForm : Form
|
||||
{
|
||||
public AboutForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
var arch = Environment.Is64BitProcess ? "x64" : "x32";
|
||||
var appAssembly = typeof(Program).Assembly.GetName();
|
||||
var productName = appAssembly.Name;
|
||||
var productVer = appAssembly.Version.ToString();
|
||||
Text += " " + productName;
|
||||
productTitleLabel.Text = productName;
|
||||
productVersionLabel.Text = $"v{productVer} [{arch}]";
|
||||
productNamelabel.Text = productName;
|
||||
modVersionLabel.Text = productVer;
|
||||
basedOnLabel.Text = "AssetStudioMod v0.17.4";
|
||||
|
||||
licenseRichTextBox.Text = GetLicenseText();
|
||||
}
|
||||
|
||||
private string GetLicenseText()
|
||||
{
|
||||
string license = "MIT License";
|
||||
|
||||
if (File.Exists("LICENSE"))
|
||||
{
|
||||
string text = File.ReadAllText("LICENSE");
|
||||
license = text.Replace("\r", "")
|
||||
.Replace("\n\n", "\r")
|
||||
.Replace("\nCopyright", "\tCopyright")
|
||||
.Replace("\n", " ")
|
||||
.Replace("\r", "\n\n")
|
||||
.Replace("\tCopyright", "\nCopyright");
|
||||
}
|
||||
|
||||
return license;
|
||||
}
|
||||
|
||||
private void checkUpdatesLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
var ps = new ProcessStartInfo("https://github.com/aelurum/AssetStudio/tags")
|
||||
{
|
||||
UseShellExecute = true
|
||||
};
|
||||
Process.Start(ps);
|
||||
}
|
||||
|
||||
private void gitPerfareLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
var ps = new ProcessStartInfo("https://github.com/Perfare")
|
||||
{
|
||||
UseShellExecute = true
|
||||
};
|
||||
Process.Start(ps);
|
||||
}
|
||||
|
||||
private void gitAelurumLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
var ps = new ProcessStartInfo("https://github.com/aelurum")
|
||||
{
|
||||
UseShellExecute = true
|
||||
};
|
||||
Process.Start(ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
754
AssetStudioGUI/AboutForm.resx
Normal file
754
AssetStudioGUI/AboutForm.resx
Normal file
@@ -0,0 +1,754 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAoAEBAQAAEABAAoAQAApgAAABAQAAABAAgAaAUAAM4BAAAQEAAAAQAgAGgEAAA2BwAAICAQAAEA
|
||||
BADoAgAAngsAACAgAAABAAgAqAgAAIYOAAAgIAAAAQAgAKgQAAAuFwAAMDAQAAEABABoBgAA1icAADAw
|
||||
AAABAAgAqA4AAD4uAAAwMAAAAQAgAKglAADmPAAAAAAAAAEAIADMMAAAjmIAACgAAAAQAAAAIAAAAAEA
|
||||
BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAACAAACAAIAAgIAAAAAAgACAgIAAAICAAMDA
|
||||
wAAAAP8A////AP8A/wAAAAAAAAAAAAAAAAAAAAAAABcXAQQBcDABcQBgYFISFUUCVAACFRUhAEMVFlMj
|
||||
IDIGaGZqubk2ABAIiKiTlpMhBxaDppYzlgUBdoapY5aTQCMBiIk5aTIFEHCKaWllIwQHEGqWmWaTJQEj
|
||||
CJZWmWcBRRBxcBV3EBcAcQYBcQEGAAYGAEUGAjBxABAjAEBRIBCAAQAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAKAAAABAAAAAgAAAAAQAIAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwKCYANzZSADI2ZQAwKSoAMCgsADInSAAxLlUAMDZeADAq
|
||||
LAAyKigAmqDgADpR/gA0M20AOiWTADk0vwA2VfwANVj+ADNQ1wAwKi4AXlZUAOfj7QBDSv0APzrTAEEj
|
||||
nAA+RewAPDvDAEArrAA6TPQAMzZvAJyUkQDz7egAdG33AEU99QBGIpgAQ0D0ADcwbAAyJzEAMis7ADEq
|
||||
MAAxKScA18/JANTH1QCuoe8ATDf/AEwmrgBKMdUARznrAEA1sgA2LV8AV05LAOTY1gCCXKUA4NfjAFMw
|
||||
/gBMKr8ARiNwAE8qwgBPMOMATDX6ADQqRwCSiIIAu6G7AFwjiQDm29oAfFT2AFMn6QA2J0QARCNbAFge
|
||||
hwBUKucAPiqAAMq+tQDdzssA1sTKAOfc1gCvjeoAXh7/AF0f/wBYH7sAXR2YAFoj8gA/J3QAUEdDAN/Q
|
||||
xgCRXpcAhF2FAJSKhQDbydoAZRb+AGMX8wBiGP4AYRn/AFcd2gAyKDAARDw4AF9TUQBAJD4AOCYzADkw
|
||||
LgBnXloARSdlAEEiXgBAI1IAPiNfADInLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAV9gYWJjZGVmZ2hpAQEBAQFTVFVWV1hZWltcXV4BAQEBAUhJSktMTU5PUFFS
|
||||
AQEBAQE9Pj9AQUJDREVGRwEBAQEBMjM0NTY3ODk6OzwBAQEBASgpKissLS4vMDEBAQEBAQEBHh8gISIj
|
||||
JCUmJwEBAQEBARQVFhcYGRobHB0BAQEBAQEKCwwNDg8QERITAQEBAQEBAQIDBAUGBwgJAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEAgAEAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAEAACgAAAAQAAAAIAAAAAEA
|
||||
IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwKCY3MCgm2DAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJtgwKCY3MCgm2DAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm2DAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/0Q8OP9fU1H/QCQ+/zgm
|
||||
M/85MC7/Z15a/0UnZf9BIl7/QCNS/z4jX/8yJy3/MCgm/zAoJv8wKCb/MCgm/zAoJv9QR0P/39DG/5Fe
|
||||
l/+EXYX/lIqF/9vJ2v9lFv7/Yxfz/2IY/v9hGf//Vx3a/zIoMP8wKCb/MCgm/zAoJv8wKCb/MCgm/8q+
|
||||
tf/dzsv/1sTK/+fc1v+vjer/Xh7//10f//9YH7v/XR2Y/1oj8v8/J3T/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv+SiIL/u6G7/1wjif/m29r/fFT2/1Mn6f82J0T/RCNb/1geh/9UKuf/PiqA/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/V05L/+TY1v+CXKX/4Nfj/1Mw/v9MKr//RiNw/08qwv9PMOP/TDX6/zQqR/8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zEpJ//Xz8n/1MfV/66h7/9MN///TCau/0ox1f9HOev/QDWy/zYtX/8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/nJSR//Pt6P90bff/RT31/0YimP9DQPT/NzBs/zInMf8yKzv/MSow/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/15WVP/n4+3/Q0r9/z860/9BI5z/PkXs/zw7w/9AK6z/Okz0/zM2
|
||||
b/8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8yKij/mqDg/zpR/v80M23/OiWT/zk0v/82Vfz/NVj+/zNQ
|
||||
1/8wKi7/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zc2Uv8yNmX/MCkq/zAoLP8yJ0j/MS5V/zA2
|
||||
Xv8wKiz/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJtgwKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJtgwKCY3MCgm2DAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJtgwKCY3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAgAAAAQAAAAAEABAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAgAAAAACAAACAAIAAgIAAAAAAgACAgIAAAICAAAAA/wDAwMAA////AAD/
|
||||
/wD/AP8AAAAAAAAAAAAAAAAAAAAwIVBFIVBAVAFFEhcDAAAXEjAGADISMEUCUGBQQCADIVBFQDIBUCMB
|
||||
cQQAQDAyBFAhUjAhUhcQcBcQVFEgRRUhVAECMEUBcQRQcSAXAwACFUUHFxcEUgRUBAMEUEBxAyAQQQAB
|
||||
BRAwUFFSMARRAgRRJmYWMjRpNzY3M3FxBUUVIVaZMzEJmYyDjIaDAjIQAjAjqZaWmanIbIaMjHEFIwMh
|
||||
UpmampqWjIaDOGg3EhAEBUVqmZmprIg4NlOGgQVFFSEBaaY1mpiMc0UzaMJUAAIwcQmmM6mYxwBTY4hl
|
||||
EHEVQBcJmTaqhoNzNoaGMCMFAjBwFpo5qYyGOGjIaGAyEgMgEGCaaamGg2hohoYBIDAEAyMCmpqoaGOG
|
||||
hlYFBgMgFSECMGmqmGhlhoQAEhAgMgIwcQIaqmhoNoaEVnNwMhADIBcVCZpoaGiGhlOGhAMHBFFwEjap
|
||||
hoZWhoaGhoIwIRUhAXBAqYaDU4aGi4ZUAjACFQYBUJhoYGVlhoaGADAjAyBAUEVlaCUVVldzUlQGEARR
|
||||
BxIwIXEEAXEBBgQBUHAwIyEDIDIAYFIVJUBQMgQBAjAFQAYBVAEjBAFUASMAMgMhcQcQJUUCMHAXBxJQ
|
||||
YSUEBQRRIwEBcQQDIQFRIQcBAGBgBFBgIwcQVFBFIwIwEAABAjAEBRIBUhAGABJRAgDAAAADgAAAAQAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABwAAAAygA
|
||||
AAAgAAAAQAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCgmAEhFVgA0Q6UAM0OlADAs
|
||||
NwAyJ0AANCdlADQmbgA0K3UAMT+UADBGogAwQYkAMC4/ALCsqwBHXvsAOFP+ADM5egA1JmkAOSWjADgy
|
||||
uQA1VfcANFn+ADNa/gAyWfYAMTluADYuLADt6eYAhI32ADtP/gA4RMEANSZUADwkoAA8KakAOFD4ADhU
|
||||
/gA3Vf4ANlb+ADVX/gA1VvgAMS9GAGxlYwD18e0AwcHwAD5K/gA9SvkAPSaVAD8jngA9OtAAPTrPAD4u
|
||||
sgA8OckAOVH8ADRBoACrpaEA9O/rAPHs7ABNT/sAQkX+AEFH/gBBMMAAQiObAD9B5gA5P7cAPyOKAD4+
|
||||
2AA4R9AANCwqAOXe2gDz7egAhYD0AEVB/gBEQv4ARTnfAEUimABCQO4AODeQADMnNgA0Jz0AMytJADMw
|
||||
VQAyL04AZl5bAPDp5ADx6+YAvrfsAEg9/gBHPv4ARz37AEgjmwBIIZYARTrlAD86wwCjm5cA7ubgAOLZ
|
||||
3ADx6uUA7ebnAFNB/ABKOf4ASTv+AEopuABLIZMASS/KAEc9/gA/NrIAODB1ADUtWQAwKCkAMysoAN3U
|
||||
zgDu5d8Ak3axAOrh4ACGc/UATTX/AE0v2wBOIJAATSKZAEs29ABLN/8ANSxPAGBXVADr4toA7OPcAGE1
|
||||
lQDArMgA8OjjALus6QBRL/8AUDH6AFAgjwBRH44AUCOgAE4x6QBJN+wAMik4AJ2TjQDq39gAzr3JAFQf
|
||||
iwCTcK0A6ODhAFoz/ABTLf8APSlyADkmQQA/JFEATyB+AFIjoQBSJrIAUC3bAE8z/wBONP8APy6WANXK
|
||||
wgDo3dQAooKwAFceiABoNZIA7eTeAIdl8QBWKf8ASSm0ADQnMgBVHoUAUivgAEou0ABaUU0A5trRAHlJ
|
||||
lgBZHYYA0sDMAO3k3QC5oecAWyL/AFkl/wBXJfQAOydhADYoQwBRIHIAViS8AFQr/wBQK+QAlImDAOXY
|
||||
zgDFrsEA3c/RAOTZ3QBhJf0AXCD/AE0ktQBZHnwAXB2DAFkizgBQJ9oAzcC2AOPWzADp3tYA6uDYAIpX
|
||||
8gBfG/8AXR37AF4evgBeHZwASiWrAFVLRwDi1MkAv6OzALeZrwC4mrEAsZ2lAKqgmgDc0ckAuJblAGMX
|
||||
/wBhGf8AOCZOAI2BegDh0cYA2snCAGkhfQBlG3sAQSRBAJmPigDo3tUA4NLXAGgX/QBlE/8AZRT/AGUX
|
||||
zwBkFfsAYBj5AEIjdgCCdm8AmIuDAIRwdwBQIFYAMicpAJ6UjgBhNKAAURqnAFEdgwBQH2YATxyVAE8c
|
||||
pgBJH4wANiZBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAerr7O3t7e4Bzonv8PHx8vP09fb3AWwBAQEBAQEB
|
||||
AQEB2tvc3d7e3wHg4eLj5OXm5+XX1+jpAQEBAQEBAQEBAQHOz8/Q0dLT1NWK1tfX19jJycnJysrZAQEB
|
||||
AQEBAQEBAQHExbmpqZzGx3vIycnJycrLzMu+r80BAQEBAQEBAQEBAbi5qbq6urt7vL2vvq+vv8DBwcKw
|
||||
wwEBAQEBAQEBAQEBqKmpqqurrK2ur7CxsrKztKurtba3AQEBAQEBAQEBAQEBm5ydnp+gXqGioqMBAaSl
|
||||
np6mkKcBAQEBAQEBAQEBAQGJiouMjV6Oj5CQkZKTlJWWl5iZmgEBAQEBAQEBAQEBAXp7fH1+f4CBgYKD
|
||||
hIWGc3N4eIeIAQEBAQEBAQEBAQEBbW5vcHFgcnNzdHV2d3hjZGRJeQEBAQEBAQEBAQEBAQEBXV5fYGFi
|
||||
Y2RlZmdWaGlqa2wBAQEBAQEBAQEBAQEBAQFSU1RFVVZXWFlaW0dcAQEBAQEBAQEBAQEBAQEBAQEBAUNE
|
||||
RTdGR0hJSkpLOkxNTk5PUFEBAQEBAQEBAQEBAQEBATY3ODk6Ozw9PT4sP0A9PUEdQgEBAQEBAQEBAQEB
|
||||
AQEBKSorLCwtLi8vMB0dMTIzNBA1AQEBAQEBAQEBAQEBAQEaGxwdHR4fICAhIiMkJCUmJygBAQEBAQEB
|
||||
AQEBAQEBAQEODxAQEQESExMUFRYXFxgZAQEBAQEBAQEBAQEBAQEBAQIDBAQFAQEGBwgJCgsMDQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAMAAAAOAAAABAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHAAAADKAAAACAA
|
||||
AABAAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwKCYKMCgmgzAoJt8wKCb+MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv4wKCbfMCgmgzAoJgoAAAAAMCgmCjAoJsgwKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgmyDAoJgowKCaDMCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgmgzAo
|
||||
Jt8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCbfMCgm/jAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv4wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv+Cdm//mIuD/4Rw
|
||||
d/9QIFb/UCBW/1AgVf8yJyn/MCgm/1JKRv+dk43/npSO/2E0oP9RGaf/URqn/1Edg/9QH2b/TxyV/08c
|
||||
pv9JH4z/NiZB/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/42B
|
||||
ev/g0MX/2snC/2khff9lG3v/ZRt7/0EkQf8wKCb/mY+K/+je1f/g0tf/aBf9/2UT//9lFP//ZRfP/2QV
|
||||
+/9jFv//Yxb//2IX//9gGPn/QiN2/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/VUtH/+HSx//i1Mn/v6Oz/7eZr/+4mrH/sZ2l/6qgmv/c0cn/6t/Y/7iW5f9jF///Yhf//2IY
|
||||
//9hGf7/YRn//2Aa//9gG///Xxz//14c//9dHfv/OCZO/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8xKSf/zcC2/+PWzP/k2M7/5tnQ/+fb0v/o3dT/6d7W/+rg2P/r4tr/ilfy/18b
|
||||
//9fHP//Xx3//14d//9eHv7/Xh2//14dnP9dHr3/WyH9/1si//9KJav/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv+UiYP/5djO/+ba0P/Frb//xa3A/8Wuwv/dz9H/6+Lb/+TZ
|
||||
3f9hJf3/XCD//1wg//9bIf//WyH//00ktf9ZHnz/XB2D/1wdg/9ZIs7/WCb//1An2v8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/1pRTf/m2tH/59vT/3lJlv9ZHYb/WR2G/9LA
|
||||
zP/t5N3/uaHn/1oj//9ZJP//VyX0/zsnYf87J2H/NihD/1Egcv9ZHYb/WR2G/1YkvP9UK///UCvk/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MSkn/9XKwv/o3tX/ooKw/1ce
|
||||
iP9oNZL/7eTe/+7m4P+HZfH/Vij//1Yp//9JKbT/MCgm/zAoJv80JzL/VR6F/1ceiP9XHon/Uivg/1Ev
|
||||
//9KLtD/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/nJKN/+rf
|
||||
2P/Ovcn/VB+L/5Nwrf/u5uD/6ODh/1oz/P9TLP//Uy3//z0pcv85JkH/PyRR/08gfv9SI6H/Uiay/1At
|
||||
2/9PM///TjT//z8ulv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv9gV1T/6+La/+zj3P9hNZX/wKzI//Do4/+7rOn/UTD//1Ax//9QMfr/UCCP/1Efjv9QI6D/TjHp/001
|
||||
//9NNv//TDf//0s3//9JN+z/Mik4/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zMrKP/d1M7/7uXf/5N2sf/q4eD/8erl/4Zz9f9NNf//TTX//00v2/9OIJD/TSKZ/0s2
|
||||
9P9LOf7/Sjn+/0k6/v9JO/7/RTne/zUsT/8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/6Obl//v5+H/4tnc//Hq5f/t5uf/U0H8/0o5/v9KOv7/Sim4/0sh
|
||||
k/9JL8r/SDz+/0c9/v8/NrL/ODB1/zUtWf8wKCn/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/Zl5b//Dp5P/x6+b/8+3o/7637P9IPf7/Rz7+/0c9
|
||||
+/9II5v/SCGW/0U65f9FQf7/PzrD/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv80LCr/5d7a//Pt6P/07ur/hYD0/0RB
|
||||
/v9EQv7/RDnf/0UimP9FIpj/QkDu/0JF/v84N5D/Myc2/zQnPf80Jz3/MytJ/zMwVf8yL07/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv+rpaH/9O/r//Hs
|
||||
7P9NT/v/QUb+/0FH/v9BMMD/QiOb/0Ijm/8/Qeb/Pkr+/zk/t/8/I4r/QiOb/0Ijm/8+Ptj/O0/+/zhH
|
||||
0P8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/2xl
|
||||
Y//18e3/wcHw/z9K/v8+Sv7/PUr5/z0mlf8/I57/PyOe/z060P87Tv7/O0/+/z06z/8+LrL/PDnJ/zlR
|
||||
/P84U/7/NEGg/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/Ni4s/+3p5v+Ejfb/O07+/ztP/v84RMH/NSZU/zwkoP88JKD/PCmp/zhQ+P84VP7/N1T+/zZV
|
||||
/v82Vv7/NVf+/zVW+P8xL0b/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/sKyr/0de+/84U/7/OFP+/zM5ev8wKCb/NSZp/zklov85JaP/ODK5/zVV
|
||||
9/80Wf7/M1r+/zNa/v8yWfb/MTlu/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv9IRVb/NEOl/zNDpf8zQ6X/MCw3/zAoJv8wKCb/MidA/zQn
|
||||
Zf80Jm7/NCt1/zE/lP8wRqL/MEGJ/zAuP/8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv4wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb+MCgm3zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJt8wKCaDMCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgmgzAoJgowKCbIMCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJsgwKCYKAAAAADAoJgowKCaDMCgm3zAo
|
||||
Jv4wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/jAoJt8wKCaDMCgmCgAAAACAAAABAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAASgA
|
||||
AAAwAAAAYAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAACAAACAAIAAgIAAAAAA
|
||||
gACAgIAAAICAAAAA/wDAwMAAAP//AP///wD/AP8AAAAAAAAAAAAAAAAAAAAAYAMhUhJRJRcBIVJRIyAS
|
||||
AyMhUgAAAARUAGBUBFBAVAFwFwEGABUjBAAwIVAAAABRcQIQUBcXECMBcBcQBgQBcBcSMEAAADISAyFU
|
||||
BgAQcVIXFxBxcQVFAyAwIwYAAyFRcVBFASMHEEUAEAcQBFQAQFQCMCBUEgUhAgYAYFIQRQEjJUAXFQBg
|
||||
MhBRIDBFBUAXAwEjAhFwMhcQBFFwBFQARQYEUSMABFFwEjJRIyUEADIGAwIQYAFUUEADBxBxAyEBcBBA
|
||||
UBIVBgAwIGBUBUUgFxVAIQcQElBxBgcDIXAyEHEEUQEjISEDIBJRBgEGBUAXAQESEAEgMhBFFxcAUDBg
|
||||
cXAXBFIwBAMgMpmWNjcVQGmZaDjGNoaDMAMgFQEgAyFUBpmZMzMyBZubPIyDjIyGhlQDIGBUElAhUGuZ
|
||||
YzYxYZuZhoaMhoyMjIRSMBIVBUAwIWmbmZmZmbm8jIyGjIaMhoMBIHFSBFElFSmZm5uZubm2hoaMiDOG
|
||||
jIYHFRIQAyFUAha5uZm5ubmYyMjIk1ZThoxxBAUjEgUhUXG5mZmZm5vIaGiDhjM2OGgwcGASBUAwIQeZ
|
||||
uTc1m5s4yGU2UDc1OMhxAQYFBFEgMlGZuTMzm5uGjIElBjM2hoY3FSASAyFUUEBpuWNWubmMhlcQRTVj
|
||||
jIZRIDIwElAhBFAZuZM5ubOGhlEjU2M4aGgXBgElBUAyUQYJm5N5m5hoyGU4aGhoaGhAEGBRBAMgFwEm
|
||||
ubM7u5jIaDY2jIaMhoFQRQBAAyEDJUUBm7lrm4aGhjg4aGhoaGAGAEUXElBxAQIymZmbm4yGgzaGhoho
|
||||
YBcQcVQABUASVFElS7ubuYaGhlhoaGIDAjAjAhBxBFFwECMBW5m5toaGg2hoZRAyBgYBIwcSAyEGAjAj
|
||||
Kbu7mGhoNzhoZSEgEAAjAhBREgUhUSMgBrm5mGhoY4aGhFNWVjcwcVQCBUAwIwAVRbu7aGhoNTaGhlNz
|
||||
hoZxASUVBFElEgMhAJubhoaGg3hoaGOGioZRcDAhFUBUBUAyUWu5hoaDc4OGioaGhoZSASMXAlEhcVIB
|
||||
Iyu2hoZzhlaGhomGhoYDIwIAFUBRAhVFBFm4qGgQc4VoaGhoqGUCEHFUAhVAcVIQYAaYaKNxU3OHhoqG
|
||||
hlIVRRBAAyADBAFSFUVoaGUCMlNzh4aHVAMhAlRQBFFxIDIDAhUjAhBgEBcQQGASFUAFRRAjBgIQVAVA
|
||||
cVISUXAGBwFSUQcDAlFxASUQEFFwRQRRAhAwQBVAEGBAFUASMEAXBxBgBxIVEjIBcVIGBSFSVAUGAlFw
|
||||
IwUhIVIQBAUSUQAyASMBIVQBAyEhUSEDBARRUEUHAwRQQFQFRQBgUhUlQFAyBxUgYFASBgEhBFAhVAMh
|
||||
AXEEAwQBVAEjAQRRBAMhUDIwAGAyFSAyBxcAYHAXBxJQYCUXAjJQQSAAAAQFBFEjAQFxBAMhAVEhBgEh
|
||||
UQEjAlEAAABgYARQYCMHEFRQRSMCMFQFRSFSMBAAAAABAjAEBRIBUhAGABJRAhUEADIBBwAA8AAAAAAP
|
||||
AADgAAAAAAcAAMAAAAAAAwAAgAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAQAAwAAAAAAD
|
||||
AADgAAAAAAcAAPAAAAAADwAAKAAAADAAAABgAAAAAQAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAwKCYAQzw6AFZp3AA1UeQAMTBLADEoKQAzJ1sANSaBADYmjwA2JZMANieWADQ8tQAyTtEAMVXhADBU
|
||||
2AAwSq8AMDZeAIF7eQCapPMAOVL+ADZV/gA0PpMAMic9ADglkQA6JaIAOC6xADRR7wA0Wf4AM1r+ADJc
|
||||
/gAxSrIAMSktAMG8ugDX1+8APFH9ADtO/gA3StgAMSc1ADoklwA6K60AN1H1ADJJtwA+NjQA9O/rAPby
|
||||
8ABbZ/gAPE3+ADIuSgA5JX0APSSgAD8jngA6RuMAMjdtAHt0cQD18e0AmJvxAD5K/gA5OKYAPiyxADs/
|
||||
2AA8NLwAPDbDADpI6QA1SswAurSwANTR7ABASP4AP0LrAEEjnABDIpoAPzjOADw1sgBBJJ4APUbmADlR
|
||||
+QAyKjoAPTUzAO7m4QDz7ekAW1z3AEND/gBBRv4AQiepAEA+3gA1J0UAQDG9ADIwVAB1bWoA8OvoAJaS
|
||||
8QBEMcgAQzzmADw+wgA2JkgANStTADQ0bQCzq6cA8erlAM/J6QBHPv4ARUH+AEU66ABGIpcAPz7VADoy
|
||||
MADm3NoAXlP2AEgkoQBLIZMARTbUAEVA+wBvZ2MA7+jiAJWJ8ABKOv4ASizCAEwquQA3L2sAMio1AKyj
|
||||
ngDTxNIAwrDMAMzB6gBNNf4ASzLjAEo48wBGPPMAQznSADoxgwA2LiwA5trSAOzj3ACiiLcAk3WzAGFI
|
||||
+gBOIpwAVCGNAE0otABpYF0A6t/aAHRNngBmO5kAlH/vAFAx/wBQJ74AVB+LAKWblgDi1dYAyLrlAFMs
|
||||
/wBMLdMARCNjAE0gfgBSIpwAUCvNAE8w7gA9LogA3M/IAOne1gC1nLsAp4q4AGE7+QBJIm0AUCzbAGNa
|
||||
VwCJYqIAe0+eAJN17QBXJ/8APyl9AEwhcABbHYUAUivgADUpRACelI4A5NjPAGQujABbIokAxbLjAEwn
|
||||
wwA+JUUAVSOqADspYwA0LCoA1Mi/AMWvvwBmM/kAWiP/AEEmfgA8KWwANyY2AFcglwBeVVEA0r+9ALOV
|
||||
tgC0lrgAzrvGAJNr7gBeHf8AVCThAFgfpgCYjIYA4tXLAMOp4wBaIuIA0MK4AGoo+gBhGv8AXh3KAF8b
|
||||
qwBcH+cAVCPcAFlPSwDh0sYA39DEAN/RygCUYO4AZBX+AJGFfgB/R4oAZyN8AEAtPABNQ0EAv6HfAGQW
|
||||
9ABTH8QAx7muAGUbegBfHHAAbBv6AGUYqQBSHbsAMycyAMu8sQCgfpUAYBxtAE0hUQDUycEAhU3YAGIT
|
||||
6QBhE+cAYRmWAF8W1QBdF90AUhuzAD4jYgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQYBAQEBAQEBAQEBAQEBAQEBAQYGBgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB3+rq
|
||||
6uvs7Ozl7QEBATa57u7v8PHw8PLl0vPx9PX2AQEBAQEBAQEBAQEBAQEBAQEBBuPX18Lk5OTk5QYGAUGf
|
||||
n5Tm2tra4efh2tra0Nra6OkBAQEBAQEBAQEBAQEBAQEBAdvWy9bc3d3d3d6C34OfjODa2tra4dra0NDa
|
||||
0NDQ0OIGAQEBAQEBAQEBAQEBAQEBAdXWy8vXntjW2NjLsJ+fn9na0NDQ0NDQ0MfHx8fHx8e9AQEBAQEB
|
||||
AQEBAQEBAQEBAQHOy7CwsIODn4OfaoyEas/Qx8fHx8fH0NHS0tPHvLzUAQEBAQEBAQEBAQEBAQEBAQHK
|
||||
y8uwsIODn5+fn4yEzMfHx8fHx7y8yaysrKzNvKmprgEBAQEBAQEBAQEBAQEBAQHBsLCDwsPDxMPFhISE
|
||||
xsfHvLy8x7zItaysrKzJqamptwEBAQEBAQEBAQEBAQEBAQG4uYODuqysrKyghISMu7y8vLyqvb2+v6ys
|
||||
rKzAqamWvgEBAQEBAQEBAQEBAQEBAQEBr4ODsLGyrLKUTk6zqampqbQBAQEBtayskqy2lpaQtwEBAQEB
|
||||
AQEBAQEBAQEBAQEBpZ+fn6aSkqeEhHGoqamWqaoBAQEGq5KskpKtkJaQrgEBAQEBAQEBAQEBAQEBAQEB
|
||||
gp6fn6CSiaFxTk6ilpaWlkwBICajkpKSmqSQfJB9AQEBAQEBAQEBAQEBAQEBAQEBAZOMhJSJiXlxcZWW
|
||||
lpCQl5iZkpKam5x8fJB8fHydAQEBAQEBAQEBAQEBAQEBAQEBAYuMhISNjoRxYo+QkJCQkZKSbYp8fHxz
|
||||
c3xzc24gAQEBAQEBAQEBAQEBAQEBAQEBAYKDhISFhmJicYd8fHx8iG2JinN8c3xzc3NzbhcBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQF4Tk55emJie3x8fHx9bW1nfnNzZHNkf4CBIAEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQFwTnFOTk9icnNzc3N0bW11ZGRkXHZ3IAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFpamJiYk9Za2Rk
|
||||
ZGRsbWduZGRvXwEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBYWJPT09jZGRlZGZnZ2dcUlFoAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBWFlZLCxaUVFRUVtGRkZcUlJdBlVeXl5fYGBgTAEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBTU5PLDdQUVJSUlNGRkZUOUNKVUZGRkZWJCQkVwEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAUE3N0JDQ0M5REVGRUVHLy8kSEVGRUlKJBRLTAEBAQEBAQEBAQEBAQEBAQEBAQEBATY3Nzg5OTk5
|
||||
OjMzMzM7JCQUJDw9Pj8UFBVAAQEBAQEBAQEBAQEBAQEBAQEBAQEBASssLS4vLyQkMDEyMjMzNBQVFRUV
|
||||
FRUVFRU1AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEhIiMUFCQlASYnGRkZKCkVFRUVHBwcHSoBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQESExQUFRUWAQEXGBkZGRobHB0dHh4eHyABAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQECAwQEBAQFAQEBBgcICQoLDA0ODxARAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAABAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAADwAAAAAA8AAOAAAAAABwAAwAAAAAADAACAAAAAAAEAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAgAAAAAABAADAAAAAAAMAAOAAAAAABwAA8AAAAAAPAAAoAAAAMAAAAGAA
|
||||
AAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCgmLDAoJpkwKCbeMCgm/TAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb9MCgm3jAoJpkwKCYsAAAAAAAAAAAAAAAAAAAAADAoJgEwKCZ3MCgm+TAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb5MCgmdzAoJgEAAAAAAAAAADAo
|
||||
JncwKCb+MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/jAo
|
||||
JncAAAAAMCgmLDAoJvkwKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJvkwKCYsMCgmmTAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCaZMCgm3jAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCbeMCgm/TAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb9MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/05EQf/Lu7D/y7yx/8y9s/+gfpX/YBxt/2Acbf9gHG3/YBxt/00hUf8wKCb/MCgm/zAo
|
||||
Jv99dG//08jA/9TJwf/VysP/hU3Y/2IS5/9iEuf/YRPo/2IT6f9hGZb/YBt4/18Yrv9fFtX/YBXm/10X
|
||||
3f9SG7P/PiNi/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zIqKP/Hua7/39DE/+DRxf/Sv73/Zhx7/2Ybe/9mG3v/Zht7/18c
|
||||
cP8xKCf/MCgm/zAoJv+/tK3/6N3V/+ne1v/k2Nb/bBv6/2YS//9mEv//ZRP//2UU+P9lGKn/ZBX1/2QU
|
||||
//9kFf//YxX//2MW//9jFv//Yhf//1Idu/8zJzL/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv+RhX7/4NHG/+HSx//h08j/f0eK/2cj
|
||||
fP9nI3z/ZyN8/2cjfP9ALTz/Ny8t/0tCQP/l2tL/6d7W/+rf2P+/od//ZBT//2QV//9kFf//Yxb//2MX
|
||||
8v9jF/v/Yhf//2IX//9iGP//YRj//2EZ//9hGv//YBr//2Ab//9TH8T/MSgp/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv9ZT0v/4dLH/+LT
|
||||
yf/i1Mr/39DI/93PyP/e0Mn/39HK/+DSzP/f08z/4NXM/+LYz//p3tf/6t/Y/+vh2f+UYO7/Yhf//2IY
|
||||
//9hGP//YRn//2EZ//9hGf//YBr//2Ab//9gG///Xxz//18c//9eHf//Xh3//14e//9dHv//QiR9/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8xKSf/0MK4/+PVyv/j1sz/5NfN/+XYzv/m2dD/5trR/+fb0//o3NT/6N7V/+nf1//q4Nj/6+HZ/+ba
|
||||
2/9qKPr/YBr//2Ab//9fG///Xxz//18c//9fHP//Xh3//14d/P9eHcr/Xh2o/10ds/9cH+f/XCD//1wh
|
||||
//9bIf//VCPc/zAoJ/8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/mIyG/+PWzP/k183/5djP/+bZ0P/m2tL/59zT/+jd1P/p3tb/6d/X/+rg
|
||||
2P/r4dr/7OLb/8Op4/9eHf//Xh3//14e//9dHv//XR///10f//9cH///XCD+/1gfpv9eHIL/XhyC/14c
|
||||
gv9dHYb/WiLi/1kk//9ZJP//WCX9/zUoQv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/XlVR/+TXzv/l2M//5trQ/8+8xP+zlLX/s5W2/7OV
|
||||
t/+0lrj/zbnH/+vh2v/s4tv/7OTd/5Nr7v9cIP//XCD//1sh//9bIf//WyL+/1si//9aIv//VCTh/z8k
|
||||
Rv9cHYT/XB2E/1wdhP9cHYT/WSCp/1cm//9XJ///Vyf//zsoYv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/NCwq/9TIv//m2tH/59vS/8Wv
|
||||
v/9aHYX/Wh2F/1odhf9aHYX/up++/+zj3P/t5N3/6d/e/2Yz+f9aI///WiP//1kk//9YJPv/QSZ+/0Em
|
||||
f/9BJ3//PCdo/zcmNv9aHYX/Wh2F/1odhf9aHYX/VyCX/1Up//9VKv//VCv//zwpbP8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/56U
|
||||
jv/n29L/6NzU/+TY0v9kLoz/WB6H/1geh/9bIon/49bX/+3k3f/u5d//xbLj/1gl//9YJv//WCb//1cn
|
||||
//9MJ8P/MCgm/zAoJv8wKCb/MCgm/zwlQ/9YHof/WB6H/1geh/9YHof/VSOq/1Mt//9TLf//Ui7//zoq
|
||||
Y/8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/2NaV//o3NT/6N7V/+nf1/+JYqL/Vh6J/1Yeif97T57/7eTe/+7l3//u5uD/k3Xt/1Yo
|
||||
//9WKf//VSn//1Uq//8/KX3/MCgm/zAoJv8wKCb/MSgo/0whcP9WHon/Vh6J/1Yeif9WHor/Uivg/1Ev
|
||||
//9RMP//UDD9/zUpRf8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zYuLP/az8j/6d/X/+rg2P+1nLv/VB+L/1Qfi/+nirj/7ubf/+/n
|
||||
4f/t5eH/YTv5/1Qr//9ULP//Uyz//1It+v8zKDv/MCgn/zEoKv82Jjn/SSJt/1Qfi/9UH4v/VCCP/1Mi
|
||||
nf9QLNv/TzL//08y//9PM///SjLg/zAoKP8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv+lm5b/6uDZ/+vh2v/g1NT/VCKN/1Mg
|
||||
jP/UxdL/7+fh/+/o4v/IuuX/Ui7//1Iu//9SL///US///0wt0/9EI2P/TSB+/1EfiP9SH4z/USKb/1Ar
|
||||
zf9PMO7/TjP4/040//9ONP//TTX//002//9MNv//PS6I/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv9pYF3/6+La/+zj
|
||||
3P/t5N3/dE2e/2Y7mf/t5eD/8Ojj//Dp5P+Uf+//UDH//1Ax//9PMv//TzL//1Anvv9QH47/UB+O/1Af
|
||||
jv9OKLj/TTT6/001//9NNv//TDb//0w3//9LN///Szj//0s4/v9FNdX/MSgs/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv82Liz/4tnS/+3k3f/u5d//ooi3/5N1s//w6eP/8erk/+7n5f9hSPr/TjT//040//9NNf//TTX9/04i
|
||||
nP9OIJD/TiCQ/00otP9LN/7/Szj//0s4/v9KOf7/Sjn+/0o6/v9JOv7/STv+/0Q30/8zKj3/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/rKOe/+7l3//u5uD/0cPR/8KwzP/x6uT/8evm/8zB6v9NN///TDf//0w3
|
||||
//9LOP//SzLl/0wgkv9MIJL/TCKX/0o48/9JOv7/STv+/0k7/v9IPP7/SDz8/0Y88/9DOdL/OjGD/zEp
|
||||
Lf8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/b2dj/+/n4f/v6OL/7+fj/+7m4//y6+b/8uzo/5WJ
|
||||
8P9KOf7/Sjr+/0o6/v9JO/7/SizC/0ohk/9KIZP/SSy6/0g9/v9HPf7/Rz7+/0Q85/83L2v/Mio1/zEp
|
||||
Lv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/OjIw/+be2f/w6eT/8erl//Lr
|
||||
5//y7Oj/8Ovo/15T9v9IPP7/SD3+/0c9/v9HPv7/SCSh/0ghlf9IIZX/RjXV/0ZA/v9FQP7/RUD7/zQt
|
||||
VP8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/7Or
|
||||
p//x6uX/8uzn//Pt6P/z7ur/z8np/0Y//v9GP/7/RkD+/0VA/v9FOuj/RiKX/0Yil/9GIpf/RDvj/0ND
|
||||
/v9DQ/7/Pz7V/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/3Vtav/y7Of/8+3o//Pu6v/07+v/lpLx/0RC/v9EQv7/Q0P+/0ND/v9EMcj/RCKZ/0Qi
|
||||
mf9EIpn/Qj7n/0FG/v9BRv7/PD7C/zEoKv82Jkf/NiZI/zYmSP82Jkj/NilR/zQ0bf80NG3/NDRt/zEr
|
||||
Of8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/z01M//r5eH/9O7q//Tv6//18O3/W1z3/0JF/v9CRf7/QUb+/0FG
|
||||
/f9CJ6n/QyKa/0Mimv9DIpr/QD7e/z9J/v8/Sf7/PUbk/zQnQv9DIpr/QyKa/0Mimv9DIpr/QDG9/zxN
|
||||
/v88Tv7/O07+/zIwVP8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv+6tLD/9fDs//Xx7f/U0ez/QEf+/0BI
|
||||
/v9ASP7/P0n+/z9C6/9BI53/QSOc/0EjnP9BI5z/PzjO/z1M/v89TP7/PE3+/zw1sv9BI5z/QSOc/0Ej
|
||||
nP9BJJ7/PEbn/zpQ/v85Uf7/OVH5/zErOP8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv97dHH/9fHt//by
|
||||
7/+Ym/H/Pkr+/z5L/v89S/7/PUz+/zk4pv8/I53/PyOe/z8jnv8/I57/Piyx/ztP/v87T/7/OlD+/zpQ
|
||||
/P87P9j/PDS8/zw2w/86SOn/OFP+/zhT/v83VP7/NUrM/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8+NjT/8u7r//by8P9bZ/j/PE3+/zxO/v87Tv7/O078/zIuSv85JX3/PSSg/z0koP89JKD/PSSg/zpG
|
||||
4/84Uv7/OFP+/zhT/v83VP7/N1T+/zdV/v82Vf7/Nlb+/zZW/v81V/7/Mjdt/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/wby6/9fX7/88Uf3/OlD+/zpR/v85Uf7/N0rY/zAoJ/8xJzX/OiSX/zsk
|
||||
of87JKH/OySh/zorrf83UfX/Nlb+/zZW/v81V/7/NVf+/zVY/v80WP7/NFn+/zNZ/v8ySbf/MCgn/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/gXt5/5qk8/84U/7/OFP+/zdU/v83VP7/ND6T/zAo
|
||||
Jv8wKCb/Mic9/zglkf85JaP/OSWj/zklo/84LrH/NFHv/zRZ/v8zWv7/M1r+/zJb/v8yW/7/Mlz+/zFK
|
||||
sv8wKi7/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/Qzw6/1Zp3P81UOT/NVDk/zVR
|
||||
5P81UeT/MTBL/zAoJv8wKCb/MCgm/zAoK/8zJ1v/NSaB/zYmj/82JZP/NieW/zQ8tf8yTtH/MVXh/zBU
|
||||
2P8wSq//MDZe/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/TAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb9MCgm3jAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCbeMCgmmTAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCaZMCgmLDAoJvkwKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJvkwKCYsAAAAADAoJncwKCb+MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/jAoJncAAAAAAAAAADAoJgEwKCZ3MCgm+TAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb5MCgmdzAoJgEAAAAAAAAAAAAA
|
||||
AAAAAAAAMCgmLDAoJpkwKCbeMCgm/TAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAo
|
||||
Jv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb/MCgm/zAoJv8wKCb9MCgm3jAoJpkwKCYsAAAAAAAA
|
||||
AAAAAAAA4AAAAAAHAACAAAAAAAEAAIAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
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
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2,19 +2,19 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFrameworks>net472;net6.0-windows;net7.0-windows;net8.0-windows</TargetFrameworks>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
|
||||
<AssemblyTitle>AssetStudio Mod by VaDiM</AssemblyTitle>
|
||||
<Version>0.16.8.1</Version>
|
||||
<AssemblyVersion>0.16.8.1</AssemblyVersion>
|
||||
<FileVersion>0.16.8.1</FileVersion>
|
||||
<Copyright>Copyright © Perfare 2018-2021</Copyright>
|
||||
<AssemblyTitle>ArknightsStudio by aelurum</AssemblyTitle>
|
||||
<AssemblyName>ArknightsStudioGUI</AssemblyName>
|
||||
<Version>1.2.0</Version>
|
||||
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2021-2025</Copyright>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
||||
<IsPublishable>false</IsPublishable>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -23,14 +23,14 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<None Update="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -47,26 +47,80 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ContentWithTargetPath Include="Libraries\x86\fmod.dll">
|
||||
<ContentWithTargetPath Include="..\LICENSE">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>x86\fmod.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="Libraries\x64\fmod.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>x64\fmod.dll</TargetPath>
|
||||
<TargetPath>LICENSE</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="OpenTK" Version="3.1.0" />
|
||||
<PackageReference Include="OpenTK.GLControl" Version="3.1.0" />
|
||||
<PackageReference Include="Microsoft-WindowsAPICodePack-Core-6.0" Version="1.1.6" />
|
||||
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell-6.0" Version="1.1.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CustomAfterBuild" AfterTargets="AfterBuild">
|
||||
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\Win32\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)x86" ContinueOnError="true" />
|
||||
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\x64\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)x64" ContinueOnError="true" />
|
||||
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\Win32\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)x86" ContinueOnError="true" />
|
||||
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\x64\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)x64" ContinueOnError="true" />
|
||||
<ItemGroup Condition=" '$(TargetFramework)' != 'net472' ">
|
||||
<PackageReference Include="OpenTK.Graphics" Version="4.8.2" />
|
||||
<PackageReference Include="OpenTK.Windowing.Desktop" Version="4.8.2" />
|
||||
<Reference Include="OpenTK.WinForms">
|
||||
<HintPath>Libraries\OpenTK.WinForms.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
||||
<PackageReference Include="OpenTK" Version="3.3.3" />
|
||||
<PackageReference Include="OpenTK.GLControl" Version="3.3.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Use local compiled win-x86 and win-x64 Texture2DDecoder libs, because libs from Kyaru.Texture2DDecoder.Windows were compiled with /MD flag -->
|
||||
|
||||
<Target Name="CopyExtraFilesPortable" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == '' OR '$(TargetFramework)' == 'net472' ">
|
||||
<Message Text="Copying extra files for $(TargetFramework)... " Importance="high" />
|
||||
<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)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="$(ProjectDir)Libraries\x86\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-x86\native" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(ProjectDir)Libraries\x64\fmod.dll" DestinationFolder="$(TargetDir)runtimes\win-x64\native" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Publishing an app as framework-dependent produces a cross-platform binary as a dll file, and a platform-specific executable that targets your current platform.
|
||||
The dll is cross-platform while the executable isn't -->
|
||||
<Target Name="PublishExtraFilesPortable" AfterTargets="Publish" Condition=" '$(RuntimeIdentifier)' == '' ">
|
||||
<Message Text="Publishing 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-x64\native\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(TargetDir)runtimes\win-x86\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-x86\native" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(TargetDir)runtimes\win-x64\native\fmod.dll" DestinationFolder="$(PublishDir)runtimes\win-x64\native" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<!-- No need to publish net472 build of AssetStudioGUI -->
|
||||
<Target Name="PublishNet472" AfterTargets="Publish" Condition=" '$(TargetFramework)' == 'net472' ">
|
||||
<Message Text="%0a NOTE: Publishing net472 build of AssetStudioGUI was disabled." Importance="high" />
|
||||
<Message Text=" Instead, use the binaries created after the build.%0a" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyExtraFilesWin86" AfterTargets="AfterBuild" Condition=" $(RuntimeIdentifier.Contains('-x86')) AND '$(TargetFramework)' != 'net472' ">
|
||||
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
|
||||
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\Win32\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\Win32\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(ProjectDir)Libraries\x86\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyExtraFilesWin64" AfterTargets="AfterBuild" Condition=" '$(RuntimeIdentifier)' == 'win-x64' AND '$(TargetFramework)' != 'net472' ">
|
||||
<Message Text="Copying extra files for $(RuntimeIdentifier)($(TargetFramework))... " Importance="high" />
|
||||
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\x64\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\x64\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
<Copy SourceFiles="$(ProjectDir)Libraries\x64\fmod.dll" DestinationFolder="$(TargetDir)" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishExtraFilesWin" AfterTargets="Publish" Condition=" $(RuntimeIdentifier.Contains('win')) AND '$(TargetFramework)' != 'net472' ">
|
||||
<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)\fmod.dll" DestinationFolder="$(PublishDir)" ContinueOnError="false" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
343
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
343
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
@@ -41,6 +41,12 @@
|
||||
this.displayAll = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.enablePreview = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.displayInfo = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.akSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.akTitleMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.akFixFaceSpriteNamesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.akUseExternalAlphaToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.akSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.buildTreeStructureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.specifyUnityVersion = new System.Windows.Forms.ToolStripTextBox();
|
||||
this.showExpOpt = new System.Windows.Forms.ToolStripMenuItem();
|
||||
@@ -66,6 +72,8 @@
|
||||
this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.allLive2DModelsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
@@ -75,7 +83,10 @@
|
||||
this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.debugMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem15 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.showConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.writeLogToFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.exportClassStructuresMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||
@@ -88,7 +99,10 @@
|
||||
this.columnHeaderType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.columnHeaderPathID = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.columnHeaderSize = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.listSearch = new System.Windows.Forms.TextBox();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.listSearch = new System.Windows.Forms.RichTextBox();
|
||||
this.listSearchHistory = new System.Windows.Forms.ComboBox();
|
||||
this.listSearchFilterMode = new System.Windows.Forms.ComboBox();
|
||||
this.tabPage3 = new System.Windows.Forms.TabPage();
|
||||
this.classesListView = new System.Windows.Forms.ListView();
|
||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
@@ -118,6 +132,14 @@
|
||||
this.dumpTextBox = new System.Windows.Forms.TextBox();
|
||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.contextMenuStrip2 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.showRelatedAssetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.clearSelectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.expandAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.collapseAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.timer = new System.Windows.Forms.Timer(this.components);
|
||||
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
|
||||
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
@@ -135,6 +157,7 @@
|
||||
this.tabControl1.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
this.tabPage2.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.tabPage3.SuspendLayout();
|
||||
this.progressbarPanel.SuspendLayout();
|
||||
this.tabControl2.SuspendLayout();
|
||||
@@ -145,6 +168,7 @@
|
||||
((System.ComponentModel.ISupportInitialize)(this.FMODvolumeBar)).BeginInit();
|
||||
this.tabPage5.SuspendLayout();
|
||||
this.statusStrip1.SuspendLayout();
|
||||
this.contextMenuStrip2.SuspendLayout();
|
||||
this.contextMenuStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
@@ -156,7 +180,8 @@
|
||||
this.modelToolStripMenuItem,
|
||||
this.exportToolStripMenuItem,
|
||||
this.filterTypeToolStripMenuItem,
|
||||
this.debugMenuItem});
|
||||
this.debugMenuItem,
|
||||
this.aboutToolStripMenuItem});
|
||||
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.menuStrip1.Name = "menuStrip1";
|
||||
this.menuStrip1.Size = new System.Drawing.Size(1264, 24);
|
||||
@@ -214,6 +239,12 @@
|
||||
this.displayAll,
|
||||
this.enablePreview,
|
||||
this.displayInfo,
|
||||
this.akSeparator1,
|
||||
this.akTitleMenuItem,
|
||||
this.akFixFaceSpriteNamesToolStripMenuItem,
|
||||
this.akUseExternalAlphaToolStripMenuItem,
|
||||
this.akSeparator2,
|
||||
this.buildTreeStructureToolStripMenuItem,
|
||||
this.toolStripMenuItem14,
|
||||
this.showExpOpt});
|
||||
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
||||
@@ -224,7 +255,7 @@
|
||||
//
|
||||
this.displayAll.CheckOnClick = true;
|
||||
this.displayAll.Name = "displayAll";
|
||||
this.displayAll.Size = new System.Drawing.Size(207, 22);
|
||||
this.displayAll.Size = new System.Drawing.Size(276, 22);
|
||||
this.displayAll.Text = "Display all assets";
|
||||
this.displayAll.ToolTipText = "Check this option will display all types assets. Not extractable assets can expor" +
|
||||
"t the RAW file.";
|
||||
@@ -236,7 +267,7 @@
|
||||
this.enablePreview.CheckOnClick = true;
|
||||
this.enablePreview.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.enablePreview.Name = "enablePreview";
|
||||
this.enablePreview.Size = new System.Drawing.Size(207, 22);
|
||||
this.enablePreview.Size = new System.Drawing.Size(276, 22);
|
||||
this.enablePreview.Text = "Enable preview";
|
||||
this.enablePreview.ToolTipText = "Toggle the loading and preview of readable assets, such as images, sounds, text, " +
|
||||
"etc.\r\nDisable preview if you have performance or compatibility issues.";
|
||||
@@ -248,30 +279,85 @@
|
||||
this.displayInfo.CheckOnClick = true;
|
||||
this.displayInfo.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.displayInfo.Name = "displayInfo";
|
||||
this.displayInfo.Size = new System.Drawing.Size(207, 22);
|
||||
this.displayInfo.Text = "Display asset infromation";
|
||||
this.displayInfo.Size = new System.Drawing.Size(276, 22);
|
||||
this.displayInfo.Text = "Display asset information";
|
||||
this.displayInfo.ToolTipText = "Toggle the overlay that shows information about each asset, eg. image size, forma" +
|
||||
"t, audio bitrate, etc.";
|
||||
this.displayInfo.CheckedChanged += new System.EventHandler(this.displayAssetInfo_Check);
|
||||
//
|
||||
// akSeparator1
|
||||
//
|
||||
this.akSeparator1.Name = "akSeparator1";
|
||||
this.akSeparator1.Size = new System.Drawing.Size(273, 6);
|
||||
//
|
||||
// akTitleMenuItem
|
||||
//
|
||||
this.akTitleMenuItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.akTitleMenuItem.Enabled = false;
|
||||
this.akTitleMenuItem.Name = "akTitleMenuItem";
|
||||
this.akTitleMenuItem.ShowShortcutKeys = false;
|
||||
this.akTitleMenuItem.Size = new System.Drawing.Size(276, 22);
|
||||
this.akTitleMenuItem.Text = "Arknights";
|
||||
//
|
||||
// akFixFaceSpriteNamesToolStripMenuItem
|
||||
//
|
||||
this.akFixFaceSpriteNamesToolStripMenuItem.Checked = true;
|
||||
this.akFixFaceSpriteNamesToolStripMenuItem.CheckOnClick = true;
|
||||
this.akFixFaceSpriteNamesToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.akFixFaceSpriteNamesToolStripMenuItem.Name = "akFixFaceSpriteNamesToolStripMenuItem";
|
||||
this.akFixFaceSpriteNamesToolStripMenuItem.Size = new System.Drawing.Size(276, 22);
|
||||
this.akFixFaceSpriteNamesToolStripMenuItem.Text = "Restore 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);
|
||||
//
|
||||
// akUseExternalAlphaToolStripMenuItem
|
||||
//
|
||||
this.akUseExternalAlphaToolStripMenuItem.Checked = true;
|
||||
this.akUseExternalAlphaToolStripMenuItem.CheckOnClick = true;
|
||||
this.akUseExternalAlphaToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.akUseExternalAlphaToolStripMenuItem.Name = "akUseExternalAlphaToolStripMenuItem";
|
||||
this.akUseExternalAlphaToolStripMenuItem.Size = new System.Drawing.Size(276, 22);
|
||||
this.akUseExternalAlphaToolStripMenuItem.Text = "Use external alpha texture for sprites";
|
||||
this.akUseExternalAlphaToolStripMenuItem.ToolTipText = "Trying to find an external alpha texture for preview/export sprite assets (Skins," +
|
||||
" Char arts, Avg char arts, etc.)";
|
||||
this.akUseExternalAlphaToolStripMenuItem.CheckedChanged += new System.EventHandler(this.akUseExternalAlphaToolStripMenuItem_Check);
|
||||
//
|
||||
// akSeparator2
|
||||
//
|
||||
this.akSeparator2.Name = "akSeparator2";
|
||||
this.akSeparator2.Size = new System.Drawing.Size(273, 6);
|
||||
//
|
||||
// buildTreeStructureToolStripMenuItem
|
||||
//
|
||||
this.buildTreeStructureToolStripMenuItem.Checked = true;
|
||||
this.buildTreeStructureToolStripMenuItem.CheckOnClick = true;
|
||||
this.buildTreeStructureToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.buildTreeStructureToolStripMenuItem.Name = "buildTreeStructureToolStripMenuItem";
|
||||
this.buildTreeStructureToolStripMenuItem.Size = new System.Drawing.Size(276, 22);
|
||||
this.buildTreeStructureToolStripMenuItem.Text = "Build tree structure";
|
||||
this.buildTreeStructureToolStripMenuItem.ToolTipText = "You can disable tree structure building if you don\'t use the Scene Hierarchy tab";
|
||||
this.buildTreeStructureToolStripMenuItem.CheckedChanged += new System.EventHandler(this.buildTreeStructureToolStripMenuItem_CheckedChanged);
|
||||
//
|
||||
// toolStripMenuItem14
|
||||
//
|
||||
this.toolStripMenuItem14.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.specifyUnityVersion});
|
||||
this.toolStripMenuItem14.Name = "toolStripMenuItem14";
|
||||
this.toolStripMenuItem14.Size = new System.Drawing.Size(207, 22);
|
||||
this.toolStripMenuItem14.Size = new System.Drawing.Size(276, 22);
|
||||
this.toolStripMenuItem14.Text = "Specify Unity version";
|
||||
//
|
||||
// specifyUnityVersion
|
||||
//
|
||||
this.specifyUnityVersion.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.specifyUnityVersion.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F);
|
||||
this.specifyUnityVersion.Name = "specifyUnityVersion";
|
||||
this.specifyUnityVersion.Size = new System.Drawing.Size(100, 23);
|
||||
this.specifyUnityVersion.ToolTipText = "Specify full Unity version, including letters at the end\r\nExample: 2017.4.39f1";
|
||||
//
|
||||
// showExpOpt
|
||||
//
|
||||
this.showExpOpt.Name = "showExpOpt";
|
||||
this.showExpOpt.Size = new System.Drawing.Size(207, 22);
|
||||
this.showExpOpt.Size = new System.Drawing.Size(276, 22);
|
||||
this.showExpOpt.Text = "Export options";
|
||||
this.showExpOpt.Click += new System.EventHandler(this.showExpOpt_Click);
|
||||
//
|
||||
@@ -339,6 +425,8 @@
|
||||
this.toolStripSeparator4,
|
||||
this.toolStripMenuItem2,
|
||||
this.toolStripMenuItem3,
|
||||
this.toolStripSeparator6,
|
||||
this.allLive2DModelsToolStripMenuItem,
|
||||
this.toolStripSeparator2,
|
||||
this.toolStripMenuItem10});
|
||||
this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
|
||||
@@ -445,6 +533,18 @@
|
||||
this.toolStripMenuItem9.Text = "Filtered assets";
|
||||
this.toolStripMenuItem9.Click += new System.EventHandler(this.toolStripMenuItem9_Click);
|
||||
//
|
||||
// toolStripSeparator6
|
||||
//
|
||||
this.toolStripSeparator6.Name = "toolStripSeparator6";
|
||||
this.toolStripSeparator6.Size = new System.Drawing.Size(263, 6);
|
||||
//
|
||||
// allLive2DModelsToolStripMenuItem
|
||||
//
|
||||
this.allLive2DModelsToolStripMenuItem.Name = "allLive2DModelsToolStripMenuItem";
|
||||
this.allLive2DModelsToolStripMenuItem.Size = new System.Drawing.Size(266, 22);
|
||||
this.allLive2DModelsToolStripMenuItem.Text = "Live2D Cubism models";
|
||||
this.allLive2DModelsToolStripMenuItem.Click += new System.EventHandler(this.allLive2DModelsToolStripMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
this.toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
@@ -503,6 +603,8 @@
|
||||
//
|
||||
this.debugMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.toolStripMenuItem15,
|
||||
this.showConsoleToolStripMenuItem,
|
||||
this.writeLogToFileToolStripMenuItem,
|
||||
this.exportClassStructuresMenuItem});
|
||||
this.debugMenuItem.Name = "debugMenuItem";
|
||||
this.debugMenuItem.Size = new System.Drawing.Size(54, 20);
|
||||
@@ -516,6 +618,24 @@
|
||||
this.toolStripMenuItem15.Text = "Show all error messages";
|
||||
this.toolStripMenuItem15.Click += new System.EventHandler(this.toolStripMenuItem15_Click);
|
||||
//
|
||||
// showConsoleToolStripMenuItem
|
||||
//
|
||||
this.showConsoleToolStripMenuItem.Checked = true;
|
||||
this.showConsoleToolStripMenuItem.CheckOnClick = true;
|
||||
this.showConsoleToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.showConsoleToolStripMenuItem.Name = "showConsoleToolStripMenuItem";
|
||||
this.showConsoleToolStripMenuItem.Size = new System.Drawing.Size(200, 22);
|
||||
this.showConsoleToolStripMenuItem.Text = "Show console logger";
|
||||
this.showConsoleToolStripMenuItem.Click += new System.EventHandler(this.showConsoleToolStripMenuItem_Click);
|
||||
//
|
||||
// writeLogToFileToolStripMenuItem
|
||||
//
|
||||
this.writeLogToFileToolStripMenuItem.CheckOnClick = true;
|
||||
this.writeLogToFileToolStripMenuItem.Name = "writeLogToFileToolStripMenuItem";
|
||||
this.writeLogToFileToolStripMenuItem.Size = new System.Drawing.Size(200, 22);
|
||||
this.writeLogToFileToolStripMenuItem.Text = "Write log to file";
|
||||
this.writeLogToFileToolStripMenuItem.CheckedChanged += new System.EventHandler(this.writeLogToFileToolStripMenuItem_CheckedChanged);
|
||||
//
|
||||
// exportClassStructuresMenuItem
|
||||
//
|
||||
this.exportClassStructuresMenuItem.Name = "exportClassStructuresMenuItem";
|
||||
@@ -523,6 +643,13 @@
|
||||
this.exportClassStructuresMenuItem.Text = "Export class structures";
|
||||
this.exportClassStructuresMenuItem.Click += new System.EventHandler(this.exportClassStructuresMenuItem_Click);
|
||||
//
|
||||
// aboutToolStripMenuItem
|
||||
//
|
||||
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
|
||||
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(52, 20);
|
||||
this.aboutToolStripMenuItem.Text = "About";
|
||||
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
|
||||
//
|
||||
// splitContainer1
|
||||
//
|
||||
this.splitContainer1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
@@ -582,6 +709,7 @@
|
||||
this.sceneTreeView.Size = new System.Drawing.Size(472, 587);
|
||||
this.sceneTreeView.TabIndex = 1;
|
||||
this.sceneTreeView.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.sceneTreeView_AfterCheck);
|
||||
this.sceneTreeView.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.sceneTreeView_NodeMouseClick);
|
||||
//
|
||||
// treeSearch
|
||||
//
|
||||
@@ -590,7 +718,7 @@
|
||||
this.treeSearch.Location = new System.Drawing.Point(0, 0);
|
||||
this.treeSearch.Name = "treeSearch";
|
||||
this.treeSearch.Size = new System.Drawing.Size(472, 20);
|
||||
this.treeSearch.TabIndex = 0;
|
||||
this.treeSearch.TabIndex = 2;
|
||||
this.treeSearch.Text = " Search ";
|
||||
this.treeSearch.TextChanged += new System.EventHandler(this.treeSearch_TextChanged);
|
||||
this.treeSearch.Enter += new System.EventHandler(this.treeSearch_Enter);
|
||||
@@ -600,7 +728,7 @@
|
||||
// tabPage2
|
||||
//
|
||||
this.tabPage2.Controls.Add(this.assetListView);
|
||||
this.tabPage2.Controls.Add(this.listSearch);
|
||||
this.tabPage2.Controls.Add(this.panel1);
|
||||
this.tabPage2.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabPage2.Name = "tabPage2";
|
||||
this.tabPage2.Size = new System.Drawing.Size(472, 607);
|
||||
@@ -620,9 +748,9 @@
|
||||
this.assetListView.FullRowSelect = true;
|
||||
this.assetListView.GridLines = true;
|
||||
this.assetListView.HideSelection = false;
|
||||
this.assetListView.Location = new System.Drawing.Point(0, 20);
|
||||
this.assetListView.Location = new System.Drawing.Point(0, 23);
|
||||
this.assetListView.Name = "assetListView";
|
||||
this.assetListView.Size = new System.Drawing.Size(472, 587);
|
||||
this.assetListView.Size = new System.Drawing.Size(472, 584);
|
||||
this.assetListView.TabIndex = 1;
|
||||
this.assetListView.UseCompatibleStateImageBehavior = false;
|
||||
this.assetListView.View = System.Windows.Forms.View.Details;
|
||||
@@ -658,19 +786,68 @@
|
||||
this.columnHeaderSize.Text = "Size";
|
||||
this.columnHeaderSize.Width = 50;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.listSearch);
|
||||
this.panel1.Controls.Add(this.listSearchHistory);
|
||||
this.panel1.Controls.Add(this.listSearchFilterMode);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(472, 23);
|
||||
this.panel1.TabIndex = 2;
|
||||
//
|
||||
// listSearch
|
||||
//
|
||||
this.listSearch.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.listSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.listSearch.BackColor = System.Drawing.Color.White;
|
||||
this.listSearch.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.listSearch.DetectUrls = false;
|
||||
this.listSearch.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
this.listSearch.Location = new System.Drawing.Point(0, 0);
|
||||
this.listSearch.Location = new System.Drawing.Point(3, 3);
|
||||
this.listSearch.Multiline = false;
|
||||
this.listSearch.Name = "listSearch";
|
||||
this.listSearch.Size = new System.Drawing.Size(472, 20);
|
||||
this.listSearch.TabIndex = 0;
|
||||
this.listSearch.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None;
|
||||
this.listSearch.Size = new System.Drawing.Size(331, 16);
|
||||
this.listSearch.TabIndex = 3;
|
||||
this.listSearch.Text = " Filter ";
|
||||
this.listSearch.WordWrap = false;
|
||||
this.listSearch.TextChanged += new System.EventHandler(this.ListSearchTextChanged);
|
||||
this.listSearch.Enter += new System.EventHandler(this.listSearch_Enter);
|
||||
this.listSearch.Leave += new System.EventHandler(this.listSearch_Leave);
|
||||
//
|
||||
// listSearchHistory
|
||||
//
|
||||
this.listSearchHistory.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
|
||||
this.listSearchHistory.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
|
||||
this.listSearchHistory.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.listSearchHistory.Location = new System.Drawing.Point(0, 0);
|
||||
this.listSearchHistory.Name = "listSearchHistory";
|
||||
this.listSearchHistory.Size = new System.Drawing.Size(351, 21);
|
||||
this.listSearchHistory.TabIndex = 2;
|
||||
this.listSearchHistory.TabStop = false;
|
||||
this.listSearchHistory.SelectedIndexChanged += new System.EventHandler(this.listSearchHistory_SelectedIndexChanged);
|
||||
this.listSearchHistory.Enter += new System.EventHandler(this.listSearch_Enter);
|
||||
this.listSearchHistory.Leave += new System.EventHandler(this.listSearch_Leave);
|
||||
//
|
||||
// listSearchFilterMode
|
||||
//
|
||||
this.listSearchFilterMode.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
this.listSearchFilterMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.listSearchFilterMode.DropDownWidth = 150;
|
||||
this.listSearchFilterMode.Items.AddRange(new object[] {
|
||||
"Include",
|
||||
"Exclude",
|
||||
"Regex (Name)",
|
||||
"Regex (Container)"});
|
||||
this.listSearchFilterMode.Location = new System.Drawing.Point(351, 0);
|
||||
this.listSearchFilterMode.Name = "listSearchFilterMode";
|
||||
this.listSearchFilterMode.Size = new System.Drawing.Size(121, 21);
|
||||
this.listSearchFilterMode.TabIndex = 3;
|
||||
this.listSearchFilterMode.SelectedIndexChanged += new System.EventHandler(this.listSearchFilterMode_SelectedIndexChanged);
|
||||
//
|
||||
// tabPage3
|
||||
//
|
||||
this.tabPage3.Controls.Add(this.classesListView);
|
||||
@@ -723,6 +900,7 @@
|
||||
// progressBar1
|
||||
//
|
||||
this.progressBar1.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.progressBar1.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.progressBar1.Location = new System.Drawing.Point(1, 3);
|
||||
this.progressBar1.Name = "progressBar1";
|
||||
this.progressBar1.Size = new System.Drawing.Size(478, 18);
|
||||
@@ -774,6 +952,7 @@
|
||||
this.assetInfoLabel.AutoSize = true;
|
||||
this.assetInfoLabel.BackColor = System.Drawing.Color.Transparent;
|
||||
this.assetInfoLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
this.assetInfoLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.assetInfoLabel.Location = new System.Drawing.Point(4, 8);
|
||||
this.assetInfoLabel.Name = "assetInfoLabel";
|
||||
this.assetInfoLabel.Size = new System.Drawing.Size(0, 13);
|
||||
@@ -801,8 +980,10 @@
|
||||
//
|
||||
// FMODcopyright
|
||||
//
|
||||
this.FMODcopyright.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODcopyright.AutoSize = true;
|
||||
this.FMODcopyright.ForeColor = System.Drawing.SystemColors.ControlLight;
|
||||
this.FMODcopyright.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODcopyright.Location = new System.Drawing.Point(214, 365);
|
||||
this.FMODcopyright.Name = "FMODcopyright";
|
||||
this.FMODcopyright.Size = new System.Drawing.Size(283, 13);
|
||||
@@ -811,35 +992,44 @@
|
||||
//
|
||||
// FMODinfoLabel
|
||||
//
|
||||
this.FMODinfoLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODinfoLabel.AutoSize = true;
|
||||
this.FMODinfoLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
this.FMODinfoLabel.Location = new System.Drawing.Point(269, 255);
|
||||
this.FMODinfoLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODinfoLabel.Location = new System.Drawing.Point(275, 255);
|
||||
this.FMODinfoLabel.Name = "FMODinfoLabel";
|
||||
this.FMODinfoLabel.Size = new System.Drawing.Size(0, 13);
|
||||
this.FMODinfoLabel.TabIndex = 8;
|
||||
//
|
||||
// FMODtimerLabel
|
||||
//
|
||||
this.FMODtimerLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODtimerLabel.AutoSize = true;
|
||||
this.FMODtimerLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
this.FMODtimerLabel.Location = new System.Drawing.Point(404, 255);
|
||||
this.FMODtimerLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODtimerLabel.Location = new System.Drawing.Point(457, 253);
|
||||
this.FMODtimerLabel.Name = "FMODtimerLabel";
|
||||
this.FMODtimerLabel.Size = new System.Drawing.Size(155, 13);
|
||||
this.FMODtimerLabel.Size = new System.Drawing.Size(102, 13);
|
||||
this.FMODtimerLabel.TabIndex = 7;
|
||||
this.FMODtimerLabel.Text = "0:00.0 / 0:00.0";
|
||||
this.FMODtimerLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
this.FMODtimerLabel.Text = "00:00.00 / 00:00.00";
|
||||
//
|
||||
// FMODstatusLabel
|
||||
//
|
||||
this.FMODstatusLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODstatusLabel.AutoSize = true;
|
||||
this.FMODstatusLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
this.FMODstatusLabel.Location = new System.Drawing.Point(213, 255);
|
||||
this.FMODstatusLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODstatusLabel.Location = new System.Drawing.Point(214, 255);
|
||||
this.FMODstatusLabel.Name = "FMODstatusLabel";
|
||||
this.FMODstatusLabel.Size = new System.Drawing.Size(50, 13);
|
||||
this.FMODstatusLabel.Size = new System.Drawing.Size(47, 13);
|
||||
this.FMODstatusLabel.TabIndex = 6;
|
||||
this.FMODstatusLabel.Text = "Stopped";
|
||||
//
|
||||
// FMODprogressBar
|
||||
//
|
||||
this.FMODprogressBar.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODprogressBar.AutoSize = false;
|
||||
this.FMODprogressBar.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODprogressBar.Location = new System.Drawing.Point(213, 274);
|
||||
this.FMODprogressBar.Maximum = 1000;
|
||||
this.FMODprogressBar.Name = "FMODprogressBar";
|
||||
@@ -852,6 +1042,8 @@
|
||||
//
|
||||
// FMODvolumeBar
|
||||
//
|
||||
this.FMODvolumeBar.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODvolumeBar.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODvolumeBar.LargeChange = 2;
|
||||
this.FMODvolumeBar.Location = new System.Drawing.Point(460, 303);
|
||||
this.FMODvolumeBar.Name = "FMODvolumeBar";
|
||||
@@ -863,7 +1055,9 @@
|
||||
//
|
||||
// FMODloopButton
|
||||
//
|
||||
this.FMODloopButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODloopButton.Appearance = System.Windows.Forms.Appearance.Button;
|
||||
this.FMODloopButton.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODloopButton.Location = new System.Drawing.Point(399, 303);
|
||||
this.FMODloopButton.Name = "FMODloopButton";
|
||||
this.FMODloopButton.Size = new System.Drawing.Size(55, 46);
|
||||
@@ -875,6 +1069,8 @@
|
||||
//
|
||||
// FMODstopButton
|
||||
//
|
||||
this.FMODstopButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODstopButton.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODstopButton.Location = new System.Drawing.Point(338, 303);
|
||||
this.FMODstopButton.Name = "FMODstopButton";
|
||||
this.FMODstopButton.Size = new System.Drawing.Size(55, 46);
|
||||
@@ -885,6 +1081,8 @@
|
||||
//
|
||||
// FMODpauseButton
|
||||
//
|
||||
this.FMODpauseButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODpauseButton.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODpauseButton.Location = new System.Drawing.Point(277, 303);
|
||||
this.FMODpauseButton.Name = "FMODpauseButton";
|
||||
this.FMODpauseButton.Size = new System.Drawing.Size(55, 46);
|
||||
@@ -895,6 +1093,8 @@
|
||||
//
|
||||
// FMODplayButton
|
||||
//
|
||||
this.FMODplayButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.FMODplayButton.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.FMODplayButton.Location = new System.Drawing.Point(216, 303);
|
||||
this.FMODplayButton.Name = "FMODplayButton";
|
||||
this.FMODplayButton.Size = new System.Drawing.Size(55, 46);
|
||||
@@ -936,7 +1136,7 @@
|
||||
// textPreviewBox
|
||||
//
|
||||
this.textPreviewBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.textPreviewBox.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.textPreviewBox.Font = new System.Drawing.Font("Consolas", 9.75F);
|
||||
this.textPreviewBox.Location = new System.Drawing.Point(0, 0);
|
||||
this.textPreviewBox.Multiline = true;
|
||||
this.textPreviewBox.Name = "textPreviewBox";
|
||||
@@ -1001,6 +1201,65 @@
|
||||
this.toolStripStatusLabel1.Text = "Ready to go";
|
||||
this.toolStripStatusLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// contextMenuStrip2
|
||||
//
|
||||
this.contextMenuStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.showRelatedAssetsToolStripMenuItem,
|
||||
this.toolStripSeparator7,
|
||||
this.selectAllToolStripMenuItem,
|
||||
this.clearSelectionToolStripMenuItem,
|
||||
this.toolStripSeparator5,
|
||||
this.expandAllToolStripMenuItem,
|
||||
this.collapseAllToolStripMenuItem});
|
||||
this.contextMenuStrip2.Name = "contextMenuStrip2";
|
||||
this.contextMenuStrip2.Size = new System.Drawing.Size(152, 126);
|
||||
this.contextMenuStrip2.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip2_Opening);
|
||||
//
|
||||
// showRelatedAssetsToolStripMenuItem
|
||||
//
|
||||
this.showRelatedAssetsToolStripMenuItem.Name = "showRelatedAssetsToolStripMenuItem";
|
||||
this.showRelatedAssetsToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
|
||||
this.showRelatedAssetsToolStripMenuItem.Text = "Related assets";
|
||||
this.showRelatedAssetsToolStripMenuItem.Click += new System.EventHandler(this.showRelatedAssetsToolStripMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator7
|
||||
//
|
||||
this.toolStripSeparator7.Name = "toolStripSeparator7";
|
||||
this.toolStripSeparator7.Size = new System.Drawing.Size(148, 6);
|
||||
//
|
||||
// selectAllToolStripMenuItem
|
||||
//
|
||||
this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem";
|
||||
this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
|
||||
this.selectAllToolStripMenuItem.Text = "Select all";
|
||||
this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click);
|
||||
//
|
||||
// clearSelectionToolStripMenuItem
|
||||
//
|
||||
this.clearSelectionToolStripMenuItem.Name = "clearSelectionToolStripMenuItem";
|
||||
this.clearSelectionToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
|
||||
this.clearSelectionToolStripMenuItem.Text = "Clear selection";
|
||||
this.clearSelectionToolStripMenuItem.Click += new System.EventHandler(this.clearSelectionToolStripMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator5
|
||||
//
|
||||
this.toolStripSeparator5.Name = "toolStripSeparator5";
|
||||
this.toolStripSeparator5.Size = new System.Drawing.Size(148, 6);
|
||||
//
|
||||
// expandAllToolStripMenuItem
|
||||
//
|
||||
this.expandAllToolStripMenuItem.Name = "expandAllToolStripMenuItem";
|
||||
this.expandAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
|
||||
this.expandAllToolStripMenuItem.Text = "Expand all";
|
||||
this.expandAllToolStripMenuItem.Click += new System.EventHandler(this.expandAllToolStripMenuItem_Click);
|
||||
//
|
||||
// collapseAllToolStripMenuItem
|
||||
//
|
||||
this.collapseAllToolStripMenuItem.Name = "collapseAllToolStripMenuItem";
|
||||
this.collapseAllToolStripMenuItem.Size = new System.Drawing.Size(151, 22);
|
||||
this.collapseAllToolStripMenuItem.Text = "Collapse all";
|
||||
this.collapseAllToolStripMenuItem.Click += new System.EventHandler(this.collapseAllToolStripMenuItem_Click);
|
||||
//
|
||||
// timer
|
||||
//
|
||||
this.timer.Interval = 10;
|
||||
@@ -1024,7 +1283,7 @@
|
||||
this.goToSceneHierarchyToolStripMenuItem,
|
||||
this.showOriginalFileToolStripMenuItem});
|
||||
this.contextMenuStrip1.Name = "contextMenuStrip1";
|
||||
this.contextMenuStrip1.Size = new System.Drawing.Size(304, 158);
|
||||
this.contextMenuStrip1.Size = new System.Drawing.Size(304, 136);
|
||||
//
|
||||
// copyToolStripMenuItem
|
||||
//
|
||||
@@ -1074,8 +1333,6 @@
|
||||
// AssetStudioGUIForm
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1264, 681);
|
||||
this.Controls.Add(this.splitContainer1);
|
||||
this.Controls.Add(this.menuStrip1);
|
||||
@@ -1085,7 +1342,8 @@
|
||||
this.MinimumSize = new System.Drawing.Size(620, 400);
|
||||
this.Name = "AssetStudioGUIForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "AssetStudioGUI";
|
||||
this.Text = "AssetStudioModGUI";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.AssetStudioGUIForm_FormClosing);
|
||||
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.AssetStudioGUIForm_DragDrop);
|
||||
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.AssetStudioGUIForm_DragEnter);
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AssetStudioForm_KeyDown);
|
||||
@@ -1100,7 +1358,7 @@
|
||||
this.tabPage1.ResumeLayout(false);
|
||||
this.tabPage1.PerformLayout();
|
||||
this.tabPage2.ResumeLayout(false);
|
||||
this.tabPage2.PerformLayout();
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.tabPage3.ResumeLayout(false);
|
||||
this.progressbarPanel.ResumeLayout(false);
|
||||
this.tabControl2.ResumeLayout(false);
|
||||
@@ -1115,6 +1373,7 @@
|
||||
this.tabPage5.PerformLayout();
|
||||
this.statusStrip1.ResumeLayout(false);
|
||||
this.statusStrip1.PerformLayout();
|
||||
this.contextMenuStrip2.ResumeLayout(false);
|
||||
this.contextMenuStrip1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
@@ -1130,10 +1389,8 @@
|
||||
private System.Windows.Forms.TabPage tabPage1;
|
||||
private System.Windows.Forms.TabPage tabPage2;
|
||||
private System.Windows.Forms.TextBox treeSearch;
|
||||
private System.Windows.Forms.TextBox listSearch;
|
||||
private System.Windows.Forms.ToolStripMenuItem loadFileToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem loadFolderToolStripMenuItem;
|
||||
private System.Windows.Forms.ListView assetListView;
|
||||
private System.Windows.Forms.ColumnHeader columnHeaderName;
|
||||
private System.Windows.Forms.ColumnHeader columnHeaderSize;
|
||||
private System.Windows.Forms.ColumnHeader columnHeaderType;
|
||||
@@ -1220,6 +1477,30 @@
|
||||
private System.Windows.Forms.ToolStripTextBox specifyUnityVersion;
|
||||
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem15;
|
||||
private System.Windows.Forms.ToolStripMenuItem dumpSelectedAssetsToolStripMenuItem;
|
||||
private System.Windows.Forms.ContextMenuStrip contextMenuStrip2;
|
||||
private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem clearSelectionToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
|
||||
private System.Windows.Forms.ToolStripMenuItem collapseAllToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem expandAllToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.ComboBox listSearchFilterMode;
|
||||
private System.Windows.Forms.ComboBox listSearchHistory;
|
||||
private System.Windows.Forms.RichTextBox listSearch;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
|
||||
private System.Windows.Forms.ToolStripMenuItem allLive2DModelsToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem showRelatedAssetsToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
|
||||
private System.Windows.Forms.ListView assetListView;
|
||||
private System.Windows.Forms.ToolStripMenuItem akFixFaceSpriteNamesToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem akUseExternalAlphaToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator akSeparator1;
|
||||
private System.Windows.Forms.ToolStripMenuItem akTitleMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator akSeparator2;
|
||||
private System.Windows.Forms.ToolStripMenuItem showConsoleToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem writeLogToFileToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem buildTreeStructureToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -141,6 +141,9 @@ The quick brown fox jumps over the lazy dog. 1234567890</value>
|
||||
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>432, 17</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>775, 21</value>
|
||||
</metadata>
|
||||
<metadata name="timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>553, 17</value>
|
||||
</metadata>
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
// This code developed by Dot Net Perls
|
||||
using System.Collections;
|
||||
// AlphanumComparatorFast mod by aelurum
|
||||
// Original code was developed by Dot Net Perls
|
||||
// For more detail visit: https://www.dotnetperls.com/alphanumeric-sorting
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal class AlphanumComparatorFast : IComparer
|
||||
internal class AlphanumComparatorFast : IComparer<string>
|
||||
{
|
||||
public int Compare(object x, object y)
|
||||
public int Compare(string s1, string s2)
|
||||
{
|
||||
if (!(x is string s1))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!(y is string s2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int len1 = s1.Length;
|
||||
int len2 = s2.Length;
|
||||
int marker1 = 0;
|
||||
@@ -69,20 +63,23 @@ namespace AssetStudioGUI
|
||||
|
||||
// If we have collected numbers, compare them numerically.
|
||||
// Otherwise, if we have strings, compare them alphabetically.
|
||||
string str1 = new string(space1);
|
||||
string str2 = new string(space2);
|
||||
|
||||
int result;
|
||||
|
||||
if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
|
||||
{
|
||||
int thisNumericChunk = int.Parse(str1);
|
||||
int thatNumericChunk = int.Parse(str2);
|
||||
if (long.TryParse(new string(space1), out long thisNumericChunk) &&
|
||||
long.TryParse(new string(space2), out long thatNumericChunk))
|
||||
{
|
||||
result = thisNumericChunk.CompareTo(thatNumericChunk);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = str1.CompareTo(str2);
|
||||
result = MemoryExtensions.CompareTo(space1, space2, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = MemoryExtensions.CompareTo(space1, space2, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
|
||||
99
AssetStudioGUI/Components/AlphanumComparatorFastNet.cs
Normal file
99
AssetStudioGUI/Components/AlphanumComparatorFastNet.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
// AlphanumComparatorFast mod by aelurum
|
||||
// Original code was developed by Dot Net Perls
|
||||
// For more detail visit: https://www.dotnetperls.com/alphanumeric-sorting
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal class AlphanumComparatorFastNet : IComparer<string>
|
||||
{
|
||||
public int Compare(string s1, string s2)
|
||||
{
|
||||
const int maxStackSize = 256;
|
||||
int len1 = s1.Length;
|
||||
int len2 = s2.Length;
|
||||
int marker1 = 0;
|
||||
int marker2 = 0;
|
||||
|
||||
// Some buffers we can build up characters in for each chunk.
|
||||
Span<char> space1 = len1 > maxStackSize ? new char[len1] : stackalloc char[len1];
|
||||
Span<char> space2 = len2 > maxStackSize ? new char[len2] : stackalloc char[len2];
|
||||
|
||||
// Walk through two the strings with two markers.
|
||||
while (marker1 < len1 && marker2 < len2)
|
||||
{
|
||||
char ch1 = s1[marker1];
|
||||
char ch2 = s2[marker2];
|
||||
|
||||
int loc1 = 0;
|
||||
int loc2 = 0;
|
||||
space1.Clear();
|
||||
space2.Clear();
|
||||
|
||||
// Walk through all following characters that are digits or
|
||||
// characters in BOTH strings starting at the appropriate marker.
|
||||
// Collect char arrays.
|
||||
do
|
||||
{
|
||||
space1[loc1++] = ch1;
|
||||
marker1++;
|
||||
|
||||
if (marker1 < len1)
|
||||
{
|
||||
ch1 = s1[marker1];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (char.IsDigit(ch1) == char.IsDigit(space1[0]));
|
||||
|
||||
do
|
||||
{
|
||||
space2[loc2++] = ch2;
|
||||
marker2++;
|
||||
|
||||
if (marker2 < len2)
|
||||
{
|
||||
ch2 = s2[marker2];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (char.IsDigit(ch2) == char.IsDigit(space2[0]));
|
||||
|
||||
// If we have collected numbers, compare them numerically.
|
||||
// Otherwise, if we have strings, compare them alphabetically.
|
||||
int result;
|
||||
|
||||
if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
|
||||
{
|
||||
if (long.TryParse(space1, out long thisNumericChunk) &&
|
||||
long.TryParse(space2, out long thatNumericChunk))
|
||||
{
|
||||
result = thisNumericChunk.CompareTo(thatNumericChunk);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = MemoryExtensions.CompareTo(space1, space2, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = MemoryExtensions.CompareTo(space1, space2, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return len1 - len2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
299
AssetStudioGUI/Components/Arknights/AkSpriteHelper.cs
Normal file
299
AssetStudioGUI/Components/Arknights/AkSpriteHelper.cs
Normal file
@@ -0,0 +1,299 @@
|
||||
using Arknights.PortraitSpriteMono;
|
||||
using AssetStudio;
|
||||
using AssetStudioGUI;
|
||||
using AssetStudioGUI.Properties;
|
||||
using Newtonsoft.Json;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.ImageSharp.Processing.Processors.Transforms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Arknights
|
||||
{
|
||||
internal static class AkSpriteHelper
|
||||
{
|
||||
public static Texture2D TryFindAlphaTex(AssetItem assetItem, AvgSprite avgSprite, bool isAvgSprite)
|
||||
{
|
||||
Sprite m_Sprite = (Sprite)assetItem.Asset;
|
||||
var imgType = "arts/characters";
|
||||
if (m_Sprite.m_RD.alphaTexture.m_PathID == 0)
|
||||
{
|
||||
if (isAvgSprite)
|
||||
{
|
||||
if (avgSprite?.FullAlphaTexture != null)
|
||||
return avgSprite.FullAlphaTexture;
|
||||
|
||||
imgType = "avg/characters"; //since the avg hub was not found for some reason, let's try to find alpha tex by name
|
||||
}
|
||||
var spriteFullName = Path.GetFileNameWithoutExtension(assetItem.Container);
|
||||
foreach (var item in Studio.exportableAssets)
|
||||
{
|
||||
if (item.Type == ClassIDType.Texture2D)
|
||||
{
|
||||
if (item.Container.Contains(imgType) && item.Container.Contains($"illust_{m_Sprite.m_Name}_material") && item.Text.Contains("[alpha]"))
|
||||
return (Texture2D)item.Asset;
|
||||
if (item.Container.Contains(imgType) && item.Container.Contains(spriteFullName) && item.Text == $"{m_Sprite.m_Name}[alpha]")
|
||||
return (Texture2D)item.Asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Image<Bgra32> AkGetImage(this Sprite m_Sprite, AvgSprite avgSprite = null, SpriteMaskMode spriteMaskMode = SpriteMaskMode.On)
|
||||
{
|
||||
if (m_Sprite.m_RD.texture.TryGet(out var m_Texture2D) && m_Sprite.m_RD.alphaTexture.TryGet(out var m_AlphaTexture2D) && spriteMaskMode != SpriteMaskMode.Off)
|
||||
{
|
||||
Image<Bgra32> tex = null;
|
||||
Image<Bgra32> alphaTex = null;
|
||||
|
||||
if (avgSprite != null && avgSprite.IsHubParsed)
|
||||
{
|
||||
alphaTex = m_AlphaTexture2D.ConvertToImage(true);
|
||||
if (avgSprite.IsFaceSprite)
|
||||
{
|
||||
var faceImage = m_Texture2D.ConvertToImage(true);
|
||||
var faceAlpha = avgSprite.FaceSpriteAlphaTexture.ConvertToImage(true);
|
||||
|
||||
tex = avgSprite.FullTexture.ConvertToImage(true);
|
||||
var facePos = tex.Width == 512 ? avgSprite.FacePos / 2 : avgSprite.FacePos; // ?
|
||||
var faceSize = tex.Width == 512 ? avgSprite.FaceSize / 2 : avgSprite.FaceSize;
|
||||
|
||||
if (new Size(faceImage.Width, faceImage.Height) != avgSprite.FaceSize)
|
||||
{
|
||||
faceImage.Mutate(x => x.Resize(new ResizeOptions { Size = faceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||
faceAlpha.Mutate(x => x.Resize(new ResizeOptions { Size = faceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||
}
|
||||
|
||||
tex.Mutate(x => x.DrawImage(faceImage, facePos, opacity: 1f));
|
||||
alphaTex.Mutate(x => x.DrawImage(faceAlpha, facePos, opacity: 1f));
|
||||
}
|
||||
else
|
||||
{
|
||||
tex = m_Texture2D.ConvertToImage(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spriteMaskMode != SpriteMaskMode.MaskOnly)
|
||||
{
|
||||
tex = CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||
}
|
||||
alphaTex = CutImage(m_AlphaTexture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||
}
|
||||
|
||||
return ImageRender(tex, alphaTex, spriteMaskMode);
|
||||
}
|
||||
else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D) && avgSprite != null && avgSprite.IsHubParsed)
|
||||
{
|
||||
if (!avgSprite.IsFaceSprite)
|
||||
{
|
||||
return m_Texture2D.ConvertToImage(true);
|
||||
}
|
||||
|
||||
var faceImage = m_Texture2D.ConvertToImage(true);
|
||||
var tex = avgSprite.FullTexture.ConvertToImage(true);
|
||||
if (new Size(faceImage.Width, faceImage.Height) != avgSprite.FaceSize)
|
||||
{
|
||||
faceImage.Mutate(x => x.Resize(new ResizeOptions {Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch}));
|
||||
}
|
||||
tex.Mutate(x => x.DrawImage(faceImage, avgSprite.FacePos, opacity: 1f));
|
||||
|
||||
return tex;
|
||||
}
|
||||
else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D))
|
||||
{
|
||||
return CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Image<Bgra32> AkGetImage(this PortraitSprite portraitSprite, SpriteMaskMode spriteMaskMode = SpriteMaskMode.On)
|
||||
{
|
||||
if (portraitSprite.Texture != null && portraitSprite.AlphaTexture != null)
|
||||
{
|
||||
Image<Bgra32> tex = null;
|
||||
Image<Bgra32> alphaTex = null;
|
||||
|
||||
if (spriteMaskMode != SpriteMaskMode.MaskOnly)
|
||||
{
|
||||
tex = CutImage(portraitSprite.Texture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||
}
|
||||
if (spriteMaskMode != SpriteMaskMode.Off)
|
||||
{
|
||||
alphaTex = CutImage(portraitSprite.AlphaTexture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||
}
|
||||
|
||||
return ImageRender(tex, alphaTex, spriteMaskMode);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<PortraitSprite> GeneratePortraits(AssetItem asset)
|
||||
{
|
||||
var portraits = new List<PortraitSprite>();
|
||||
|
||||
var portraitsDict = ((MonoBehaviour)asset.Asset).ToType();
|
||||
if (portraitsDict == null)
|
||||
{
|
||||
Logger.Warning("Portraits MonoBehaviour is not readable.");
|
||||
return portraits;
|
||||
}
|
||||
var portraitsJson = JsonConvert.SerializeObject(portraitsDict);
|
||||
var portraitsData = JsonConvert.DeserializeObject<PortraitSpriteConfig>(portraitsJson);
|
||||
|
||||
if (portraitsData._sprites.Length == 0)
|
||||
return portraits;
|
||||
|
||||
var atlasTex = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == portraitsData._atlas.Texture.m_PathID).Asset;
|
||||
var atlasAlpha = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == portraitsData._atlas.Alpha.m_PathID).Asset;
|
||||
|
||||
foreach (var portraitData in portraitsData._sprites)
|
||||
{
|
||||
var portraitSprite = new PortraitSprite()
|
||||
{
|
||||
Name = portraitData.Name,
|
||||
AssetsFile = atlasTex.assetsFile,
|
||||
Container = asset.Container,
|
||||
Texture = atlasTex,
|
||||
AlphaTexture = atlasAlpha,
|
||||
TextureRect = new Rectf(portraitData.Rect.X, portraitData.Rect.Y, portraitData.Rect.W, portraitData.Rect.H),
|
||||
Rotate = portraitData.Rotate,
|
||||
};
|
||||
portraits.Add(portraitSprite);
|
||||
}
|
||||
|
||||
return portraits;
|
||||
}
|
||||
|
||||
private static Image<Bgra32> ImageRender(Image<Bgra32> tex, Image<Bgra32> alpha, SpriteMaskMode maskMode)
|
||||
{
|
||||
switch (maskMode)
|
||||
{
|
||||
case SpriteMaskMode.On:
|
||||
tex.ApplyRGBMask(alpha, isPreview: true);
|
||||
return tex;
|
||||
case SpriteMaskMode.Off:
|
||||
alpha?.Dispose();
|
||||
return tex;
|
||||
case SpriteMaskMode.MaskOnly:
|
||||
tex?.Dispose();
|
||||
return alpha;
|
||||
case SpriteMaskMode.Export:
|
||||
tex.ApplyRGBMask(alpha);
|
||||
return tex;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IResampler GetResampler(bool isPreview)
|
||||
{
|
||||
IResampler resampler;
|
||||
if (isPreview)
|
||||
{
|
||||
resampler = KnownResamplers.NearestNeighbor;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Settings.Default.resamplerIndex)
|
||||
{
|
||||
case 0:
|
||||
resampler = KnownResamplers.NearestNeighbor;
|
||||
break;
|
||||
case 1: //Bilinear
|
||||
resampler = KnownResamplers.Triangle;
|
||||
break;
|
||||
case 2:
|
||||
resampler = KnownResamplers.Bicubic;
|
||||
break;
|
||||
case 3:
|
||||
resampler = KnownResamplers.MitchellNetravali;
|
||||
break;
|
||||
case 4:
|
||||
resampler = KnownResamplers.Spline;
|
||||
break;
|
||||
case 5:
|
||||
resampler = KnownResamplers.Welch;
|
||||
break;
|
||||
default:
|
||||
resampler = KnownResamplers.MitchellNetravali;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return resampler;
|
||||
}
|
||||
|
||||
private static void ApplyRGBMask(this Image<Bgra32> tex, Image<Bgra32> texMask, bool isPreview = false)
|
||||
{
|
||||
using (texMask)
|
||||
{
|
||||
bool resized = false;
|
||||
if (tex.Width != texMask.Width || tex.Height != texMask.Height)
|
||||
{
|
||||
texMask.Mutate(x => x.Resize(tex.Width, tex.Height, GetResampler(isPreview)));
|
||||
resized = true;
|
||||
}
|
||||
|
||||
var invGamma = 1.0 / (1.0 + Settings.Default.alphaMaskGamma / 10.0);
|
||||
if (Settings.Default.resizedOnly && !resized)
|
||||
{
|
||||
invGamma = 1.0;
|
||||
}
|
||||
|
||||
tex.ProcessPixelRows(texMask, (sourceTex, targetTexMask) =>
|
||||
{
|
||||
for (int y = 0; y < texMask.Height; y++)
|
||||
{
|
||||
var texRow = sourceTex.GetRowSpan(y);
|
||||
var maskRow = targetTexMask.GetRowSpan(y);
|
||||
for (int x = 0; x < maskRow.Length; x++)
|
||||
{
|
||||
var grayscale = (maskRow[x].R + maskRow[x].G + maskRow[x].B) / 3.0;
|
||||
if (invGamma != 1)
|
||||
{
|
||||
grayscale = 255 - Math.Pow((255 - grayscale) / 255, invGamma) * 255;
|
||||
}
|
||||
texRow[x].A = (byte)grayscale;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static Image<Bgra32> CutImage(Image<Bgra32> originalImage, Rectf textureRect, float downscaleMultiplier, bool rotate = false)
|
||||
{
|
||||
if (originalImage != null)
|
||||
{
|
||||
if (downscaleMultiplier > 0f && downscaleMultiplier != 1f)
|
||||
{
|
||||
var newSize = (Size)(new Size(originalImage.Width, originalImage.Height) / downscaleMultiplier);
|
||||
originalImage.Mutate(x => x.Resize(newSize, KnownResamplers.Lanczos3, compand: true));
|
||||
}
|
||||
var rectX = (int)Math.Floor(textureRect.x);
|
||||
var rectY = (int)Math.Floor(textureRect.y);
|
||||
var rectRight = (int)Math.Ceiling(textureRect.x + textureRect.width);
|
||||
var rectBottom = (int)Math.Ceiling(textureRect.y + textureRect.height);
|
||||
rectRight = Math.Min(rectRight, originalImage.Width);
|
||||
rectBottom = Math.Min(rectBottom, originalImage.Height);
|
||||
var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY);
|
||||
var spriteImage = originalImage.Clone(x => x.Crop(rect));
|
||||
originalImage.Dispose();
|
||||
if (rotate)
|
||||
{
|
||||
spriteImage.Mutate(x => x.Rotate(RotateMode.Rotate270));
|
||||
}
|
||||
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
|
||||
|
||||
return spriteImage;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
149
AssetStudioGUI/Components/Arknights/AvgSprite.cs
Normal file
149
AssetStudioGUI/Components/Arknights/AvgSprite.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using Arknights.AvgCharHubMono;
|
||||
using AssetStudio;
|
||||
using AssetStudioGUI;
|
||||
using SixLabors.ImageSharp;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Arknights
|
||||
{
|
||||
internal class AvgSprite
|
||||
{
|
||||
public Texture2D FaceSpriteAlphaTexture { get; }
|
||||
public Texture2D FullTexture { get; }
|
||||
public Texture2D FullAlphaTexture { get; }
|
||||
public Point FacePos { get; }
|
||||
public Size FaceSize { get; }
|
||||
public string Alias { get; }
|
||||
public bool IsWholeBodySprite { get; }
|
||||
public bool IsFaceSprite { get; }
|
||||
public bool IsHubParsed { get; }
|
||||
|
||||
private AvgSpriteConfig GetCurSpriteGroup(AvgSpriteConfigGroup spriteHubDataGrouped, long spriteItemID, string spriteName)
|
||||
{
|
||||
if (spriteHubDataGrouped.SpriteGroups.Length > 1)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(spriteName))
|
||||
{
|
||||
var groupFromName = int.TryParse(spriteName?.Substring(spriteName.IndexOf('$') + 1, 1), out int groupIndex);
|
||||
if (groupFromName)
|
||||
{
|
||||
return spriteHubDataGrouped.SpriteGroups[groupIndex - 1];
|
||||
}
|
||||
}
|
||||
return spriteHubDataGrouped.SpriteGroups.FirstOrDefault(x => x.Sprites.Any(y => y.Sprite.m_PathID == spriteItemID));
|
||||
}
|
||||
else
|
||||
{
|
||||
return spriteHubDataGrouped.SpriteGroups[0];
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryGetSpriteHub(AssetItem assetItem, out AvgSpriteConfig spriteHubData)
|
||||
{
|
||||
spriteHubData = null;
|
||||
var scriptAssets = Studio.exportableAssets.FindAll(x =>
|
||||
x.Type == ClassIDType.MonoBehaviour
|
||||
&& x.Container == assetItem.Container);
|
||||
if (scriptAssets.Count == 0)
|
||||
{
|
||||
Logger.Warning("No MonoBehaviours were found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
OrderedDictionary spriteHubDict = null;
|
||||
var isGrouped = false;
|
||||
foreach (var scriptAsset in scriptAssets)
|
||||
{
|
||||
var scriptAssetDict = ((MonoBehaviour)scriptAsset.Asset).ToType();
|
||||
if (scriptAssetDict == null)
|
||||
{
|
||||
Logger.Warning("MonoBehaviour is not readable.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scriptAssetDict.Contains("spriteGroups"))
|
||||
{
|
||||
spriteHubDict = scriptAssetDict;
|
||||
isGrouped = true;
|
||||
break;
|
||||
}
|
||||
if (scriptAssetDict.Contains("sprites"))
|
||||
{
|
||||
spriteHubDict = scriptAssetDict;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spriteHubDict == null)
|
||||
{
|
||||
Logger.Warning("AVGCharacterSpriteHub is not readable.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var spriteHubJson = JsonConvert.SerializeObject(spriteHubDict);
|
||||
if (isGrouped)
|
||||
{
|
||||
var groupedSpriteHub = JsonConvert.DeserializeObject<AvgSpriteConfigGroup>(spriteHubJson);
|
||||
spriteHubData = GetCurSpriteGroup(groupedSpriteHub, assetItem.m_PathID, assetItem.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteHubData = JsonConvert.DeserializeObject<AvgSpriteConfig>(spriteHubJson);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public AvgSprite(AssetItem assetItem)
|
||||
{
|
||||
if (TryGetSpriteHub(assetItem, out var spriteHubData))
|
||||
{
|
||||
IsHubParsed = spriteHubData?.Sprites.Length > 0;
|
||||
}
|
||||
if (IsHubParsed)
|
||||
{
|
||||
var curSpriteData = spriteHubData.Sprites.FirstOrDefault(x => x.Sprite.m_PathID == assetItem.m_PathID);
|
||||
|
||||
if (curSpriteData == null)
|
||||
{
|
||||
Studio.StatusStripUpdate($"Sprite \"{assetItem.Text}\" was not found in the avg sprite hub.");
|
||||
return;
|
||||
}
|
||||
|
||||
Alias = curSpriteData.Alias;
|
||||
IsWholeBodySprite = curSpriteData.IsWholeBody;
|
||||
|
||||
if (spriteHubData.FaceSize.X > 0 && spriteHubData.FaceSize.Y > 0) //If face data exist
|
||||
{
|
||||
var fullTexSpriteData = spriteHubData.Sprites.Last(); //Last sprite item in the list usually contains PathID of Sprite with full texture
|
||||
|
||||
var curSprite = (Sprite)assetItem.Asset;
|
||||
IsFaceSprite = curSprite.m_Rect.width <= 256 && curSprite.m_Rect.height <= 256 && curSprite.m_PathID != fullTexSpriteData.Sprite.m_PathID;
|
||||
|
||||
var curSpriteAlphaID = curSpriteData.AlphaTex.m_PathID;
|
||||
var curSpriteAlphaTex = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == curSpriteAlphaID)?.Asset;
|
||||
if (curSpriteAlphaTex != null)
|
||||
{
|
||||
FaceSpriteAlphaTexture = IsFaceSprite ? curSpriteAlphaTex : null;
|
||||
fullTexSpriteData = IsFaceSprite ? fullTexSpriteData : curSpriteData;
|
||||
}
|
||||
var fullTexSpriteID = fullTexSpriteData.Sprite.m_PathID;
|
||||
var fullTexAlphaID = fullTexSpriteData.AlphaTex.m_PathID;
|
||||
var fullTexSprite = (Sprite)Studio.exportableAssets.Find(x => x.m_PathID == fullTexSpriteID).Asset;
|
||||
|
||||
FullTexture = fullTexSprite.m_RD.texture.TryGet(out var fullTex) ? fullTex : null;
|
||||
FullAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == fullTexAlphaID)?.Asset;
|
||||
FacePos = new Point((int)Math.Round(spriteHubData.FacePos.X), (int)Math.Round(spriteHubData.FacePos.Y));
|
||||
FaceSize = new Size((int)Math.Round(spriteHubData.FaceSize.X), (int)Math.Round(spriteHubData.FaceSize.Y));
|
||||
}
|
||||
else
|
||||
{
|
||||
FullAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == curSpriteData.AlphaTex.m_PathID)?.Asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
AssetStudioGUI/Components/Arknights/AvgSpriteConfig.cs
Normal file
30
AssetStudioGUI/Components/Arknights/AvgSpriteConfig.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using AssetStudio;
|
||||
|
||||
namespace Arknights.AvgCharHubMono
|
||||
{
|
||||
internal class AvgAssetIDs
|
||||
{
|
||||
public int m_FileID { get; set; }
|
||||
public long m_PathID { get; set; }
|
||||
}
|
||||
|
||||
internal class AvgSpriteData
|
||||
{
|
||||
public AvgAssetIDs Sprite { get; set; }
|
||||
public AvgAssetIDs AlphaTex { get; set; }
|
||||
public string Alias { get; set; }
|
||||
public bool IsWholeBody { get; set; }
|
||||
}
|
||||
|
||||
internal class AvgSpriteConfig
|
||||
{
|
||||
public AvgSpriteData[] Sprites { get; set; }
|
||||
public Vector2 FaceSize { get; set; }
|
||||
public Vector3 FacePos { get; set; }
|
||||
}
|
||||
|
||||
internal class AvgSpriteConfigGroup
|
||||
{
|
||||
public AvgSpriteConfig[] SpriteGroups { get; set; }
|
||||
}
|
||||
}
|
||||
24
AssetStudioGUI/Components/Arknights/PortraitSprite.cs
Normal file
24
AssetStudioGUI/Components/Arknights/PortraitSprite.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using AssetStudio;
|
||||
|
||||
|
||||
namespace Arknights
|
||||
{
|
||||
internal class PortraitSprite
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public ClassIDType Type { get; }
|
||||
public SerializedFile AssetsFile { get; set; }
|
||||
public string Container { get; set; }
|
||||
public Texture2D Texture { get; set; }
|
||||
public Texture2D AlphaTexture { get; set; }
|
||||
public Rectf TextureRect { get; set; }
|
||||
public bool Rotate { get; set; }
|
||||
public float DownscaleMultiplier { get; }
|
||||
|
||||
public PortraitSprite()
|
||||
{
|
||||
Type = ClassIDType.AkPortraitSprite;
|
||||
DownscaleMultiplier = 1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
AssetStudioGUI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
41
AssetStudioGUI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
namespace Arknights.PortraitSpriteMono
|
||||
{
|
||||
internal class PortraitRect
|
||||
{
|
||||
public float X { get; set; }
|
||||
public float Y { get; set; }
|
||||
public float W { get; set; }
|
||||
public float H { get; set; }
|
||||
}
|
||||
|
||||
internal class AtlasSprite
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Guid { get; set; }
|
||||
public int Atlas { get; set; }
|
||||
public PortraitRect Rect { get; set; }
|
||||
public bool Rotate { get; set; }
|
||||
}
|
||||
|
||||
internal class TextureIDs
|
||||
{
|
||||
public int m_FileID { get; set; }
|
||||
public long m_PathID { get; set; }
|
||||
}
|
||||
|
||||
internal class AtlasInfo
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public TextureIDs Texture { get; set; }
|
||||
public TextureIDs Alpha { get; set; }
|
||||
public int Size { get; set; }
|
||||
}
|
||||
|
||||
internal class PortraitSpriteConfig
|
||||
{
|
||||
public string m_Name { get; set; }
|
||||
public AtlasSprite[] _sprites { get; set; }
|
||||
public AtlasInfo _atlas { get; set; }
|
||||
public int _index { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Windows.Forms;
|
||||
using AssetStudio;
|
||||
using Arknights;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
@@ -15,6 +16,7 @@ namespace AssetStudioGUI
|
||||
public string InfoText;
|
||||
public string UniqueID;
|
||||
public GameObjectTreeNode TreeNode;
|
||||
public PortraitSprite AkPortraitSprite;
|
||||
|
||||
public AssetItem(Object asset)
|
||||
{
|
||||
@@ -26,6 +28,19 @@ namespace AssetStudioGUI
|
||||
FullSize = asset.byteSize;
|
||||
}
|
||||
|
||||
public AssetItem(PortraitSprite akPortraitSprite)
|
||||
{
|
||||
Asset = null;
|
||||
SourceFile = akPortraitSprite.AssetsFile;
|
||||
Container = akPortraitSprite.Container;
|
||||
Type = akPortraitSprite.Type;
|
||||
TypeString = Type.ToString();
|
||||
Text = akPortraitSprite.Name;
|
||||
m_PathID = -1;
|
||||
FullSize = (long)(akPortraitSprite.TextureRect.width * akPortraitSprite.TextureRect.height * 4);
|
||||
AkPortraitSprite = akPortraitSprite;
|
||||
}
|
||||
|
||||
public void SetSubItems()
|
||||
{
|
||||
SubItems.AddRange(new[]
|
||||
|
||||
67
AssetStudioGUI/Components/ConsoleWindow.cs
Normal file
67
AssetStudioGUI/Components/ConsoleWindow.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using AssetStudio;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal static class ConsoleWindow
|
||||
{
|
||||
private enum CtrlSignalType
|
||||
{
|
||||
CTRL_C_EVENT,
|
||||
CTRL_BREAK_EVENT,
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool AllocConsole();
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr GetConsoleWindow();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
|
||||
|
||||
private delegate bool EventHandler(CtrlSignalType ctrlSignal);
|
||||
private static EventHandler eventHandler;
|
||||
private static IntPtr ConsoleWindowHandle;
|
||||
private static readonly int SW_HIDE = 0;
|
||||
private static readonly int SW_SHOW = 5;
|
||||
|
||||
private static bool CloseEventHandler(CtrlSignalType ctrlSignal)
|
||||
{
|
||||
switch (ctrlSignal)
|
||||
{
|
||||
case CtrlSignalType.CTRL_C_EVENT:
|
||||
case CtrlSignalType.CTRL_BREAK_EVENT:
|
||||
return true;
|
||||
default:
|
||||
Logger.Verbose("Closing AssetStudio");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RunConsole(bool showConsole)
|
||||
{
|
||||
AllocConsole();
|
||||
ConsoleWindowHandle = GetConsoleWindow();
|
||||
eventHandler += CloseEventHandler;
|
||||
SetConsoleCtrlHandler(eventHandler, true);
|
||||
|
||||
if (!showConsole)
|
||||
HideConsoleWindow();
|
||||
}
|
||||
|
||||
public static void ShowConsoleWindow()
|
||||
{
|
||||
ShowWindow(ConsoleWindowHandle, SW_SHOW);
|
||||
}
|
||||
|
||||
public static void HideConsoleWindow()
|
||||
{
|
||||
ShowWindow(ConsoleWindowHandle, SW_HIDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,6 @@ namespace AssetStudioGUI
|
||||
{
|
||||
public GameObject gameObject;
|
||||
|
||||
public GameObjectTreeNode(string name)
|
||||
{
|
||||
Text = name;
|
||||
}
|
||||
|
||||
public GameObjectTreeNode(GameObject gameObject)
|
||||
{
|
||||
this.gameObject = gameObject;
|
||||
|
||||
164
AssetStudioGUI/Components/LnkReader.cs
Normal file
164
AssetStudioGUI/Components/LnkReader.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
// Shortcut (.lnk) file reader
|
||||
// by aelurum
|
||||
// Based on https://github.com/libyal/liblnk/blob/main/documentation/Windows%20Shortcut%20File%20(LNK)%20format.asciidoc
|
||||
|
||||
using AssetStudio;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
public static class LnkReader
|
||||
{
|
||||
[Flags]
|
||||
private enum LnkDataFlags
|
||||
{
|
||||
//The LNK file contains a link target identifier
|
||||
HasTargetIDList = 0x00000001,
|
||||
//The LNK file contains location information
|
||||
HasLinkInfo = 0x00000002,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum LnkLocFlags
|
||||
{
|
||||
//The linked file is on a volume
|
||||
//If set the volume information and the local path contain data
|
||||
VolumeIDAndLocalBasePath = 0x0001,
|
||||
//The linked file is on a network share
|
||||
//If set the network share information and common path contain data
|
||||
CommonNetworkRelativeLinkAndPathSuffix = 0x0002
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum PathTypeFlags
|
||||
{
|
||||
IsUnicodeLocalPath = 0x01,
|
||||
IsUnicodeNetShareName = 0x02,
|
||||
IsUnicodeCommonPath = 0x04
|
||||
}
|
||||
|
||||
public static string GetLnkTarget(string filePath)
|
||||
{
|
||||
var targetPath = string.Empty;
|
||||
var pathType = (PathTypeFlags)0;
|
||||
Encoding sysEncoding;
|
||||
try
|
||||
{
|
||||
sysEncoding = GetSysEncoding();
|
||||
Logger.Debug($"System default text encoding: {sysEncoding.CodePage}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Text encoding error", ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var reader = new FileReader(filePath))
|
||||
{
|
||||
reader.Endian = EndianType.LittleEndian;
|
||||
|
||||
var headerSize = reader.ReadUInt32(); //76 bytes
|
||||
reader.Position = 20; //skip LNK class identifier (GUID)
|
||||
var dataFlags = (LnkDataFlags)reader.ReadUInt32();
|
||||
if ((dataFlags & LnkDataFlags.HasLinkInfo) == 0)
|
||||
{
|
||||
Logger.Warning("Unsupported type of .lnk file. Link info was not found.");
|
||||
return null;
|
||||
}
|
||||
reader.Position = headerSize;
|
||||
|
||||
//Skip the shell item ID list
|
||||
if ((dataFlags & LnkDataFlags.HasTargetIDList) != 0)
|
||||
{
|
||||
var itemIDListSize = reader.ReadUInt16();
|
||||
reader.Position += itemIDListSize;
|
||||
}
|
||||
|
||||
//The offsets is relative to the start of the location information block
|
||||
var locInfoPos = reader.Position;
|
||||
var locInfoFullSize = reader.ReadUInt32();
|
||||
if (locInfoFullSize == 0)
|
||||
{
|
||||
Logger.Warning("Unsupported type of .lnk file. Link info was not found.");
|
||||
return null;
|
||||
}
|
||||
var locInfoHeaderSize = reader.ReadUInt32();
|
||||
var locFlags = (LnkLocFlags)reader.ReadUInt32();
|
||||
//Offset to the volume information block
|
||||
var offsetVolumeInfo = reader.ReadUInt32();
|
||||
//Offset to the ANSI local path
|
||||
var offsetLocalPath = reader.ReadUInt32();
|
||||
//Offset to the network share information block
|
||||
var offsetNetInfo = reader.ReadUInt32();
|
||||
//Offset to the ANSI common path. 0 if not available
|
||||
var offsetCommonPath = reader.ReadUInt32();
|
||||
if (locInfoHeaderSize > 28)
|
||||
{
|
||||
//Offset to the Unicode local path
|
||||
offsetLocalPath = reader.ReadUInt32();
|
||||
pathType |= PathTypeFlags.IsUnicodeLocalPath;
|
||||
}
|
||||
if (locInfoHeaderSize > 32)
|
||||
{
|
||||
//Offset to the Unicode common path
|
||||
offsetCommonPath = reader.ReadUInt32();
|
||||
pathType |= PathTypeFlags.IsUnicodeCommonPath;
|
||||
}
|
||||
|
||||
//Read local path, if exist
|
||||
if (offsetLocalPath > 0)
|
||||
{
|
||||
reader.Position = locInfoPos + offsetLocalPath;
|
||||
targetPath = (pathType & PathTypeFlags.IsUnicodeLocalPath) != 0
|
||||
? reader.ReadStringToNull(encoding: Encoding.Unicode)
|
||||
: reader.ReadStringToNull(encoding: sysEncoding);
|
||||
}
|
||||
|
||||
//Read network path, if exist
|
||||
if (locFlags == LnkLocFlags.CommonNetworkRelativeLinkAndPathSuffix)
|
||||
{
|
||||
reader.Position = locInfoPos + offsetNetInfo;
|
||||
var netInfoSize = reader.ReadUInt32();
|
||||
var netInfoFlags = reader.ReadUInt32();
|
||||
//Offset to the ANSI network share name. The offset is relative to the start of the network share information block
|
||||
var offsetNetShareName = reader.ReadUInt32();
|
||||
if (offsetNetShareName > 20)
|
||||
{
|
||||
reader.Position = locInfoPos + offsetNetInfo + 20;
|
||||
//Offset to the Unicode network share name
|
||||
offsetNetShareName = reader.ReadUInt32();
|
||||
pathType |= PathTypeFlags.IsUnicodeNetShareName;
|
||||
}
|
||||
if (offsetNetShareName > 0)
|
||||
{
|
||||
reader.Position = locInfoPos + offsetNetInfo + offsetNetShareName;
|
||||
targetPath = (pathType & PathTypeFlags.IsUnicodeNetShareName) != 0
|
||||
? reader.ReadStringToNull(encoding: Encoding.Unicode)
|
||||
: reader.ReadStringToNull(encoding: sysEncoding);
|
||||
}
|
||||
}
|
||||
|
||||
//Read common path, if exist
|
||||
if (offsetCommonPath > 0)
|
||||
{
|
||||
reader.Position = locInfoPos + offsetCommonPath;
|
||||
var commonPath = (pathType & PathTypeFlags.IsUnicodeCommonPath) != 0
|
||||
? reader.ReadStringToNull(encoding: Encoding.Unicode)
|
||||
: reader.ReadStringToNull(encoding: sysEncoding);
|
||||
targetPath = Path.Combine(targetPath, commonPath);
|
||||
}
|
||||
}
|
||||
return targetPath;
|
||||
}
|
||||
|
||||
private static Encoding GetSysEncoding()
|
||||
{
|
||||
#if !NETFRAMEWORK
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
#endif
|
||||
return Encoding.GetEncoding(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
@@ -15,12 +14,13 @@ namespace AssetStudioGUI
|
||||
|
||||
internal DialogResult ShowDialog(IWin32Window owner = null)
|
||||
{
|
||||
//#if NETFRAMEWORK
|
||||
if (Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
return ShowVistaDialog(owner);
|
||||
}
|
||||
|
||||
return ShowLegacyDialog(owner);
|
||||
//#endif
|
||||
return ShowFolderBrowserDialog(owner);
|
||||
}
|
||||
|
||||
private DialogResult ShowVistaDialog(IWin32Window owner)
|
||||
@@ -74,7 +74,7 @@ namespace AssetStudioGUI
|
||||
return DialogResult.Cancel;
|
||||
}
|
||||
|
||||
private DialogResult ShowLegacyDialog(IWin32Window owner)
|
||||
private DialogResult ShowFolderBrowserDialog(IWin32Window owner)
|
||||
{
|
||||
using (var frm = new FolderBrowserDialog())
|
||||
{
|
||||
@@ -82,13 +82,20 @@ namespace AssetStudioGUI
|
||||
{
|
||||
frm.SelectedPath = InitialFolder;
|
||||
}
|
||||
if ((owner == null ? frm.ShowDialog() : frm.ShowDialog(owner)) == DialogResult.OK)
|
||||
#if !NETFRAMEWORK
|
||||
if (Title != null)
|
||||
{
|
||||
Folder = Path.GetDirectoryName(frm.SelectedPath);
|
||||
return DialogResult.OK;
|
||||
frm.Description = Title;
|
||||
frm.UseDescriptionForTitle = true;
|
||||
}
|
||||
|
||||
return DialogResult.Cancel;
|
||||
#endif
|
||||
var result = owner == null ? frm.ShowDialog() : frm.ShowDialog(owner);
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
Folder = frm.SelectedPath;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal static class TreeViewExtensions
|
||||
{
|
||||
private const int TVIF_STATE = 0x8;
|
||||
private const int TVIS_STATEIMAGEMASK = 0xF000;
|
||||
private const int TV_FIRST = 0x1100;
|
||||
private const int TVM_SETITEM = TV_FIRST + 63;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)]
|
||||
private struct TVITEM
|
||||
{
|
||||
public int mask;
|
||||
public IntPtr hItem;
|
||||
public int state;
|
||||
public int stateMask;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
public string lpszText;
|
||||
public int cchTextMax;
|
||||
public int iImage;
|
||||
public int iSelectedImage;
|
||||
public int cChildren;
|
||||
public IntPtr lParam;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref TVITEM lParam);
|
||||
|
||||
/// <summary>
|
||||
/// Hides the checkbox for the specified node on a TreeView control.
|
||||
/// </summary>
|
||||
public static void HideCheckBox(this TreeNode node)
|
||||
{
|
||||
var tvi = new TVITEM
|
||||
{
|
||||
hItem = node.Handle,
|
||||
mask = TVIF_STATE,
|
||||
stateMask = TVIS_STATEIMAGEMASK,
|
||||
state = TVIS_STATEIMAGEMASK //temp bugfix for an issue with getting stuck during the "Building tree structure" step
|
||||
};
|
||||
SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
AssetStudioGUI/DirectBitmap.cs
Normal file
48
AssetStudioGUI/DirectBitmap.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using AssetStudio;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
public sealed class DirectBitmap : IDisposable
|
||||
{
|
||||
public DirectBitmap(Image<Bgra32> image)
|
||||
{
|
||||
Width = image.Width;
|
||||
Height = image.Height;
|
||||
Bits = BigArrayPool<byte>.Shared.Rent(Width * Height * 4);
|
||||
image.CopyPixelDataTo(Bits);
|
||||
m_handle = GCHandle.Alloc(Bits, GCHandleType.Pinned);
|
||||
m_bitmap = new Bitmap(Width, Height, Stride, PixelFormat.Format32bppArgb, m_handle.AddrOfPinnedObject());
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
m_bitmap.Dispose();
|
||||
m_handle.Free();
|
||||
BigArrayPool<byte>.Shared.Return(Bits);
|
||||
}
|
||||
m_bitmap = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
public int Height { get; }
|
||||
public int Width { get; }
|
||||
public int Stride => Width * 4;
|
||||
public byte[] Bits { get; }
|
||||
public Bitmap Bitmap => m_bitmap;
|
||||
|
||||
private Bitmap m_bitmap;
|
||||
private readonly GCHandle m_handle;
|
||||
}
|
||||
}
|
||||
356
AssetStudioGUI/ExportOptions.Designer.cs
generated
356
AssetStudioGUI/ExportOptions.Designer.cs
generated
@@ -32,17 +32,25 @@
|
||||
this.OKbutton = new System.Windows.Forms.Button();
|
||||
this.Cancel = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.exportSpriteWithAlphaMask = new System.Windows.Forms.CheckBox();
|
||||
this.openAfterExport = new System.Windows.Forms.CheckBox();
|
||||
this.restoreExtensionName = new System.Windows.Forms.CheckBox();
|
||||
this.assetGroupOptions = new System.Windows.Forms.ComboBox();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.convertAudio = new System.Windows.Forms.CheckBox();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.towebp = new System.Windows.Forms.RadioButton();
|
||||
this.totga = new System.Windows.Forms.RadioButton();
|
||||
this.tojpg = new System.Windows.Forms.RadioButton();
|
||||
this.topng = new System.Windows.Forms.RadioButton();
|
||||
this.tobmp = new System.Windows.Forms.RadioButton();
|
||||
this.converttexture = new System.Windows.Forms.CheckBox();
|
||||
this.l2dGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.l2dMotionExportMethodPanel = new System.Windows.Forms.Panel();
|
||||
this.l2dMonoBehaviourRadioButton = new System.Windows.Forms.RadioButton();
|
||||
this.l2dAnimationClipRadioButton = new System.Windows.Forms.RadioButton();
|
||||
this.l2dMotionExportMethodLabel = new System.Windows.Forms.Label();
|
||||
this.l2dForceBezierCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.exportAllUvsAsDiffuseMaps = new System.Windows.Forms.CheckBox();
|
||||
this.exportBlendShape = new System.Windows.Forms.CheckBox();
|
||||
@@ -61,18 +69,34 @@
|
||||
this.castToBone = new System.Windows.Forms.CheckBox();
|
||||
this.exportAllNodes = new System.Windows.Forms.CheckBox();
|
||||
this.eulerFilter = new System.Windows.Forms.CheckBox();
|
||||
this.exportUvsTooltip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.akResamplerLabel = new System.Windows.Forms.Label();
|
||||
this.akResamplerComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.akSpritesAlphaGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.akGammaNoteLabel = new System.Windows.Forms.Label();
|
||||
this.akResamplerDescLabel = new System.Windows.Forms.Label();
|
||||
this.akResizedOnlyCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.akGammaValueLabel = new System.Windows.Forms.Label();
|
||||
this.akGammaLabel = new System.Windows.Forms.Label();
|
||||
this.akAlphaMaskGammaTrackBar = new System.Windows.Forms.TrackBar();
|
||||
this.akSpritesExportGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.akAddAliasesCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.optionTooltip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.l2dGroupBox.SuspendLayout();
|
||||
this.l2dMotionExportMethodPanel.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.scaleFactor)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.boneSize)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.filterPrecision)).BeginInit();
|
||||
this.akSpritesAlphaGroupBox.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.akAlphaMaskGammaTrackBar)).BeginInit();
|
||||
this.akSpritesExportGroupBox.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// OKbutton
|
||||
//
|
||||
this.OKbutton.Location = new System.Drawing.Point(318, 380);
|
||||
this.OKbutton.Location = new System.Drawing.Point(681, 381);
|
||||
this.OKbutton.Name = "OKbutton";
|
||||
this.OKbutton.Size = new System.Drawing.Size(75, 23);
|
||||
this.OKbutton.TabIndex = 6;
|
||||
@@ -83,7 +107,7 @@
|
||||
// Cancel
|
||||
//
|
||||
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.Cancel.Location = new System.Drawing.Point(399, 380);
|
||||
this.Cancel.Location = new System.Drawing.Point(762, 381);
|
||||
this.Cancel.Name = "Cancel";
|
||||
this.Cancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.Cancel.TabIndex = 7;
|
||||
@@ -94,6 +118,7 @@
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.AutoSize = true;
|
||||
this.groupBox1.Controls.Add(this.exportSpriteWithAlphaMask);
|
||||
this.groupBox1.Controls.Add(this.openAfterExport);
|
||||
this.groupBox1.Controls.Add(this.restoreExtensionName);
|
||||
this.groupBox1.Controls.Add(this.assetGroupOptions);
|
||||
@@ -103,20 +128,32 @@
|
||||
this.groupBox1.Controls.Add(this.converttexture);
|
||||
this.groupBox1.Location = new System.Drawing.Point(12, 13);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(232, 362);
|
||||
this.groupBox1.TabIndex = 9;
|
||||
this.groupBox1.Size = new System.Drawing.Size(301, 272);
|
||||
this.groupBox1.TabIndex = 1;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Export";
|
||||
//
|
||||
// exportSpriteWithAlphaMask
|
||||
//
|
||||
this.exportSpriteWithAlphaMask.AutoSize = true;
|
||||
this.exportSpriteWithAlphaMask.Checked = true;
|
||||
this.exportSpriteWithAlphaMask.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportSpriteWithAlphaMask.Location = new System.Drawing.Point(6, 150);
|
||||
this.exportSpriteWithAlphaMask.Name = "exportSpriteWithAlphaMask";
|
||||
this.exportSpriteWithAlphaMask.Size = new System.Drawing.Size(205, 17);
|
||||
this.exportSpriteWithAlphaMask.TabIndex = 6;
|
||||
this.exportSpriteWithAlphaMask.Text = "Export sprites with alpha mask applied";
|
||||
this.exportSpriteWithAlphaMask.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// openAfterExport
|
||||
//
|
||||
this.openAfterExport.AutoSize = true;
|
||||
this.openAfterExport.Checked = true;
|
||||
this.openAfterExport.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.openAfterExport.Location = new System.Drawing.Point(6, 173);
|
||||
this.openAfterExport.Location = new System.Drawing.Point(6, 196);
|
||||
this.openAfterExport.Name = "openAfterExport";
|
||||
this.openAfterExport.Size = new System.Drawing.Size(137, 17);
|
||||
this.openAfterExport.TabIndex = 10;
|
||||
this.openAfterExport.TabIndex = 8;
|
||||
this.openAfterExport.Text = "Open folder after export";
|
||||
this.openAfterExport.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -127,9 +164,10 @@
|
||||
this.restoreExtensionName.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.restoreExtensionName.Location = new System.Drawing.Point(6, 63);
|
||||
this.restoreExtensionName.Name = "restoreExtensionName";
|
||||
this.restoreExtensionName.Size = new System.Drawing.Size(190, 17);
|
||||
this.restoreExtensionName.TabIndex = 9;
|
||||
this.restoreExtensionName.Text = "Restore TextAsset extension name";
|
||||
this.restoreExtensionName.Size = new System.Drawing.Size(275, 17);
|
||||
this.restoreExtensionName.TabIndex = 3;
|
||||
this.restoreExtensionName.Text = "Try to restore/Use original TextAsset extension name";
|
||||
this.optionTooltip.SetToolTip(this.restoreExtensionName, "If not checked, AssetStudio will export all TextAssets with the \".txt\" extension");
|
||||
this.restoreExtensionName.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// assetGroupOptions
|
||||
@@ -139,12 +177,13 @@
|
||||
this.assetGroupOptions.Items.AddRange(new object[] {
|
||||
"type name",
|
||||
"container path",
|
||||
"container path full (with name)",
|
||||
"source file name",
|
||||
"do not group"});
|
||||
this.assetGroupOptions.Location = new System.Drawing.Point(6, 35);
|
||||
this.assetGroupOptions.Name = "assetGroupOptions";
|
||||
this.assetGroupOptions.Size = new System.Drawing.Size(149, 21);
|
||||
this.assetGroupOptions.TabIndex = 8;
|
||||
this.assetGroupOptions.Size = new System.Drawing.Size(165, 21);
|
||||
this.assetGroupOptions.TabIndex = 2;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
@@ -152,7 +191,7 @@
|
||||
this.label6.Location = new System.Drawing.Point(6, 18);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(127, 13);
|
||||
this.label6.TabIndex = 7;
|
||||
this.label6.TabIndex = 1;
|
||||
this.label6.Text = "Group exported assets by";
|
||||
//
|
||||
// convertAudio
|
||||
@@ -160,31 +199,42 @@
|
||||
this.convertAudio.AutoSize = true;
|
||||
this.convertAudio.Checked = true;
|
||||
this.convertAudio.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.convertAudio.Location = new System.Drawing.Point(6, 150);
|
||||
this.convertAudio.Location = new System.Drawing.Point(6, 173);
|
||||
this.convertAudio.Name = "convertAudio";
|
||||
this.convertAudio.Size = new System.Drawing.Size(179, 17);
|
||||
this.convertAudio.TabIndex = 6;
|
||||
this.convertAudio.TabIndex = 7;
|
||||
this.convertAudio.Text = "Convert AudioClip to WAV(PCM)";
|
||||
this.convertAudio.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.towebp);
|
||||
this.panel1.Controls.Add(this.totga);
|
||||
this.panel1.Controls.Add(this.tojpg);
|
||||
this.panel1.Controls.Add(this.topng);
|
||||
this.panel1.Controls.Add(this.tobmp);
|
||||
this.panel1.Location = new System.Drawing.Point(20, 111);
|
||||
this.panel1.Location = new System.Drawing.Point(18, 111);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(202, 33);
|
||||
this.panel1.Size = new System.Drawing.Size(260, 33);
|
||||
this.panel1.TabIndex = 5;
|
||||
//
|
||||
// towebp
|
||||
//
|
||||
this.towebp.AutoSize = true;
|
||||
this.towebp.Location = new System.Drawing.Point(201, 7);
|
||||
this.towebp.Name = "towebp";
|
||||
this.towebp.Size = new System.Drawing.Size(54, 17);
|
||||
this.towebp.TabIndex = 4;
|
||||
this.towebp.Text = "Webp";
|
||||
this.towebp.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// totga
|
||||
//
|
||||
this.totga.AutoSize = true;
|
||||
this.totga.Location = new System.Drawing.Point(150, 7);
|
||||
this.totga.Name = "totga";
|
||||
this.totga.Size = new System.Drawing.Size(44, 17);
|
||||
this.totga.TabIndex = 2;
|
||||
this.totga.TabIndex = 3;
|
||||
this.totga.Text = "Tga";
|
||||
this.totga.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -194,7 +244,7 @@
|
||||
this.tojpg.Location = new System.Drawing.Point(97, 7);
|
||||
this.tojpg.Name = "tojpg";
|
||||
this.tojpg.Size = new System.Drawing.Size(48, 17);
|
||||
this.tojpg.TabIndex = 4;
|
||||
this.tojpg.TabIndex = 2;
|
||||
this.tojpg.Text = "Jpeg";
|
||||
this.tojpg.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -205,7 +255,7 @@
|
||||
this.topng.Location = new System.Drawing.Point(50, 7);
|
||||
this.topng.Name = "topng";
|
||||
this.topng.Size = new System.Drawing.Size(44, 17);
|
||||
this.topng.TabIndex = 3;
|
||||
this.topng.TabIndex = 1;
|
||||
this.topng.TabStop = true;
|
||||
this.topng.Text = "Png";
|
||||
this.topng.UseVisualStyleBackColor = true;
|
||||
@@ -216,7 +266,7 @@
|
||||
this.tobmp.Location = new System.Drawing.Point(3, 7);
|
||||
this.tobmp.Name = "tobmp";
|
||||
this.tobmp.Size = new System.Drawing.Size(46, 17);
|
||||
this.tobmp.TabIndex = 2;
|
||||
this.tobmp.TabIndex = 0;
|
||||
this.tobmp.Text = "Bmp";
|
||||
this.tobmp.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -228,10 +278,76 @@
|
||||
this.converttexture.Location = new System.Drawing.Point(6, 87);
|
||||
this.converttexture.Name = "converttexture";
|
||||
this.converttexture.Size = new System.Drawing.Size(116, 17);
|
||||
this.converttexture.TabIndex = 1;
|
||||
this.converttexture.TabIndex = 4;
|
||||
this.converttexture.Text = "Convert Texture2D";
|
||||
this.converttexture.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// l2dGroupBox
|
||||
//
|
||||
this.l2dGroupBox.Controls.Add(this.l2dMotionExportMethodPanel);
|
||||
this.l2dGroupBox.Controls.Add(this.l2dMotionExportMethodLabel);
|
||||
this.l2dGroupBox.Controls.Add(this.l2dForceBezierCheckBox);
|
||||
this.l2dGroupBox.Location = new System.Drawing.Point(12, 275);
|
||||
this.l2dGroupBox.Name = "l2dGroupBox";
|
||||
this.l2dGroupBox.Size = new System.Drawing.Size(301, 100);
|
||||
this.l2dGroupBox.TabIndex = 2;
|
||||
this.l2dGroupBox.TabStop = false;
|
||||
this.l2dGroupBox.Text = "Cubism Live2D";
|
||||
//
|
||||
// l2dMotionExportMethodPanel
|
||||
//
|
||||
this.l2dMotionExportMethodPanel.Controls.Add(this.l2dMonoBehaviourRadioButton);
|
||||
this.l2dMotionExportMethodPanel.Controls.Add(this.l2dAnimationClipRadioButton);
|
||||
this.l2dMotionExportMethodPanel.Location = new System.Drawing.Point(18, 40);
|
||||
this.l2dMotionExportMethodPanel.Name = "l2dMotionExportMethodPanel";
|
||||
this.l2dMotionExportMethodPanel.Size = new System.Drawing.Size(263, 27);
|
||||
this.l2dMotionExportMethodPanel.TabIndex = 2;
|
||||
//
|
||||
// l2dMonoBehaviourRadioButton
|
||||
//
|
||||
this.l2dMonoBehaviourRadioButton.AccessibleName = "MonoBehaviour";
|
||||
this.l2dMonoBehaviourRadioButton.AutoSize = true;
|
||||
this.l2dMonoBehaviourRadioButton.Checked = true;
|
||||
this.l2dMonoBehaviourRadioButton.Location = new System.Drawing.Point(3, 5);
|
||||
this.l2dMonoBehaviourRadioButton.Name = "l2dMonoBehaviourRadioButton";
|
||||
this.l2dMonoBehaviourRadioButton.Size = new System.Drawing.Size(167, 17);
|
||||
this.l2dMonoBehaviourRadioButton.TabIndex = 0;
|
||||
this.l2dMonoBehaviourRadioButton.TabStop = true;
|
||||
this.l2dMonoBehaviourRadioButton.Text = "MonoBehaviour (Fade motion)";
|
||||
this.optionTooltip.SetToolTip(this.l2dMonoBehaviourRadioButton, "If no Fade motions are found, the AnimationClip method will be used");
|
||||
this.l2dMonoBehaviourRadioButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// l2dAnimationClipRadioButton
|
||||
//
|
||||
this.l2dAnimationClipRadioButton.AccessibleName = "AnimationClip";
|
||||
this.l2dAnimationClipRadioButton.AutoSize = true;
|
||||
this.l2dAnimationClipRadioButton.Location = new System.Drawing.Point(172, 5);
|
||||
this.l2dAnimationClipRadioButton.Name = "l2dAnimationClipRadioButton";
|
||||
this.l2dAnimationClipRadioButton.Size = new System.Drawing.Size(88, 17);
|
||||
this.l2dAnimationClipRadioButton.TabIndex = 1;
|
||||
this.l2dAnimationClipRadioButton.Text = "AnimationClip";
|
||||
this.l2dAnimationClipRadioButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// l2dMotionExportMethodLabel
|
||||
//
|
||||
this.l2dMotionExportMethodLabel.AutoSize = true;
|
||||
this.l2dMotionExportMethodLabel.Location = new System.Drawing.Point(6, 21);
|
||||
this.l2dMotionExportMethodLabel.Name = "l2dMotionExportMethodLabel";
|
||||
this.l2dMotionExportMethodLabel.Size = new System.Drawing.Size(109, 13);
|
||||
this.l2dMotionExportMethodLabel.TabIndex = 1;
|
||||
this.l2dMotionExportMethodLabel.Text = "Motion export method";
|
||||
//
|
||||
// l2dForceBezierCheckBox
|
||||
//
|
||||
this.l2dForceBezierCheckBox.AutoSize = true;
|
||||
this.l2dForceBezierCheckBox.Location = new System.Drawing.Point(6, 77);
|
||||
this.l2dForceBezierCheckBox.Name = "l2dForceBezierCheckBox";
|
||||
this.l2dForceBezierCheckBox.Size = new System.Drawing.Size(278, 17);
|
||||
this.l2dForceBezierCheckBox.TabIndex = 3;
|
||||
this.l2dForceBezierCheckBox.Text = "Calculate Linear motion segments as Bezier segments";
|
||||
this.optionTooltip.SetToolTip(this.l2dForceBezierCheckBox, "May help if the exported motions look jerky/not smooth enough");
|
||||
this.l2dForceBezierCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.AutoSize = true;
|
||||
@@ -252,10 +368,10 @@
|
||||
this.groupBox2.Controls.Add(this.castToBone);
|
||||
this.groupBox2.Controls.Add(this.exportAllNodes);
|
||||
this.groupBox2.Controls.Add(this.eulerFilter);
|
||||
this.groupBox2.Location = new System.Drawing.Point(250, 13);
|
||||
this.groupBox2.Location = new System.Drawing.Point(313, 13);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(224, 362);
|
||||
this.groupBox2.TabIndex = 11;
|
||||
this.groupBox2.TabIndex = 3;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Fbx";
|
||||
//
|
||||
@@ -266,9 +382,9 @@
|
||||
this.exportAllUvsAsDiffuseMaps.Location = new System.Drawing.Point(6, 185);
|
||||
this.exportAllUvsAsDiffuseMaps.Name = "exportAllUvsAsDiffuseMaps";
|
||||
this.exportAllUvsAsDiffuseMaps.Size = new System.Drawing.Size(168, 17);
|
||||
this.exportAllUvsAsDiffuseMaps.TabIndex = 23;
|
||||
this.exportAllUvsAsDiffuseMaps.TabIndex = 9;
|
||||
this.exportAllUvsAsDiffuseMaps.Text = "Export all UVs as diffuse maps";
|
||||
this.exportUvsTooltip.SetToolTip(this.exportAllUvsAsDiffuseMaps, "Unchecked: UV1 exported as normal map. Check this if your export is missing a UV " +
|
||||
this.optionTooltip.SetToolTip(this.exportAllUvsAsDiffuseMaps, "Unchecked: UV1 exported as normal map. Check this if your export is missing a UV " +
|
||||
"map.");
|
||||
this.exportAllUvsAsDiffuseMaps.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -280,7 +396,7 @@
|
||||
this.exportBlendShape.Location = new System.Drawing.Point(6, 138);
|
||||
this.exportBlendShape.Name = "exportBlendShape";
|
||||
this.exportBlendShape.Size = new System.Drawing.Size(114, 17);
|
||||
this.exportBlendShape.TabIndex = 22;
|
||||
this.exportBlendShape.TabIndex = 7;
|
||||
this.exportBlendShape.Text = "Export blendshape";
|
||||
this.exportBlendShape.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -292,7 +408,7 @@
|
||||
this.exportAnimations.Location = new System.Drawing.Point(6, 114);
|
||||
this.exportAnimations.Name = "exportAnimations";
|
||||
this.exportAnimations.Size = new System.Drawing.Size(109, 17);
|
||||
this.exportAnimations.TabIndex = 21;
|
||||
this.exportAnimations.TabIndex = 6;
|
||||
this.exportAnimations.Text = "Export animations";
|
||||
this.exportAnimations.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -307,7 +423,7 @@
|
||||
this.scaleFactor.Location = new System.Drawing.Point(83, 243);
|
||||
this.scaleFactor.Name = "scaleFactor";
|
||||
this.scaleFactor.Size = new System.Drawing.Size(60, 20);
|
||||
this.scaleFactor.TabIndex = 20;
|
||||
this.scaleFactor.TabIndex = 13;
|
||||
this.scaleFactor.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.scaleFactor.Value = new decimal(new int[] {
|
||||
1,
|
||||
@@ -321,7 +437,7 @@
|
||||
this.label5.Location = new System.Drawing.Point(6, 245);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(64, 13);
|
||||
this.label5.TabIndex = 19;
|
||||
this.label5.TabIndex = 12;
|
||||
this.label5.Text = "ScaleFactor";
|
||||
//
|
||||
// fbxFormat
|
||||
@@ -334,7 +450,7 @@
|
||||
this.fbxFormat.Location = new System.Drawing.Point(77, 275);
|
||||
this.fbxFormat.Name = "fbxFormat";
|
||||
this.fbxFormat.Size = new System.Drawing.Size(61, 21);
|
||||
this.fbxFormat.TabIndex = 18;
|
||||
this.fbxFormat.TabIndex = 15;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
@@ -342,7 +458,7 @@
|
||||
this.label4.Location = new System.Drawing.Point(6, 280);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(59, 13);
|
||||
this.label4.TabIndex = 17;
|
||||
this.label4.TabIndex = 14;
|
||||
this.label4.Text = "FBXFormat";
|
||||
//
|
||||
// fbxVersion
|
||||
@@ -359,7 +475,7 @@
|
||||
this.fbxVersion.Location = new System.Drawing.Point(77, 308);
|
||||
this.fbxVersion.Name = "fbxVersion";
|
||||
this.fbxVersion.Size = new System.Drawing.Size(47, 21);
|
||||
this.fbxVersion.TabIndex = 16;
|
||||
this.fbxVersion.TabIndex = 17;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
@@ -367,7 +483,7 @@
|
||||
this.label3.Location = new System.Drawing.Point(6, 311);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(62, 13);
|
||||
this.label3.TabIndex = 15;
|
||||
this.label3.TabIndex = 16;
|
||||
this.label3.Text = "FBXVersion";
|
||||
//
|
||||
// boneSize
|
||||
@@ -399,7 +515,7 @@
|
||||
this.exportSkins.Location = new System.Drawing.Point(6, 90);
|
||||
this.exportSkins.Name = "exportSkins";
|
||||
this.exportSkins.Size = new System.Drawing.Size(83, 17);
|
||||
this.exportSkins.TabIndex = 8;
|
||||
this.exportSkins.TabIndex = 5;
|
||||
this.exportSkins.Text = "Export skins";
|
||||
this.exportSkins.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -409,7 +525,7 @@
|
||||
this.label1.Location = new System.Drawing.Point(26, 42);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(72, 13);
|
||||
this.label1.TabIndex = 7;
|
||||
this.label1.TabIndex = 2;
|
||||
this.label1.Text = "FilterPrecision";
|
||||
//
|
||||
// filterPrecision
|
||||
@@ -423,7 +539,7 @@
|
||||
this.filterPrecision.Location = new System.Drawing.Point(127, 40);
|
||||
this.filterPrecision.Name = "filterPrecision";
|
||||
this.filterPrecision.Size = new System.Drawing.Size(51, 20);
|
||||
this.filterPrecision.TabIndex = 6;
|
||||
this.filterPrecision.TabIndex = 3;
|
||||
this.filterPrecision.Value = new decimal(new int[] {
|
||||
25,
|
||||
0,
|
||||
@@ -436,7 +552,7 @@
|
||||
this.castToBone.Location = new System.Drawing.Point(6, 161);
|
||||
this.castToBone.Name = "castToBone";
|
||||
this.castToBone.Size = new System.Drawing.Size(131, 17);
|
||||
this.castToBone.TabIndex = 5;
|
||||
this.castToBone.TabIndex = 8;
|
||||
this.castToBone.Text = "All nodes cast to bone";
|
||||
this.castToBone.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -460,17 +576,145 @@
|
||||
this.eulerFilter.Location = new System.Drawing.Point(6, 22);
|
||||
this.eulerFilter.Name = "eulerFilter";
|
||||
this.eulerFilter.Size = new System.Drawing.Size(72, 17);
|
||||
this.eulerFilter.TabIndex = 3;
|
||||
this.eulerFilter.TabIndex = 1;
|
||||
this.eulerFilter.Text = "EulerFilter";
|
||||
this.eulerFilter.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// akResamplerLabel
|
||||
//
|
||||
this.akResamplerLabel.AutoSize = true;
|
||||
this.akResamplerLabel.Location = new System.Drawing.Point(6, 21);
|
||||
this.akResamplerLabel.Name = "akResamplerLabel";
|
||||
this.akResamplerLabel.Size = new System.Drawing.Size(120, 13);
|
||||
this.akResamplerLabel.TabIndex = 1;
|
||||
this.akResamplerLabel.Text = "Alpha texture resampler:";
|
||||
this.optionTooltip.SetToolTip(this.akResamplerLabel, "Only affects exported images");
|
||||
//
|
||||
// akResamplerComboBox
|
||||
//
|
||||
this.akResamplerComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.akResamplerComboBox.FormattingEnabled = true;
|
||||
this.akResamplerComboBox.Items.AddRange(new object[] {
|
||||
"Nearest Neighbor",
|
||||
"Bilinear",
|
||||
"Bicubic",
|
||||
"Mitchell-Netravali",
|
||||
"Spline",
|
||||
"Welch"});
|
||||
this.akResamplerComboBox.Location = new System.Drawing.Point(132, 18);
|
||||
this.akResamplerComboBox.Name = "akResamplerComboBox";
|
||||
this.akResamplerComboBox.Size = new System.Drawing.Size(162, 21);
|
||||
this.akResamplerComboBox.TabIndex = 2;
|
||||
this.optionTooltip.SetToolTip(this.akResamplerComboBox, "Only affects exported images");
|
||||
//
|
||||
// akSpritesAlphaGroupBox
|
||||
//
|
||||
this.akSpritesAlphaGroupBox.Controls.Add(this.akGammaNoteLabel);
|
||||
this.akSpritesAlphaGroupBox.Controls.Add(this.akResamplerDescLabel);
|
||||
this.akSpritesAlphaGroupBox.Controls.Add(this.akResamplerLabel);
|
||||
this.akSpritesAlphaGroupBox.Controls.Add(this.akResamplerComboBox);
|
||||
this.akSpritesAlphaGroupBox.Controls.Add(this.akResizedOnlyCheckBox);
|
||||
this.akSpritesAlphaGroupBox.Controls.Add(this.akGammaValueLabel);
|
||||
this.akSpritesAlphaGroupBox.Controls.Add(this.akGammaLabel);
|
||||
this.akSpritesAlphaGroupBox.Controls.Add(this.akAlphaMaskGammaTrackBar);
|
||||
this.akSpritesAlphaGroupBox.Location = new System.Drawing.Point(537, 13);
|
||||
this.akSpritesAlphaGroupBox.Name = "akSpritesAlphaGroupBox";
|
||||
this.akSpritesAlphaGroupBox.Size = new System.Drawing.Size(300, 178);
|
||||
this.akSpritesAlphaGroupBox.TabIndex = 4;
|
||||
this.akSpritesAlphaGroupBox.TabStop = false;
|
||||
this.akSpritesAlphaGroupBox.Text = "Sprites: Alpha Texture [Arknights]";
|
||||
//
|
||||
// akGammaNoteLabel
|
||||
//
|
||||
this.akGammaNoteLabel.AutoSize = true;
|
||||
this.akGammaNoteLabel.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
this.akGammaNoteLabel.Location = new System.Drawing.Point(6, 138);
|
||||
this.akGammaNoteLabel.Name = "akGammaNoteLabel";
|
||||
this.akGammaNoteLabel.Size = new System.Drawing.Size(230, 13);
|
||||
this.akGammaNoteLabel.TabIndex = 8;
|
||||
this.akGammaNoteLabel.Text = "* Gamma settings also affect the preview image";
|
||||
//
|
||||
// akResamplerDescLabel
|
||||
//
|
||||
this.akResamplerDescLabel.AutoSize = true;
|
||||
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(251, 13);
|
||||
this.akResamplerDescLabel.TabIndex = 3;
|
||||
this.akResamplerDescLabel.Text = "Alpha texture upscale method for 2048x2048 sprites";
|
||||
//
|
||||
// akResizedOnlyCheckBox
|
||||
//
|
||||
this.akResizedOnlyCheckBox.AutoSize = true;
|
||||
this.akResizedOnlyCheckBox.Checked = true;
|
||||
this.akResizedOnlyCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.akResizedOnlyCheckBox.Location = new System.Drawing.Point(172, 85);
|
||||
this.akResizedOnlyCheckBox.Name = "akResizedOnlyCheckBox";
|
||||
this.akResizedOnlyCheckBox.Size = new System.Drawing.Size(122, 17);
|
||||
this.akResizedOnlyCheckBox.TabIndex = 6;
|
||||
this.akResizedOnlyCheckBox.Text = "Apply to resized only";
|
||||
this.akResizedOnlyCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// akGammaValueLabel
|
||||
//
|
||||
this.akGammaValueLabel.AutoSize = true;
|
||||
this.akGammaValueLabel.Location = new System.Drawing.Point(111, 86);
|
||||
this.akGammaValueLabel.Name = "akGammaValueLabel";
|
||||
this.akGammaValueLabel.Size = new System.Drawing.Size(41, 13);
|
||||
this.akGammaValueLabel.TabIndex = 5;
|
||||
this.akGammaValueLabel.Text = "Default";
|
||||
//
|
||||
// akGammaLabel
|
||||
//
|
||||
this.akGammaLabel.AutoSize = true;
|
||||
this.akGammaLabel.Location = new System.Drawing.Point(6, 86);
|
||||
this.akGammaLabel.Name = "akGammaLabel";
|
||||
this.akGammaLabel.Size = new System.Drawing.Size(86, 13);
|
||||
this.akGammaLabel.TabIndex = 4;
|
||||
this.akGammaLabel.Text = "Shadow gamma:";
|
||||
//
|
||||
// akAlphaMaskGammaTrackBar
|
||||
//
|
||||
this.akAlphaMaskGammaTrackBar.LargeChange = 2;
|
||||
this.akAlphaMaskGammaTrackBar.Location = new System.Drawing.Point(6, 102);
|
||||
this.akAlphaMaskGammaTrackBar.Maximum = 5;
|
||||
this.akAlphaMaskGammaTrackBar.Minimum = -5;
|
||||
this.akAlphaMaskGammaTrackBar.Name = "akAlphaMaskGammaTrackBar";
|
||||
this.akAlphaMaskGammaTrackBar.Size = new System.Drawing.Size(288, 45);
|
||||
this.akAlphaMaskGammaTrackBar.TabIndex = 7;
|
||||
this.akAlphaMaskGammaTrackBar.Scroll += new System.EventHandler(this.akAlphaMaskGammaTrackBar_Scroll);
|
||||
//
|
||||
// akSpritesExportGroupBox
|
||||
//
|
||||
this.akSpritesExportGroupBox.Controls.Add(this.akAddAliasesCheckBox);
|
||||
this.akSpritesExportGroupBox.Location = new System.Drawing.Point(537, 197);
|
||||
this.akSpritesExportGroupBox.Name = "akSpritesExportGroupBox";
|
||||
this.akSpritesExportGroupBox.Size = new System.Drawing.Size(300, 178);
|
||||
this.akSpritesExportGroupBox.TabIndex = 5;
|
||||
this.akSpritesExportGroupBox.TabStop = false;
|
||||
this.akSpritesExportGroupBox.Text = "Sprites: Export [Arknights]";
|
||||
//
|
||||
// akAddAliasesCheckBox
|
||||
//
|
||||
this.akAddAliasesCheckBox.AutoSize = true;
|
||||
this.akAddAliasesCheckBox.Location = new System.Drawing.Point(6, 28);
|
||||
this.akAddAliasesCheckBox.Name = "akAddAliasesCheckBox";
|
||||
this.akAddAliasesCheckBox.Size = new System.Drawing.Size(261, 17);
|
||||
this.akAddAliasesCheckBox.TabIndex = 1;
|
||||
this.akAddAliasesCheckBox.Text = "Add aliases to avg character sprite names (if exist)";
|
||||
this.akAddAliasesCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ExportOptions
|
||||
//
|
||||
this.AcceptButton = this.OKbutton;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.Cancel;
|
||||
this.ClientSize = new System.Drawing.Size(486, 416);
|
||||
this.ClientSize = new System.Drawing.Size(849, 416);
|
||||
this.Controls.Add(this.l2dGroupBox);
|
||||
this.Controls.Add(this.akSpritesExportGroupBox);
|
||||
this.Controls.Add(this.akSpritesAlphaGroupBox);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.Cancel);
|
||||
@@ -480,18 +724,27 @@
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "ExportOptions";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Export options";
|
||||
this.TopMost = true;
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.l2dGroupBox.ResumeLayout(false);
|
||||
this.l2dGroupBox.PerformLayout();
|
||||
this.l2dMotionExportMethodPanel.ResumeLayout(false);
|
||||
this.l2dMotionExportMethodPanel.PerformLayout();
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.scaleFactor)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.boneSize)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.filterPrecision)).EndInit();
|
||||
this.akSpritesAlphaGroupBox.ResumeLayout(false);
|
||||
this.akSpritesAlphaGroupBox.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.akAlphaMaskGammaTrackBar)).EndInit();
|
||||
this.akSpritesExportGroupBox.ResumeLayout(false);
|
||||
this.akSpritesExportGroupBox.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@@ -530,6 +783,25 @@
|
||||
private System.Windows.Forms.CheckBox restoreExtensionName;
|
||||
private System.Windows.Forms.CheckBox openAfterExport;
|
||||
private System.Windows.Forms.CheckBox exportAllUvsAsDiffuseMaps;
|
||||
private System.Windows.Forms.ToolTip exportUvsTooltip;
|
||||
private System.Windows.Forms.ToolTip optionTooltip;
|
||||
private System.Windows.Forms.CheckBox exportSpriteWithAlphaMask;
|
||||
private System.Windows.Forms.RadioButton towebp;
|
||||
private System.Windows.Forms.GroupBox akSpritesAlphaGroupBox;
|
||||
private System.Windows.Forms.TrackBar akAlphaMaskGammaTrackBar;
|
||||
private System.Windows.Forms.Label akResamplerDescLabel;
|
||||
private System.Windows.Forms.Label akResamplerLabel;
|
||||
private System.Windows.Forms.ComboBox akResamplerComboBox;
|
||||
private System.Windows.Forms.CheckBox akResizedOnlyCheckBox;
|
||||
private System.Windows.Forms.Label akGammaValueLabel;
|
||||
private System.Windows.Forms.Label akGammaLabel;
|
||||
private System.Windows.Forms.GroupBox akSpritesExportGroupBox;
|
||||
private System.Windows.Forms.CheckBox akAddAliasesCheckBox;
|
||||
private System.Windows.Forms.Label akGammaNoteLabel;
|
||||
private System.Windows.Forms.GroupBox l2dGroupBox;
|
||||
private System.Windows.Forms.CheckBox l2dForceBezierCheckBox;
|
||||
private System.Windows.Forms.Label l2dMotionExportMethodLabel;
|
||||
private System.Windows.Forms.RadioButton l2dAnimationClipRadioButton;
|
||||
private System.Windows.Forms.RadioButton l2dMonoBehaviourRadioButton;
|
||||
private System.Windows.Forms.Panel l2dMotionExportMethodPanel;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user