Compare commits

...

31 Commits

Author SHA1 Message Date
Perfare 2ce9cae957 Modify the prompt statement 2021-11-20 03:11:02 +08:00
Perfare af5e50cfa9 Update README.md 2021-11-20 02:52:53 +08:00
Perfare ce1172ca9a rename. closed #817 2021-11-19 18:24:18 +08:00
Perfare a7e6d91f5b Fixed bug 2021-11-19 18:22:39 +08:00
Perfare 34a0af683a Fixed bug 2021-11-19 18:11:00 +08:00
Perfare 91410a33b1 Improve the handling of compressed files. 2021-11-19 17:54:06 +08:00
Perfare d08b78c2cf support 2021.2 2021-11-12 10:25:22 +08:00
Perfare 2ef52afe1e Fixed #835 2021-11-12 09:30:12 +08:00
Perfare 05a41d2f1e Merge pull request #855 from nikitalita/fix-assembly-loading
Fix AssemblyLoading bug
2021-11-08 09:36:03 +08:00
nikitalita 34c38e1415 Fix AssemblyLoading bug
If the AssemblyLoader attempted to load a non-csil dll
while iterating through the file list, it would catch the exception
OUTSIDE the loop, and wouldn't load the rest.
This fix makes it catch inside the loop so it will continue iterating.
2021-10-07 13:36:03 -07:00
Perfare c85873b729 0.16.0 2021-07-06 16:03:54 +08:00
Perfare b146d251a7 add option to not show error message 2021-07-06 15:57:59 +08:00
Perfare 3129d67fc1 Improve ShaderConverter 2021-07-06 12:45:24 +08:00
Perfare 850ba63a10 support exporting VideoClips with a size above 2gb. close #765 2021-07-02 03:26:46 +08:00
Perfare 17b91984d6 fixed bug 2021-07-02 02:29:03 +08:00
Perfare 7ab2cda120 refactor the file reading part 2021-07-02 02:17:59 +08:00
Perfare 4345885cc9 remember the last opened path, close #646 2021-06-30 22:41:16 +08:00
Perfare 53720e37ab Fixed #435 2021-06-30 06:31:05 +08:00
Perfare 7c3cb36630 update project files 2021-06-29 11:03:19 +08:00
Perfare c1cddce031 added option to support version stripped files, close #766 2021-06-29 10:32:19 +08:00
Perfare 973a1076e4 support exporting AnimationClip versions below 4.3 2021-06-29 02:43:42 +08:00
Perfare 089e164756 improved Sprite export 2021-06-28 07:14:02 +08:00
Perfare c2b6691fd9 fix build 2021-06-27 09:42:13 +08:00
Perfare 8dec094304 update project files 2021-06-27 09:27:40 +08:00
Perfare bedee240be Use ImageSharp to process textures 2021-06-27 07:33:20 +08:00
Perfare d963d71b12 clean up TypeDefinitionConverter code 2021-06-26 13:16:12 +08:00
Perfare 77a0c9c40a Fbx multiple uv export 2021-06-24 13:48:56 +08:00
Perfare f3e406983b Merge pull request #768 from Fraxul/master
Fix blend shape export with multiple submeshes
2021-06-24 12:59:31 +08:00
Dan Weatherford 08b7bfcf9a Fix blend shape export with multiple submeshes
Share a single vertex list between submeshes in the exported mesh, which
makes the blend target vertex list indices line up correctly.

As a bonus, the exported FBX file will be smaller for meshes with more
than one submesh, since we're not duplicating vertices anymore.
2021-06-20 00:18:22 -05:00
Patrick King 57e4f7cefd Add an option to export all UVs as diffuse maps. 2021-06-11 17:12:15 -06:00
Patrick King c9cf2d188e Enable FBX export for higher UV maps. 2021-06-11 14:26:37 -06:00
73 changed files with 2522 additions and 7697 deletions
+9 -48
View File
@@ -1,51 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssetStudio.PInvoke</RootNamespace>
<AssemblyName>AssetStudio.PInvoke</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.16.0.0</Version>
<AssemblyVersion>0.16.0.0</AssemblyVersion>
<FileVersion>0.16.0.0</FileVersion>
<Copyright>Copyright © Perfare 2020-2021; Copyright © hozuki 2020</Copyright>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DllLoader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utf8StringHandle.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AssetStudio.PInvoke")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssetStudio.PInvoke")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("40c796b5-88ce-4adc-acd6-2f4862b7f136")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+84 -84
View File
@@ -1,29 +1,29 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29920.165
VisualStudioVersion = 16.0.31410.357
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{422FEC21-EF60-4F29-AA56-95DFDA23C913}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{80AEC261-21EE-4E4F-A93B-7A744DC84888}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudio.PInvoke", "AssetStudio.PInvoke\AssetStudio.PInvoke.csproj", "{0B2BE613-3049-4021-85D1-21C325F729F4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBXNative", "AssetStudioFBXNative\AssetStudioFBXNative.vcxproj", "{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioFBXWrapper", "AssetStudioFBXWrapper\AssetStudioFBXWrapper.csproj", "{BD76E63F-1517-47FA-8233-33E853A3ACEE}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioFBXWrapper", "AssetStudioFBXWrapper\AssetStudioFBXWrapper.csproj", "{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}"
ProjectSection(ProjectDependencies) = postProject
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027} = {11EA25A3-ED68-40EE-A9D0-7FDE3B583027}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Texture2DDecoderNative", "Texture2DDecoderNative\Texture2DDecoderNative.vcxproj", "{29356642-C46E-4144-83D8-22DC09D0D7FD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{29EAD018-1C67-497A-AB8E-727D595AD756}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Texture2DDecoderWrapper", "Texture2DDecoderWrapper\Texture2DDecoderWrapper.csproj", "{2AFCE830-B463-49B3-A026-877E5EAFC0A4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Texture2DDecoderWrapper", "Texture2DDecoderWrapper\Texture2DDecoderWrapper.csproj", "{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}"
ProjectSection(ProjectDependencies) = postProject
{29356642-C46E-4144-83D8-22DC09D0D7FD} = {29356642-C46E-4144-83D8-22DC09D0D7FD}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio.PInvoke", "AssetStudio.PInvoke\AssetStudio.PInvoke.csproj", "{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBXNative", "AssetStudioFBXNative\AssetStudioFBXNative.vcxproj", "{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Texture2DDecoderNative", "Texture2DDecoderNative\Texture2DDecoderNative.vcxproj", "{29356642-C46E-4144-83D8-22DC09D0D7FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -35,42 +35,78 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.ActiveCfg = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.Build.0 = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.ActiveCfg = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.Build.0 = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|Any CPU.Build.0 = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.ActiveCfg = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.Build.0 = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.ActiveCfg = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.Build.0 = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|Any CPU.Build.0 = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.ActiveCfg = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.Build.0 = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.ActiveCfg = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.Build.0 = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|Any CPU.Build.0 = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.ActiveCfg = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.Build.0 = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.ActiveCfg = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.Build.0 = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.ActiveCfg = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.Build.0 = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.ActiveCfg = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.Build.0 = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|Any CPU.Build.0 = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.ActiveCfg = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.Build.0 = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.ActiveCfg = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.Build.0 = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|Any CPU.Build.0 = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x64.ActiveCfg = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x64.Build.0 = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x86.ActiveCfg = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x86.Build.0 = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|Any CPU.ActiveCfg = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|Any CPU.Build.0 = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x64.ActiveCfg = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x64.Build.0 = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x86.ActiveCfg = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x86.Build.0 = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x64.ActiveCfg = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x64.Build.0 = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x86.ActiveCfg = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x86.Build.0 = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|Any CPU.Build.0 = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x64.ActiveCfg = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x64.Build.0 = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x86.ActiveCfg = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x86.Build.0 = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x64.ActiveCfg = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x64.Build.0 = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x86.ActiveCfg = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x86.Build.0 = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|Any CPU.Build.0 = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x64.ActiveCfg = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x64.Build.0 = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x86.ActiveCfg = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x86.Build.0 = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x64.ActiveCfg = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x64.Build.0 = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x86.ActiveCfg = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x86.Build.0 = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|Any CPU.Build.0 = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x64.ActiveCfg = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x64.Build.0 = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x86.ActiveCfg = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x86.Build.0 = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x64.ActiveCfg = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x64.Build.0 = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x86.ActiveCfg = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x86.Build.0 = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|Any CPU.Build.0 = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x64.ActiveCfg = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x64.Build.0 = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x86.ActiveCfg = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x86.Build.0 = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x64.ActiveCfg = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x64.Build.0 = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x86.ActiveCfg = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x86.Build.0 = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|Any CPU.Build.0 = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x64.ActiveCfg = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x64.Build.0 = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x86.ActiveCfg = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x86.Build.0 = Release|Any CPU
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|Any CPU.ActiveCfg = Debug|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|Any CPU.Build.0 = Debug|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x64.ActiveCfg = Debug|x64
@@ -83,18 +119,6 @@ Global
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x64.Build.0 = Release|x64
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x86.ActiveCfg = Release|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x86.Build.0 = Release|Win32
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Debug|x64.ActiveCfg = Debug|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Debug|x64.Build.0 = Debug|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Debug|x86.ActiveCfg = Debug|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Debug|x86.Build.0 = Debug|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Release|Any CPU.Build.0 = Release|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Release|x64.ActiveCfg = Release|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Release|x64.Build.0 = Release|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Release|x86.ActiveCfg = Release|Any CPU
{BD76E63F-1517-47FA-8233-33E853A3ACEE}.Release|x86.Build.0 = Release|Any CPU
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|Any CPU.ActiveCfg = Debug|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|Any CPU.Build.0 = Debug|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x64.ActiveCfg = Debug|x64
@@ -107,35 +131,11 @@ 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
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Debug|x64.ActiveCfg = Debug|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Debug|x64.Build.0 = Debug|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Debug|x86.ActiveCfg = Debug|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Debug|x86.Build.0 = Debug|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Release|Any CPU.Build.0 = Release|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Release|x64.ActiveCfg = Release|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Release|x64.Build.0 = Release|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Release|x86.ActiveCfg = Release|Any CPU
{2AFCE830-B463-49B3-A026-877E5EAFC0A4}.Release|x86.Build.0 = Release|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Debug|x64.ActiveCfg = Debug|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Debug|x64.Build.0 = Debug|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Debug|x86.ActiveCfg = Debug|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Debug|x86.Build.0 = Debug|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|Any CPU.Build.0 = Release|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x64.ActiveCfg = Release|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x64.Build.0 = Release|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x86.ActiveCfg = Release|Any CPU
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F8734F96-97B6-40CA-B791-6D5467F2F713}
SolutionGuid = {3C074481-9CDD-4780-B9F6-57BBC5092EA2}
EndGlobalSection
EndGlobal
+9 -147
View File
@@ -1,149 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssetStudio</RootNamespace>
<AssemblyName>AssetStudio</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<Version>0.16.0.0</Version>
<AssemblyVersion>0.16.0.0</AssemblyVersion>
<FileVersion>0.16.0.0</FileVersion>
<Copyright>Copyright © Perfare 2018-2021</Copyright>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="7zip\Common\CommandLineParser.cs" />
<Compile Include="7zip\Common\CRC.cs" />
<Compile Include="7zip\Common\InBuffer.cs" />
<Compile Include="7zip\Common\OutBuffer.cs" />
<Compile Include="7zip\Compress\LZMA\LzmaBase.cs" />
<Compile Include="7zip\Compress\LZMA\LzmaDecoder.cs" />
<Compile Include="7zip\Compress\LZMA\LzmaEncoder.cs" />
<Compile Include="7zip\Compress\LZ\IMatchFinder.cs" />
<Compile Include="7zip\Compress\LZ\LzBinTree.cs" />
<Compile Include="7zip\Compress\LZ\LzInWindow.cs" />
<Compile Include="7zip\Compress\LZ\LzOutWindow.cs" />
<Compile Include="7zip\Compress\RangeCoder\RangeCoder.cs" />
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBit.cs" />
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBitTree.cs" />
<Compile Include="7zip\ICoder.cs" />
<Compile Include="AssetsManager.cs" />
<Compile Include="Brotli\BitReader.cs" />
<Compile Include="Brotli\BrotliInputStream.cs" />
<Compile Include="Brotli\BrotliRuntimeException.cs" />
<Compile Include="Brotli\Context.cs" />
<Compile Include="Brotli\Decode.cs" />
<Compile Include="Brotli\Dictionary.cs" />
<Compile Include="Brotli\Huffman.cs" />
<Compile Include="Brotli\HuffmanTreeGroup.cs" />
<Compile Include="Brotli\IntReader.cs" />
<Compile Include="Brotli\Prefix.cs" />
<Compile Include="Brotli\RunningState.cs" />
<Compile Include="Brotli\State.cs" />
<Compile Include="Brotli\Transform.cs" />
<Compile Include="Brotli\Utils.cs" />
<Compile Include="Brotli\WordTransformType.cs" />
<Compile Include="BuildTarget.cs" />
<Compile Include="BuildType.cs" />
<Compile Include="BundleFile.cs" />
<Compile Include="Classes\Animation.cs" />
<Compile Include="Classes\AnimationClip.cs" />
<Compile Include="Classes\Animator.cs" />
<Compile Include="Classes\AnimatorController.cs" />
<Compile Include="Classes\AnimatorOverrideController.cs" />
<Compile Include="Classes\AssetBundle.cs" />
<Compile Include="Classes\AudioClip.cs" />
<Compile Include="Classes\Avatar.cs" />
<Compile Include="Classes\Behaviour.cs" />
<Compile Include="Classes\BuildSettings.cs" />
<Compile Include="Classes\Component.cs" />
<Compile Include="Classes\EditorExtension.cs" />
<Compile Include="Classes\Font.cs" />
<Compile Include="Classes\GameObject.cs" />
<Compile Include="Classes\Material.cs" />
<Compile Include="Classes\Mesh.cs" />
<Compile Include="Classes\MeshFilter.cs" />
<Compile Include="Classes\MeshRenderer.cs" />
<Compile Include="Classes\MonoBehaviour.cs" />
<Compile Include="Classes\MonoScript.cs" />
<Compile Include="Classes\MovieTexture.cs" />
<Compile Include="Classes\NamedObject.cs" />
<Compile Include="Classes\Object.cs" />
<Compile Include="Classes\PlayerSettings.cs" />
<Compile Include="Classes\PPtr.cs" />
<Compile Include="Classes\RectTransform.cs" />
<Compile Include="Classes\Renderer.cs" />
<Compile Include="Classes\ResourceManager.cs" />
<Compile Include="Classes\RuntimeAnimatorController.cs" />
<Compile Include="Classes\Shader.cs" />
<Compile Include="Classes\SkinnedMeshRenderer.cs" />
<Compile Include="Classes\Sprite.cs" />
<Compile Include="Classes\SpriteAtlas.cs" />
<Compile Include="Classes\TextAsset.cs" />
<Compile Include="Classes\Texture.cs" />
<Compile Include="Classes\Texture2D.cs" />
<Compile Include="Classes\Transform.cs" />
<Compile Include="Classes\VideoClip.cs" />
<Compile Include="ClassIDType.cs" />
<Compile Include="CommonString.cs" />
<Compile Include="EndianBinaryReader.cs" />
<Compile Include="Extensions\BinaryReaderExtensions.cs" />
<Compile Include="Extensions\BinaryWriterExtensions.cs" />
<Compile Include="Extensions\StreamExtensions.cs" />
<Compile Include="FileIdentifier.cs" />
<Compile Include="IImported.cs" />
<Compile Include="ILogger.cs" />
<Compile Include="ImportHelper.cs" />
<Compile Include="IProgress.cs" />
<Compile Include="LocalSerializedObjectIdentifier.cs" />
<Compile Include="Logger.cs" />
<Compile Include="Lz4DecoderStream.cs" />
<Compile Include="Math\Color.cs" />
<Compile Include="Math\Half.cs" />
<Compile Include="Math\HalfHelper.cs" />
<Compile Include="Math\Matrix4x4.cs" />
<Compile Include="Math\Quaternion.cs" />
<Compile Include="Math\Vector2.cs" />
<Compile Include="Math\Vector3.cs" />
<Compile Include="Math\Vector4.cs" />
<Compile Include="ObjectInfo.cs" />
<Compile Include="ObjectReader.cs" />
<Compile Include="Progress.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResourceReader.cs" />
<Compile Include="SerializedFile.cs" />
<Compile Include="SerializedFileFormatVersion.cs" />
<Compile Include="SerializedFileHeader.cs" />
<Compile Include="SerializedType.cs" />
<Compile Include="SevenZipHelper.cs" />
<Compile Include="StreamFile.cs" />
<Compile Include="TypeTree.cs" />
<Compile Include="TypeTreeHelper.cs" />
<Compile Include="TypeTreeNode.cs" />
<Compile Include="WebFile.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
+65 -40
View File
@@ -9,7 +9,9 @@ namespace AssetStudio
{
public class AssetsManager
{
public string SpecifyUnityVersion;
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
internal Dictionary<string, BinaryReader> resourceFileReaders = new Dictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
@@ -59,42 +61,54 @@ namespace AssetStudio
private void LoadFile(string fullName)
{
switch (CheckFileType(fullName, out var reader))
var reader = new FileReader(fullName);
LoadFile(reader);
}
private void LoadFile(FileReader reader)
{
switch (reader.FileType)
{
case FileType.AssetsFile:
LoadAssetsFile(fullName, reader);
LoadAssetsFile(reader);
break;
case FileType.BundleFile:
LoadBundleFile(fullName, reader);
LoadBundleFile(reader);
break;
case FileType.WebFile:
LoadWebFile(fullName, reader);
LoadWebFile(reader);
break;
case FileType.GZipFile:
LoadFile(DecompressGZip(reader));
break;
case FileType.BrotliFile:
LoadFile(DecompressBrotli(reader));
break;
}
}
private void LoadAssetsFile(string fullName, EndianBinaryReader reader)
private void LoadAssetsFile(FileReader reader)
{
var fileName = Path.GetFileName(fullName);
if (!assetsFileListHash.Contains(fileName))
if (!assetsFileListHash.Contains(reader.FileName))
{
Logger.Info($"Loading {fileName}");
Logger.Info($"Loading {reader.FileName}");
try
{
var assetsFile = new SerializedFile(this, fullName, reader);
var assetsFile = new SerializedFile(reader, this);
CheckStrippedVersion(assetsFile);
assetsFileList.Add(assetsFile);
assetsFileListHash.Add(assetsFile.fileName);
foreach (var sharedFile in assetsFile.m_Externals)
{
var sharedFilePath = Path.Combine(Path.GetDirectoryName(fullName), sharedFile.fileName);
var sharedFileName = sharedFile.fileName;
if (!importFilesHash.Contains(sharedFileName))
{
var sharedFilePath = Path.Combine(Path.GetDirectoryName(reader.FullPath), sharedFileName);
if (!File.Exists(sharedFilePath))
{
var findFiles = Directory.GetFiles(Path.GetDirectoryName(fullName), sharedFileName, SearchOption.AllDirectories);
var findFiles = Directory.GetFiles(Path.GetDirectoryName(reader.FullPath), sharedFileName, SearchOption.AllDirectories);
if (findFiles.Length > 0)
{
sharedFilePath = findFiles[0];
@@ -111,7 +125,7 @@ namespace AssetStudio
}
catch (Exception e)
{
Logger.Error($"Error while reading assets file {fileName}", e);
Logger.Error($"Error while reading assets file {reader.FileName}", e);
reader.Dispose();
}
}
@@ -121,44 +135,43 @@ namespace AssetStudio
}
}
private void LoadAssetsFromMemory(string fullName, EndianBinaryReader reader, string originalPath, string unityVersion = null)
private void LoadAssetsFromMemory(FileReader reader, string originalPath, string unityVersion = null)
{
var fileName = Path.GetFileName(fullName);
if (!assetsFileListHash.Contains(fileName))
if (!assetsFileListHash.Contains(reader.FileName))
{
try
{
var assetsFile = new SerializedFile(this, fullName, reader);
var assetsFile = new SerializedFile(reader, this);
assetsFile.originalPath = originalPath;
if (assetsFile.header.m_Version < SerializedFileFormatVersion.kUnknown_7)
if (!string.IsNullOrEmpty(unityVersion) && assetsFile.header.m_Version < SerializedFileFormatVersion.kUnknown_7)
{
assetsFile.SetVersion(unityVersion);
}
CheckStrippedVersion(assetsFile);
assetsFileList.Add(assetsFile);
assetsFileListHash.Add(assetsFile.fileName);
}
catch (Exception e)
{
Logger.Error($"Error while reading assets file {fileName} from {Path.GetFileName(originalPath)}", e);
resourceFileReaders.Add(fileName, reader);
Logger.Error($"Error while reading assets file {reader.FileName} from {Path.GetFileName(originalPath)}", e);
resourceFileReaders.Add(reader.FileName, reader);
}
}
}
private void LoadBundleFile(string fullName, EndianBinaryReader reader, string parentPath = null)
private void LoadBundleFile(FileReader reader, string originalPath = null)
{
var fileName = Path.GetFileName(fullName);
Logger.Info("Loading " + fileName);
Logger.Info("Loading " + reader.FileName);
try
{
var bundleFile = new BundleFile(reader, fullName);
var bundleFile = new BundleFile(reader);
foreach (var file in bundleFile.fileList)
{
var subReader = new EndianBinaryReader(file.stream);
if (SerializedFile.IsSerializedFile(subReader))
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
var subReader = new FileReader(dummyPath, file.stream);
if (subReader.FileType == FileType.AssetsFile)
{
var dummyPath = Path.GetDirectoryName(fullName) + Path.DirectorySeparatorChar + file.fileName;
LoadAssetsFromMemory(dummyPath, subReader, parentPath ?? fullName, bundleFile.m_Header.unityRevision);
LoadAssetsFromMemory(subReader, originalPath ?? reader.FullPath, bundleFile.m_Header.unityRevision);
}
else
{
@@ -168,10 +181,10 @@ namespace AssetStudio
}
catch (Exception e)
{
var str = $"Error while reading bundle file {fileName}";
if (parentPath != null)
var str = $"Error while reading bundle file {reader.FileName}";
if (originalPath != null)
{
str += $" from {Path.GetFileName(parentPath)}";
str += $" from {Path.GetFileName(originalPath)}";
}
Logger.Error(str, e);
}
@@ -181,36 +194,36 @@ namespace AssetStudio
}
}
private void LoadWebFile(string fullName, EndianBinaryReader reader)
private void LoadWebFile(FileReader reader)
{
var fileName = Path.GetFileName(fullName);
Logger.Info("Loading " + fileName);
Logger.Info("Loading " + reader.FileName);
try
{
var webFile = new WebFile(reader);
foreach (var file in webFile.fileList)
{
var dummyPath = Path.Combine(Path.GetDirectoryName(fullName), file.fileName);
switch (CheckFileType(file.stream, out var fileReader))
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
var subReader = new FileReader(dummyPath, file.stream);
switch (subReader.FileType)
{
case FileType.AssetsFile:
LoadAssetsFromMemory(dummyPath, fileReader, fullName);
LoadAssetsFromMemory(subReader, reader.FullPath);
break;
case FileType.BundleFile:
LoadBundleFile(dummyPath, fileReader, fullName);
LoadBundleFile(subReader, reader.FullPath);
break;
case FileType.WebFile:
LoadWebFile(dummyPath, fileReader);
LoadWebFile(subReader);
break;
case FileType.ResourceFile:
resourceFileReaders[file.fileName] = fileReader; //TODO
resourceFileReaders[file.fileName] = subReader; //TODO
break;
}
}
}
catch (Exception e)
{
Logger.Error($"Error while reading web file {fileName}", e);
Logger.Error($"Error while reading web file {reader.FileName}", e);
}
finally
{
@@ -218,6 +231,18 @@ namespace AssetStudio
}
}
public void CheckStrippedVersion(SerializedFile assetsFile)
{
if (assetsFile.IsVersionStripped && string.IsNullOrEmpty(SpecifyUnityVersion))
{
throw new Exception("The Unity version has been stripped, please set the version in the options");
}
if (!string.IsNullOrEmpty(SpecifyUnityVersion))
{
assetsFile.SetVersion(SpecifyUnityVersion);
}
}
public void Clear()
{
foreach (var assetsFile in assetsFileList)
+7 -7
View File
@@ -41,7 +41,7 @@ namespace AssetStudio
public StreamFile[] fileList;
public BundleFile(EndianBinaryReader reader, string path)
public BundleFile(FileReader reader)
{
m_Header = new Header();
m_Header.signature = reader.ReadStringToNull();
@@ -59,19 +59,19 @@ namespace AssetStudio
goto case "UnityFS";
}
ReadHeaderAndBlocksInfo(reader);
using (var blocksStream = CreateBlocksStream(path))
using (var blocksStream = CreateBlocksStream(reader.FullPath))
{
ReadBlocksAndDirectory(reader, blocksStream);
ReadFiles(blocksStream, path);
ReadFiles(blocksStream, reader.FullPath);
}
break;
case "UnityFS":
ReadHeader(reader);
ReadBlocksInfoAndDirectory(reader);
using (var blocksStream = CreateBlocksStream(path))
using (var blocksStream = CreateBlocksStream(reader.FullPath))
{
ReadBlocks(reader, blocksStream);
ReadFiles(blocksStream, path);
ReadFiles(blocksStream, reader.FullPath);
}
break;
}
@@ -120,7 +120,7 @@ namespace AssetStudio
var uncompressedSizeSum = m_BlocksInfo.Sum(x => x.uncompressedSize);
if (uncompressedSizeSum >= int.MaxValue)
{
/*var memoryMappedFile = MemoryMappedFile.CreateNew(Path.GetFileName(path), uncompressedSizeSum);
/*var memoryMappedFile = MemoryMappedFile.CreateNew(null, uncompressedSizeSum);
assetsDataStream = memoryMappedFile.CreateViewStream();*/
blocksStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
}
@@ -175,7 +175,7 @@ namespace AssetStudio
file.fileName = Path.GetFileName(node.path);
if (node.size >= int.MaxValue)
{
/*var memoryMappedFile = MemoryMappedFile.CreateNew(file.fileName, entryinfo_size);
/*var memoryMappedFile = MemoryMappedFile.CreateNew(null, entryinfo_size);
file.stream = memoryMappedFile.CreateViewStream();*/
var extractPath = path + "_unpacked" + Path.DirectorySeparatorChar;
Directory.CreateDirectory(extractPath);
+48
View File
@@ -637,6 +637,50 @@ namespace AssetStudio
m_Binding = new ValueArrayConstant(reader);
}
}
public AnimationClipBindingConstant ConvertValueArrayToGenericBinding()
{
var bindings = new AnimationClipBindingConstant();
var genericBindings = new List<GenericBinding>();
var values = m_Binding;
for (int i = 0; i < values.m_ValueArray.Length;)
{
var curveID = values.m_ValueArray[i].m_ID;
var curveTypeID = values.m_ValueArray[i].m_TypeID;
var binding = new GenericBinding();
genericBindings.Add(binding);
if (curveTypeID == 4174552735) //CRC(PositionX))
{
binding.path = curveID;
binding.attribute = 1; //kBindTransformPosition
binding.typeID = ClassIDType.Transform;
i += 3;
}
else if (curveTypeID == 2211994246) //CRC(QuaternionX))
{
binding.path = curveID;
binding.attribute = 2; //kBindTransformRotation
binding.typeID = ClassIDType.Transform;
i += 4;
}
else if (curveTypeID == 1512518241) //CRC(ScaleX))
{
binding.path = curveID;
binding.attribute = 3; //kBindTransformScale
binding.typeID = ClassIDType.Transform;
i += 3;
}
else
{
binding.typeID = ClassIDType.Animator;
binding.path = 0;
binding.attribute = curveID;
i++;
}
}
bindings.genericBindings = genericBindings.ToArray();
return bindings;
}
}
public class ValueDelta
@@ -754,6 +798,8 @@ namespace AssetStudio
public byte customType;
public byte isPPtrCurve;
public GenericBinding() { }
public GenericBinding(ObjectReader reader)
{
var version = reader.version;
@@ -779,6 +825,8 @@ namespace AssetStudio
public GenericBinding[] genericBindings;
public PPtr<Object>[] pptrCurveMapping;
public AnimationClipBindingConstant() { }
public AnimationClipBindingConstant(ObjectReader reader)
{
int numBindings = reader.ReadInt32();
+4
View File
@@ -31,6 +31,10 @@ namespace AssetStudio
if (version[0] >= 5) //5.0 and up
{
var m_LinearVelocityBlending = reader.ReadBoolean();
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
{
var m_StabilizeFeet = reader.ReadBoolean();
}
reader.AlignStream();
}
+5 -5
View File
@@ -27,8 +27,8 @@ namespace AssetStudio
public AudioCompressionFormat m_CompressionFormat;
public string m_Source;
public ulong m_Offset;
public long m_Size;
public long m_Offset; //ulong
public long m_Size; //ulong
public ResourceReader m_AudioData;
public AudioClip(ObjectReader reader) : base(reader)
@@ -74,7 +74,7 @@ namespace AssetStudio
//StreamedResource m_Resource
m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadUInt64();
m_Offset = reader.ReadInt64();
m_Size = reader.ReadInt64();
m_CompressionFormat = (AudioCompressionFormat)reader.ReadInt32();
}
@@ -82,11 +82,11 @@ namespace AssetStudio
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_Source))
{
resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, (int)m_Size);
resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, m_Size);
}
else
{
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size);
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_Size);
}
m_AudioData = resourceReader;
}
+1 -1
View File
@@ -681,7 +681,7 @@ namespace AssetStudio
{
if (m_VertexData.m_VertexCount > 0)
{
var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size);
var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
m_VertexData.m_DataSize = resourceReader.GetData();
}
}
+29 -14
View File
@@ -427,10 +427,9 @@ namespace AssetStudio
m_Size = reader.ReadInt32();
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] > 0) ||
(version[0] == 2020 && version[1] == 3 && version[2] == 0 && version[3] >= 2) || //2020.3.0f2 to 2020.3.x
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 to 2021.1.x
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
{
m_IsPartialCB = reader.ReadBoolean();
reader.AlignStream();
@@ -583,7 +582,7 @@ namespace AssetStudio
m_BlobIndex = reader.ReadUInt32();
m_Channels = new ParserBindChannels(reader);
if (version[0] >= 2019) //2019 and up
if ((version[0] >= 2019 && version[0] < 2021) || (version[0] == 2021 && version[1] < 2)) //2019 ~2021.1
{
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
@@ -604,10 +603,9 @@ namespace AssetStudio
reader.AlignStream();
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] > 0) ||
(version[0] == 2020 && version[1] == 3 && version[2] == 0 && version[3] >= 2) || //2020.3.0f2 to 2020.3.x
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 to 2021.1.x
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
{
m_Parameters = new SerializedProgramParameters(reader);
}
@@ -704,10 +702,9 @@ namespace AssetStudio
}
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] > 0) ||
(version[0] == 2020 && version[1] == 3 && version[2] == 0 && version[3] >= 2) || //2020.3.0f2 to 2020.3.x
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 to 2021.1.x
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
{
m_CommonParameters = new SerializedProgramParameters(reader);
}
@@ -742,6 +739,7 @@ namespace AssetStudio
public string m_Name;
public string m_TextureName;
public SerializedTagMap m_Tags;
public ushort[] m_SerializedKeywordStateMask;
public SerializedPass(ObjectReader reader)
{
@@ -758,10 +756,13 @@ namespace AssetStudio
reader.AlignStream();
m_Platforms = reader.ReadUInt8Array();
reader.AlignStream();
m_LocalKeywordMask = reader.ReadUInt16Array();
reader.AlignStream();
m_GlobalKeywordMask = reader.ReadUInt16Array();
reader.AlignStream();
if (version[0] < 2021 || (version[0] == 2021 && version[1] < 2)) //2021.1 and down
{
m_LocalKeywordMask = reader.ReadUInt16Array();
reader.AlignStream();
m_GlobalKeywordMask = reader.ReadUInt16Array();
reader.AlignStream();
}
}
int numIndices = reader.ReadInt32();
@@ -793,6 +794,11 @@ 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
{
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
reader.AlignStream();
}
}
}
@@ -859,6 +865,8 @@ namespace AssetStudio
{
public SerializedProperties m_PropInfo;
public SerializedSubShader[] m_SubShaders;
public string[] m_KeywordNames;
public byte[] m_KeywordFlags;
public string m_Name;
public string m_CustomEditorName;
public string m_FallbackName;
@@ -879,6 +887,13 @@ namespace AssetStudio
m_SubShaders[i] = new SerializedSubShader(reader);
}
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
{
m_KeywordNames = reader.ReadStringArray();
m_KeywordFlags = reader.ReadUInt8Array();
reader.AlignStream();
}
m_Name = reader.ReadAlignedString();
m_CustomEditorName = reader.ReadAlignedString();
m_FallbackName = reader.ReadAlignedString();
+3 -3
View File
@@ -4,7 +4,7 @@ namespace AssetStudio
{
public class StreamingInfo
{
public ulong offset;
public long offset; //ulong
public uint size;
public string path;
@@ -14,7 +14,7 @@ namespace AssetStudio
if (version[0] >= 2020) //2020.1 and up
{
offset = reader.ReadUInt64();
offset = reader.ReadInt64();
}
else
{
@@ -134,7 +134,7 @@ namespace AssetStudio
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_StreamData?.path))
{
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size);
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
}
else
{
+6 -6
View File
@@ -5,14 +5,14 @@ namespace AssetStudio
public class StreamedResource
{
public string m_Source;
public ulong m_Offset;
public ulong m_Size;
public long m_Offset; //ulong
public long m_Size; //ulong
public StreamedResource(BinaryReader reader)
{
m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadUInt64();
m_Size = reader.ReadUInt64();
m_Offset = reader.ReadInt64();
m_Size = reader.ReadInt64();
}
}
@@ -60,11 +60,11 @@ namespace AssetStudio
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_ExternalResources.m_Source))
{
resourceReader = new ResourceReader(m_ExternalResources.m_Source, assetsFile, m_ExternalResources.m_Offset, (int)m_ExternalResources.m_Size);
resourceReader = new ResourceReader(m_ExternalResources.m_Source, assetsFile, m_ExternalResources.m_Offset, m_ExternalResources.m_Size);
}
else
{
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_ExternalResources.m_Size);
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_ExternalResources.m_Size);
}
m_VideoData = resourceReader;
}
+100
View File
@@ -0,0 +1,100 @@
using System.IO;
using System.Linq;
namespace AssetStudio
{
public class FileReader : EndianBinaryReader
{
public string FullPath;
public string FileName;
public FileType FileType;
private static readonly byte[] gzipMagic = { 0x1f, 0x8b };
private static readonly byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
public FileReader(string path) : this(path, File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { }
public FileReader(string path, Stream stream) : base(stream, EndianType.BigEndian)
{
FullPath = Path.GetFullPath(path);
FileName = Path.GetFileName(path);
FileType = CheckFileType();
}
private FileType CheckFileType()
{
var signature = this.ReadStringToNull(20);
Position = 0;
switch (signature)
{
case "UnityWeb":
case "UnityRaw":
case "UnityArchive":
case "UnityFS":
return FileType.BundleFile;
case "UnityWebData1.0":
return FileType.WebFile;
default:
{
var magic = ReadBytes(2);
Position = 0;
if (gzipMagic.SequenceEqual(magic))
{
return FileType.GZipFile;
}
Position = 0x20;
magic = ReadBytes(6);
Position = 0;
if (brotliMagic.SequenceEqual(magic))
{
return FileType.BrotliFile;
}
if (IsSerializedFile())
{
return FileType.AssetsFile;
}
else
{
return FileType.ResourceFile;
}
}
}
}
private bool IsSerializedFile()
{
var fileSize = BaseStream.Length;
if (fileSize < 20)
{
return false;
}
var m_MetadataSize = ReadUInt32();
long m_FileSize = ReadUInt32();
var m_Version = ReadUInt32();
long m_DataOffset = ReadUInt32();
var m_Endianess = ReadByte();
var m_Reserved = ReadBytes(3);
if (m_Version >= 22)
{
if (fileSize < 48)
{
Position = 0;
return false;
}
m_MetadataSize = ReadUInt32();
m_FileSize = ReadInt64();
m_DataOffset = ReadInt64();
}
Position = 0;
if (m_FileSize != fileSize)
{
return false;
}
if (m_DataOffset > fileSize)
{
return false;
}
return true;
}
}
}
+18
View File
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AssetStudio
{
public enum FileType
{
AssetsFile,
BundleFile,
WebFile,
ResourceFile,
GZipFile,
BrotliFile
}
}
+2 -1
View File
@@ -132,6 +132,7 @@ namespace AssetStudio
public class ImportedMesh
{
public string Path { get; set; }
public List<ImportedVertex> VertexList { get; set; }
public List<ImportedSubmesh> SubmeshList { get; set; }
public List<ImportedBone> BoneList { get; set; }
public bool hasNormal { get; set; }
@@ -142,9 +143,9 @@ namespace AssetStudio
public class ImportedSubmesh
{
public List<ImportedVertex> VertexList { get; set; }
public List<ImportedFace> FaceList { get; set; }
public string Material { get; set; }
public int BaseVertex { get; set; }
}
public class ImportedVertex
+26 -56
View File
@@ -1,17 +1,11 @@
using System.Collections.Generic;
using Org.Brotli.Dec;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
namespace AssetStudio
{
public enum FileType
{
AssetsFile,
BundleFile,
WebFile,
ResourceFile
}
public static class ImportHelper
{
public static void MergeSplitAssets(string path, bool allDirectories = false)
@@ -57,55 +51,31 @@ namespace AssetStudio
return selectFile.Distinct().ToArray();
}
public static FileType CheckFileType(Stream stream, out EndianBinaryReader reader)
public static FileReader DecompressGZip(FileReader reader)
{
reader = new EndianBinaryReader(stream);
return CheckFileType(reader);
}
public static FileType CheckFileType(string fileName, out EndianBinaryReader reader)
{
reader = new EndianBinaryReader(File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
return CheckFileType(reader);
}
private static FileType CheckFileType(EndianBinaryReader reader)
{
var signature = reader.ReadStringToNull(20);
reader.Position = 0;
switch (signature)
using (reader)
{
case "UnityWeb":
case "UnityRaw":
case "UnityArchive":
case "UnityFS":
return FileType.BundleFile;
case "UnityWebData1.0":
return FileType.WebFile;
default:
{
var magic = reader.ReadBytes(2);
reader.Position = 0;
if (WebFile.gzipMagic.SequenceEqual(magic))
{
return FileType.WebFile;
}
reader.Position = 0x20;
magic = reader.ReadBytes(6);
reader.Position = 0;
if (WebFile.brotliMagic.SequenceEqual(magic))
{
return FileType.WebFile;
}
if (SerializedFile.IsSerializedFile(reader))
{
return FileType.AssetsFile;
}
else
{
return FileType.ResourceFile;
}
}
var stream = new MemoryStream();
using (var gs = new GZipStream(reader.BaseStream, CompressionMode.Decompress))
{
gs.CopyTo(stream);
}
stream.Position = 0;
return new FileReader(reader.FullPath, stream);
}
}
public static FileReader DecompressBrotli(FileReader reader)
{
using (reader)
{
var stream = new MemoryStream();
using (var brotliStream = new BrotliInputStream(reader.BaseStream))
{
brotliStream.CopyTo(stream);
}
stream.Position = 0;
return new FileReader(reader.FullPath, stream);
}
}
}
+3 -3
View File
@@ -1,8 +1,8 @@
using System.Diagnostics;
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
namespace System
namespace AssetStudio
{
/// <summary>
/// Represents a half-precision floating point number.
+3 -2
View File
@@ -1,6 +1,7 @@
using System.Runtime.InteropServices;
using System;
using System.Runtime.InteropServices;
namespace System
namespace AssetStudio
{
/// <summary>
/// Helper class for Half conversions and some low level operations.
-36
View File
@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AssetStudio")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssetStudio")]
[assembly: AssemblyCopyright("Copyright © Perfare 2018-2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("7662f8c2-7bfd-442e-a948-a43b4f7eb06e")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+29 -17
View File
@@ -8,41 +8,37 @@ namespace AssetStudio
private string path;
private SerializedFile assetsFile;
private long offset;
private int size;
private long size;
private BinaryReader reader;
public ResourceReader(string path, SerializedFile assetsFile, ulong offset, int size)
public ResourceReader(string path, SerializedFile assetsFile, long offset, long size)
{
needSearch = true;
this.path = path;
this.assetsFile = assetsFile;
this.offset = (long)offset;
this.offset = offset;
this.size = size;
}
public ResourceReader(BinaryReader reader, long offset, int size)
public ResourceReader(BinaryReader reader, long offset, long size)
{
this.reader = reader;
this.offset = offset;
this.size = size;
}
public byte[] GetData()
private BinaryReader GetReader()
{
if (needSearch)
{
var resourceFileName = Path.GetFileName(path);
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader))
{
needSearch = false;
reader.BaseStream.Position = offset;
return reader.ReadBytes(size);
return reader;
}
var assetsFileDirectory = Path.GetDirectoryName(assetsFile.fullName);
var resourceFilePath = assetsFileDirectory + Path.DirectorySeparatorChar + resourceFileName;
var resourceFilePath = Path.Combine(assetsFileDirectory, resourceFileName);
if (!File.Exists(resourceFilePath))
{
var findFiles = Directory.GetFiles(assetsFileDirectory, resourceFileName, SearchOption.AllDirectories);
@@ -53,18 +49,34 @@ namespace AssetStudio
}
if (File.Exists(resourceFilePath))
{
reader = new BinaryReader(File.OpenRead(resourceFilePath));
needSearch = false;
reader = new BinaryReader(File.OpenRead(resourceFilePath));
assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader);
reader.BaseStream.Position = offset;
return reader.ReadBytes(size);
return reader;
}
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
}
else
{
return reader;
}
}
reader.BaseStream.Position = offset;
return reader.ReadBytes(size);
public byte[] GetData()
{
var binaryReader = GetReader();
binaryReader.BaseStream.Position = offset;
return binaryReader.ReadBytes((int)size);
}
public void WriteData(string path)
{
var binaryReader = GetReader();
binaryReader.BaseStream.Position = offset;
using (var writer = File.OpenWrite(path))
{
binaryReader.BaseStream.CopyTo(writer, size);
}
}
}
}
+15 -45
View File
@@ -9,7 +9,7 @@ namespace AssetStudio
public class SerializedFile
{
public AssetsManager assetsManager;
public EndianBinaryReader reader;
public FileReader reader;
public string fullName;
public string originalPath;
public string fileName;
@@ -31,12 +31,12 @@ namespace AssetStudio
public List<SerializedType> m_RefTypes;
public string userInformation;
public SerializedFile(AssetsManager assetsManager, string fullName, EndianBinaryReader reader)
public SerializedFile(FileReader reader, AssetsManager assetsManager)
{
this.assetsManager = assetsManager;
this.reader = reader;
this.fullName = fullName;
fileName = Path.GetFileName(fullName);
fullName = reader.FullPath;
fileName = reader.FileName;
// ReadHeader
header = new SerializedFileHeader();
@@ -219,11 +219,14 @@ namespace AssetStudio
public void SetVersion(string stringVersion)
{
unityVersion = stringVersion;
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
buildType = new BuildType(buildSplit[0]);
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
version = versionSplit.Select(int.Parse).ToArray();
if (stringVersion != strippedVersion)
{
unityVersion = stringVersion;
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
buildType = new BuildType(buildSplit[0]);
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
version = versionSplit.Select(int.Parse).ToArray();
}
}
private SerializedType ReadSerializedType(bool isRefType)
@@ -371,41 +374,8 @@ namespace AssetStudio
ObjectsDic.Add(obj.m_PathID, obj);
}
public static bool IsSerializedFile(EndianBinaryReader reader)
{
var fileSize = reader.BaseStream.Length;
if (fileSize < 20)
{
return false;
}
var m_MetadataSize = reader.ReadUInt32();
long m_FileSize = reader.ReadUInt32();
var m_Version = reader.ReadUInt32();
long m_DataOffset = reader.ReadUInt32();
var m_Endianess = reader.ReadByte();
var m_Reserved = reader.ReadBytes(3);
if (m_Version >= 22)
{
if (fileSize < 48)
{
return false;
}
m_MetadataSize = reader.ReadUInt32();
m_FileSize = reader.ReadInt64();
m_DataOffset = reader.ReadInt64();
}
if (m_FileSize != fileSize)
{
reader.Position = 0;
return false;
}
if (m_DataOffset > fileSize)
{
reader.Position = 0;
return false;
}
reader.Position = 0;
return true;
}
public bool IsVersionStripped => unityVersion == strippedVersion;
private const string strippedVersion = "0.0.0";
}
}
+2 -50
View File
@@ -1,17 +1,11 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using Org.Brotli.Dec;
namespace AssetStudio
{
public class WebFile
{
public static byte[] gzipMagic = { 0x1f, 0x8b };
public static byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
public StreamFile[] fileList;
private class WebData
@@ -23,50 +17,8 @@ namespace AssetStudio
public WebFile(EndianBinaryReader reader)
{
var magic = reader.ReadBytes(2);
reader.Position = 0;
if (gzipMagic.SequenceEqual(magic))
{
var stream = new MemoryStream();
using (var gs = new GZipStream(reader.BaseStream, CompressionMode.Decompress))
{
gs.CopyTo(stream);
}
stream.Position = 0;
using (var binaryReader = new BinaryReader(stream))
{
ReadWebData(binaryReader);
}
}
else
{
reader.Position = 0x20;
magic = reader.ReadBytes(6);
reader.Position = 0;
if (brotliMagic.SequenceEqual(magic))
{
var brotliStream = new BrotliInputStream(reader.BaseStream);
var stream = new MemoryStream();
brotliStream.CopyTo(stream);
stream.Position = 0;
using (var binaryReader = new BinaryReader(stream))
{
ReadWebData(binaryReader);
}
}
else
{
reader.endian = EndianType.LittleEndian;
ReadWebData(reader);
}
}
}
private void ReadWebData(BinaryReader reader)
{
reader.endian = EndianType.LittleEndian;
var signature = reader.ReadStringToNull();
if (signature != "UnityWebData1.0")
return;
var headLength = reader.ReadInt32();
var dataList = new List<WebData>();
while (reader.BaseStream.Position < headLength)
@@ -1,60 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BD76E63F-1517-47FA-8233-33E853A3ACEE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssetStudio.FbxInterop</RootNamespace>
<AssemblyName>AssetStudioFBXWrapper</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.16.0.0</Version>
<AssemblyVersion>0.16.0.0</AssemblyVersion>
<FileVersion>0.16.0.0</FileVersion>
<Copyright>Copyright © Perfare 2018-2021; Copyright © hozuki 2020</Copyright>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Include="Fbx.PInvoke.cs" />
<Compile Include="FbxDll.cs" />
<Compile Include="FbxExporterContext.cs" />
<Compile Include="FbxExporterContext.PInvoke.cs" />
<Compile Include="Fbx.cs" />
<Compile Include="FbxExporter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj">
<Project>{40c796b5-88ce-4adc-acd6-2f4862b7f136}</Project>
<Name>AssetStudio.PInvoke</Name>
</ProjectReference>
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
<Project>{7662f8c2-7bfd-442e-a948-a43b4f7eb06e}</Project>
<Name>AssetStudio</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
+2 -2
View File
@@ -28,7 +28,7 @@ namespace AssetStudio
{
public static void Export(string path, IImported imported, bool eulerFilter, float filterPrecision,
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii)
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, float scaleFactor, int versionIndex, bool isAscii)
{
var file = new FileInfo(path);
var dir = file.Directory;
@@ -43,7 +43,7 @@ namespace AssetStudio
var name = Path.GetFileName(path);
using (var exporter = new FbxExporter(name, imported, allNodes, skins, castToBone, boneSize, scaleFactor, versionIndex, isAscii))
using (var exporter = new FbxExporter(name, imported, allNodes, skins, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, versionIndex, isAscii))
{
exporter.Initialize();
exporter.ExportAll(blendShape, animation, eulerFilter, filterPrecision);
+4 -2
View File
@@ -15,11 +15,12 @@ namespace AssetStudio.FbxInterop
private readonly bool _exportSkins;
private readonly bool _castToBone;
private readonly float _boneSize;
private readonly bool _exportAllUvsAsDiffuseMaps;
private readonly float _scaleFactor;
private readonly int _versionIndex;
private readonly bool _isAscii;
internal FbxExporter(string fileName, IImported imported, bool allNodes, bool exportSkins, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii)
internal FbxExporter(string fileName, IImported imported, bool allNodes, bool exportSkins, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, float scaleFactor, int versionIndex, bool isAscii)
{
_context = new FbxExporterContext();
@@ -29,6 +30,7 @@ namespace AssetStudio.FbxInterop
_exportSkins = exportSkins;
_castToBone = castToBone;
_boneSize = boneSize;
_exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps;
_scaleFactor = scaleFactor;
_versionIndex = versionIndex;
_isAscii = isAscii;
@@ -171,7 +173,7 @@ namespace AssetStudio.FbxInterop
{
foreach (var meshFrame in meshFrames)
{
_context.ExportMeshFromFrame(rootFrame, meshFrame, _imported.MeshList, _imported.MaterialList, _imported.TextureList, _exportSkins);
_context.ExportMeshFromFrame(rootFrame, meshFrame, _imported.MeshList, _imported.MaterialList, _imported.TextureList, _exportSkins, _exportAllUvsAsDiffuseMaps);
}
}
+72 -78
View File
@@ -173,12 +173,12 @@ namespace AssetStudio.FbxInterop
AsFbxPrepareMaterials(_pContext, materialCount, textureCount);
}
internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List<ImportedMesh> meshList, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, bool exportSkins)
internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List<ImportedMesh> meshList, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, bool exportSkins, bool exportAllUvsAsDiffuseMaps)
{
var meshNode = _frameToNode[meshFrame];
var mesh = ImportedHelpers.FindMesh(meshFrame.Path, meshList);
ExportMesh(rootFrame, materialList, textureList, meshNode, mesh, exportSkins);
ExportMesh(rootFrame, materialList, textureList, meshNode, mesh, exportSkins, exportAllUvsAsDiffuseMaps);
}
private IntPtr ExportTexture(ImportedTexture texture)
@@ -207,7 +207,7 @@ namespace AssetStudio.FbxInterop
return pTex;
}
private void ExportMesh(ImportedFrame rootFrame, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, bool exportSkins)
private void ExportMesh(ImportedFrame rootFrame, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, bool exportSkins, bool exportAllUvsAsDiffuseMaps)
{
var boneList = importedMesh.BoneList;
var totalBoneCount = 0;
@@ -246,28 +246,25 @@ namespace AssetStudio.FbxInterop
var mesh = AsFbxMeshCreateMesh(_pContext, frameNode);
var totalVertexCount = 0;
foreach (var m in importedMesh.SubmeshList)
{
totalVertexCount += m.VertexList.Count;
}
AsFbxMeshInitControlPoints(mesh, totalVertexCount);
AsFbxMeshInitControlPoints(mesh, importedMesh.VertexList.Count);
if (importedMesh.hasNormal)
{
AsFbxMeshCreateElementNormal(mesh);
}
if (importedMesh.hasUV[0])
for (int i = 0; i < importedMesh.hasUV.Length; i++)
{
AsFbxMeshCreateDiffuseUV(mesh, 0);
}
if (!importedMesh.hasUV[i]) { continue; }
if (importedMesh.hasUV[1])
{
AsFbxMeshCreateNormalMapUV(mesh, 1);
if (i == 1 && !exportAllUvsAsDiffuseMaps)
{
AsFbxMeshCreateNormalMapUV(mesh, 1);
}
else
{
AsFbxMeshCreateDiffuseUV(mesh, i);
}
}
if (importedMesh.hasTangent)
@@ -282,8 +279,6 @@ namespace AssetStudio.FbxInterop
AsFbxMeshCreateElementMaterial(mesh);
var firstVertex = 0;
foreach (var meshObj in importedMesh.SubmeshList)
{
var materialIndex = 0;
@@ -345,71 +340,70 @@ namespace AssetStudio.FbxInterop
}
}
var vertexList = meshObj.VertexList;
var vertexCount = vertexList.Count;
for (var j = 0; j < vertexCount; j += 1)
{
var importedVertex = vertexList[j];
var vertex = importedVertex.Vertex;
AsFbxMeshSetControlPoint(mesh, j + firstVertex, vertex.X, vertex.Y, vertex.Z);
if (importedMesh.hasNormal)
{
var normal = importedVertex.Normal;
AsFbxMeshElementNormalAdd(mesh, 0, normal.X, normal.Y, normal.Z);
}
for (var uvIndex = 0; uvIndex < 2; uvIndex += 1)
{
if (importedMesh.hasUV[uvIndex])
{
var uv = importedVertex.UV[uvIndex];
AsFbxMeshElementUVAdd(mesh, uvIndex, uv[0], uv[1]);
}
}
if (importedMesh.hasTangent)
{
var tangent = importedVertex.Tangent;
AsFbxMeshElementTangentAdd(mesh, 0, tangent.X, tangent.Y, tangent.Z, tangent.W);
}
if (importedMesh.hasColor)
{
var color = importedVertex.Color;
AsFbxMeshElementVertexColorAdd(mesh, 0, color.R, color.G, color.B, color.A);
}
if (hasBones && importedVertex.BoneIndices != null)
{
var boneIndices = importedVertex.BoneIndices;
var boneWeights = importedVertex.Weights;
for (var k = 0; k < 4; k += 1)
{
if (boneIndices[k] < totalBoneCount && boneWeights[k] > 0)
{
AsFbxMeshSetBoneWeight(pClusterArray, boneIndices[k], j + firstVertex, boneWeights[k]);
}
}
}
}
foreach (var face in meshObj.FaceList)
{
var index0 = face.VertexIndices[0] + firstVertex;
var index1 = face.VertexIndices[1] + firstVertex;
var index2 = face.VertexIndices[2] + firstVertex;
var index0 = face.VertexIndices[0] + meshObj.BaseVertex;
var index1 = face.VertexIndices[1] + meshObj.BaseVertex;
var index2 = face.VertexIndices[2] + meshObj.BaseVertex;
AsFbxMeshAddPolygon(mesh, materialIndex, index0, index1, index2);
}
firstVertex += vertexCount;
}
var vertexList = importedMesh.VertexList;
var vertexCount = vertexList.Count;
for (var j = 0; j < vertexCount; j += 1)
{
var importedVertex = vertexList[j];
var vertex = importedVertex.Vertex;
AsFbxMeshSetControlPoint(mesh, j, vertex.X, vertex.Y, vertex.Z);
if (importedMesh.hasNormal)
{
var normal = importedVertex.Normal;
AsFbxMeshElementNormalAdd(mesh, 0, normal.X, normal.Y, normal.Z);
}
for (var uvIndex = 0; uvIndex < importedMesh.hasUV.Length; uvIndex += 1)
{
if (importedMesh.hasUV[uvIndex])
{
var uv = importedVertex.UV[uvIndex];
AsFbxMeshElementUVAdd(mesh, uvIndex, uv[0], uv[1]);
}
}
if (importedMesh.hasTangent)
{
var tangent = importedVertex.Tangent;
AsFbxMeshElementTangentAdd(mesh, 0, tangent.X, tangent.Y, tangent.Z, tangent.W);
}
if (importedMesh.hasColor)
{
var color = importedVertex.Color;
AsFbxMeshElementVertexColorAdd(mesh, 0, color.R, color.G, color.B, color.A);
}
if (hasBones && importedVertex.BoneIndices != null)
{
var boneIndices = importedVertex.BoneIndices;
var boneWeights = importedVertex.Weights;
for (var k = 0; k < 4; k += 1)
{
if (boneIndices[k] < totalBoneCount && boneWeights[k] > 0)
{
AsFbxMeshSetBoneWeight(pClusterArray, boneIndices[k], j, boneWeights[k]);
}
}
}
}
if (hasBones)
{
IntPtr pSkinContext = IntPtr.Zero;
@@ -646,4 +640,4 @@ namespace AssetStudio.FbxInterop
}
}
}
}
@@ -1,19 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("AssetStudioFBXWrapper")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssetStudioFBXWrapper")]
[assembly: AssemblyCopyright("Copyright © Perfare 2018-2020; Copyright © hozuki 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("bd76e63f-1517-47fa-8233-33e853a3acee")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+65 -153
View File
@@ -1,154 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>AssetStudioGUI</RootNamespace>
<AssemblyName>AssetStudioGUI</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="OpenTK, Version=3.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\packages\OpenTK.3.1.0\lib\net20\OpenTK.dll</HintPath>
</Reference>
<Reference Include="OpenTK.GLControl, Version=3.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\packages\OpenTK.GLControl.3.1.0\lib\net20\OpenTK.GLControl.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssetStudioGUIForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="AssetStudioGUIForm.designer.cs">
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon>
</Compile>
<Compile Include="Components\AssetItem.cs" />
<Compile Include="Components\GameObjectTreeNode.cs" />
<Compile Include="Components\GOHierarchy.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Components\OpenFolderDialog.cs" />
<Compile Include="Components\TreeViewExtensions.cs" />
<Compile Include="Components\TypeTreeItem.cs" />
<Compile Include="Exporter.cs" />
<Compile Include="ExportOptions.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="ExportOptions.designer.cs">
<DependentUpon>ExportOptions.cs</DependentUpon>
</Compile>
<Compile Include="GUILogger.cs" />
<Compile Include="GUIProgress.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Studio.cs" />
<EmbeddedResource Include="AssetStudioGUIForm.resx">
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ExportOptions.resx">
<DependentUpon>ExportOptions.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\preview.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\as.ico" />
</ItemGroup>
<ItemGroup>
<ContentWithTargetPath Include="Libraries\x86\fmod.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>x86\fmod.dll</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Libraries\x64\fmod.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>x64\fmod.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj">
<Project>{80aec261-21ee-4e4f-a93b-7a744dc84888}</Project>
<Name>AssetStudioUtility</Name>
</ProjectReference>
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
<Project>{7662f8c2-7bfd-442e-a948-a43b4f7eb06e}</Project>
<Name>AssetStudio</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="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" />
</Target>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net472</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
<Version>0.16.0.0</Version>
<AssemblyVersion>0.16.0.0</AssemblyVersion>
<FileVersion>0.16.0.0</FileVersion>
<Copyright>Copyright © Perfare 2018-2021</Copyright>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj" />
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Update="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Compile Update="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
</ItemGroup>
<ItemGroup>
<ContentWithTargetPath Include="Libraries\x86\fmod.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>x86\fmod.dll</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Libraries\x64\fmod.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>x64\fmod.dll</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" />
</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" />
</Target>
</Project>
+37 -5
View File
@@ -41,6 +41,8 @@
this.displayAll = new System.Windows.Forms.ToolStripMenuItem();
this.enablePreview = new System.Windows.Forms.ToolStripMenuItem();
this.displayInfo = 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();
this.modelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportAllObjectssplitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
@@ -72,6 +74,7 @@
this.filterTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.debugMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem15 = new System.Windows.Forms.ToolStripMenuItem();
this.exportClassStructuresMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.tabControl1 = new System.Windows.Forms.TabControl();
@@ -210,6 +213,7 @@
this.displayAll,
this.enablePreview,
this.displayInfo,
this.toolStripMenuItem14,
this.showExpOpt});
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(66, 21);
@@ -249,6 +253,20 @@
"t, audio bitrate, etc.";
this.displayInfo.CheckedChanged += new System.EventHandler(this.displayAssetInfo_Check);
//
// toolStripMenuItem14
//
this.toolStripMenuItem14.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.specifyUnityVersion});
this.toolStripMenuItem14.Name = "toolStripMenuItem14";
this.toolStripMenuItem14.Size = new System.Drawing.Size(223, 22);
this.toolStripMenuItem14.Text = "Specify Unity version";
//
// specifyUnityVersion
//
this.specifyUnityVersion.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F);
this.specifyUnityVersion.Name = "specifyUnityVersion";
this.specifyUnityVersion.Size = new System.Drawing.Size(100, 23);
//
// showExpOpt
//
this.showExpOpt.Name = "showExpOpt";
@@ -429,7 +447,7 @@
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(396, 6);
this.toolStripSeparator2.Size = new System.Drawing.Size(281, 6);
//
// toolStripMenuItem10
//
@@ -438,27 +456,27 @@
this.toolStripMenuItem12,
this.toolStripMenuItem13});
this.toolStripMenuItem10.Name = "toolStripMenuItem10";
this.toolStripMenuItem10.Size = new System.Drawing.Size(399, 34);
this.toolStripMenuItem10.Size = new System.Drawing.Size(284, 22);
this.toolStripMenuItem10.Text = "Asset list to XML";
//
// toolStripMenuItem11
//
this.toolStripMenuItem11.Name = "toolStripMenuItem11";
this.toolStripMenuItem11.Size = new System.Drawing.Size(270, 34);
this.toolStripMenuItem11.Size = new System.Drawing.Size(165, 22);
this.toolStripMenuItem11.Text = "All assets";
this.toolStripMenuItem11.Click += new System.EventHandler(this.toolStripMenuItem11_Click);
//
// toolStripMenuItem12
//
this.toolStripMenuItem12.Name = "toolStripMenuItem12";
this.toolStripMenuItem12.Size = new System.Drawing.Size(270, 34);
this.toolStripMenuItem12.Size = new System.Drawing.Size(165, 22);
this.toolStripMenuItem12.Text = "Selected assets";
this.toolStripMenuItem12.Click += new System.EventHandler(this.toolStripMenuItem12_Click);
//
// toolStripMenuItem13
//
this.toolStripMenuItem13.Name = "toolStripMenuItem13";
this.toolStripMenuItem13.Size = new System.Drawing.Size(270, 34);
this.toolStripMenuItem13.Size = new System.Drawing.Size(165, 22);
this.toolStripMenuItem13.Text = "Filtered assets";
this.toolStripMenuItem13.Click += new System.EventHandler(this.toolStripMenuItem13_Click);
//
@@ -483,11 +501,22 @@
// debugMenuItem
//
this.debugMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem15,
this.exportClassStructuresMenuItem});
this.debugMenuItem.Name = "debugMenuItem";
this.debugMenuItem.Size = new System.Drawing.Size(59, 21);
this.debugMenuItem.Text = "Debug";
//
// toolStripMenuItem15
//
this.toolStripMenuItem15.Checked = true;
this.toolStripMenuItem15.CheckOnClick = true;
this.toolStripMenuItem15.CheckState = System.Windows.Forms.CheckState.Checked;
this.toolStripMenuItem15.Name = "toolStripMenuItem15";
this.toolStripMenuItem15.Size = new System.Drawing.Size(207, 22);
this.toolStripMenuItem15.Text = "Show error message";
this.toolStripMenuItem15.Click += new System.EventHandler(this.toolStripMenuItem15_Click);
//
// exportClassStructuresMenuItem
//
this.exportClassStructuresMenuItem.Name = "exportClassStructuresMenuItem";
@@ -1178,6 +1207,9 @@
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem11;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem12;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem13;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem14;
private System.Windows.Forms.ToolStripTextBox specifyUnityVersion;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem15;
}
}
+42 -14
View File
@@ -19,6 +19,7 @@ using System.Timers;
using System.Windows.Forms;
using static AssetStudioGUI.Studio;
using Font = AssetStudio.Font;
using ImageFormat = AssetStudio.ImageFormat;
using PixelFormat = System.Drawing.Imaging.PixelFormat;
using Vector3 = OpenTK.Vector3;
using Vector4 = OpenTK.Vector4;
@@ -81,6 +82,11 @@ namespace AssetStudioGUI
private int nextGObject;
private List<TreeNode> treeSrcResults = new List<TreeNode>();
private string openDirectoryBackup = string.Empty;
private string saveDirectoryBackup = string.Empty;
private GUILogger logger;
[DllImport("gdi32.dll")]
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts);
@@ -96,7 +102,8 @@ namespace AssetStudioGUI
enablePreview.Checked = Properties.Settings.Default.enablePreview;
FMODinit();
Logger.Default = new GUILogger(StatusStripUpdate);
logger = new GUILogger(StatusStripUpdate);
Logger.Default = logger;
Progress.Default = new GUIProgress(SetProgressBarValue);
Studio.StatusStripUpdate = StatusStripUpdate;
}
@@ -115,7 +122,7 @@ namespace AssetStudioGUI
if (paths.Length > 0)
{
ResetForm();
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
if (paths.Length == 1 && Directory.Exists(paths[0]))
{
await Task.Run(() => assetsManager.LoadFolder(paths[0]));
@@ -124,16 +131,18 @@ namespace AssetStudioGUI
{
await Task.Run(() => assetsManager.LoadFiles(paths));
}
BuildAssetStructures();
}
}
private async void loadFile_Click(object sender, EventArgs e)
{
openFileDialog1.InitialDirectory = openDirectoryBackup;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
ResetForm();
openDirectoryBackup = Path.GetDirectoryName(openFileDialog1.FileNames[0]);
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
await Task.Run(() => assetsManager.LoadFiles(openFileDialog1.FileNames));
BuildAssetStructures();
}
@@ -142,9 +151,12 @@ namespace AssetStudioGUI
private async void loadFolder_Click(object sender, EventArgs e)
{
var openFolderDialog = new OpenFolderDialog();
openFolderDialog.InitialFolder = openDirectoryBackup;
if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
{
ResetForm();
openDirectoryBackup = openFolderDialog.Folder;
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
await Task.Run(() => assetsManager.LoadFolder(openFolderDialog.Folder));
BuildAssetStructures();
}
@@ -187,7 +199,7 @@ namespace AssetStudioGUI
{
if (assetsManager.assetsFileList.Count == 0)
{
StatusStripUpdate("No file was loaded.");
StatusStripUpdate("No Unity file can be loaded.");
return;
}
@@ -350,7 +362,7 @@ namespace AssetStudioGUI
var versionPath = Path.Combine(savePath, item.Group.Header);
Directory.CreateDirectory(versionPath);
var saveFile = $"{versionPath}\\{item.SubItems[1].Text} {item.Text}.txt";
var saveFile = $"{versionPath}{Path.DirectorySeparatorChar}{item.SubItems[1].Text} {item.Text}.txt";
File.WriteAllText(saveFile, item.ToString());
Progress.Report(++i, count);
@@ -741,9 +753,10 @@ namespace AssetStudioGUI
private void PreviewTexture2D(AssetItem assetItem, Texture2D m_Texture2D)
{
var bitmap = m_Texture2D.ConvertToBitmap(true);
if (bitmap != null)
var stream = m_Texture2D.ConvertToStream(ImageFormat.Png, true);
if (stream != null)
{
var bitmap = new Bitmap(stream);
assetItem.InfoText = $"Width: {m_Texture2D.m_Width}\nHeight: {m_Texture2D.m_Height}\nFormat: {m_Texture2D.m_TextureFormat}";
switch (m_Texture2D.m_TextureSettings.m_FilterMode)
{
@@ -1151,11 +1164,11 @@ namespace AssetStudioGUI
private void PreviewSprite(AssetItem assetItem, Sprite m_Sprite)
{
var bitmap = m_Sprite.GetImage();
if (bitmap != null)
var stream = m_Sprite.GetImage(ImageFormat.Png);
if (stream != null)
{
var bitmap = new Bitmap(stream);
assetItem.InfoText = $"Width: {bitmap.Width}\nHeight: {bitmap.Height}\n";
PreviewTexture(bitmap);
}
else
@@ -1305,9 +1318,11 @@ namespace AssetStudioGUI
if (animator != null)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{
var exportPath = saveFolderDialog.Folder + "\\Animator\\";
saveDirectoryBackup = saveFolderDialog.Folder;
var exportPath = Path.Combine(saveFolderDialog.Folder, "Animator") + Path.DirectorySeparatorChar;
ExportAnimatorWithAnimationClip(animator, animationList, exportPath);
}
}
@@ -1328,9 +1343,11 @@ namespace AssetStudioGUI
if (sceneTreeView.Nodes.Count > 0)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{
var exportPath = saveFolderDialog.Folder + "\\GameObject\\";
saveDirectoryBackup = saveFolderDialog.Folder;
var exportPath = Path.Combine(saveFolderDialog.Folder, "GameObject") + Path.DirectorySeparatorChar;
List<AssetItem> animationList = null;
if (animation)
{
@@ -1369,8 +1386,10 @@ namespace AssetStudioGUI
saveFileDialog.FileName = gameObjects[0].m_Name + " (merge).fbx";
saveFileDialog.AddExtension = false;
saveFileDialog.Filter = "Fbx file (*.fbx)|*.fbx";
saveFileDialog.InitialDirectory = saveDirectoryBackup;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
saveDirectoryBackup = Path.GetDirectoryName(saveFileDialog.FileName);
var exportPath = saveFileDialog.FileName;
List<AssetItem> animationList = null;
if (animation)
@@ -1461,8 +1480,10 @@ namespace AssetStudioGUI
if (sceneTreeView.Nodes.Count > 0)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{
saveDirectoryBackup = saveFolderDialog.Folder;
var savePath = saveFolderDialog.Folder + Path.DirectorySeparatorChar;
ExportSplitObjects(savePath, sceneTreeView.Nodes);
}
@@ -1521,10 +1542,11 @@ namespace AssetStudioGUI
if (exportableAssets.Count > 0)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{
timer.Stop();
saveDirectoryBackup = saveFolderDialog.Folder;
List<AssetItem> toExportAssets = null;
switch (type)
{
@@ -1554,10 +1576,11 @@ namespace AssetStudioGUI
if (exportableAssets.Count > 0)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{
timer.Stop();
saveDirectoryBackup = saveFolderDialog.Folder;
List<AssetItem> toExportAssets = null;
switch (type)
{
@@ -2016,6 +2039,11 @@ namespace AssetStudioGUI
}
}
private void toolStripMenuItem15_Click(object sender, EventArgs e)
{
logger.ShowErrorMessage = toolStripMenuItem15.Checked;
}
private void glControl1_MouseWheel(object sender, MouseEventArgs e)
{
if (glControl1.Visible)
@@ -29,9 +29,11 @@ namespace AssetStudioGUI
frm.GetOptions(out var options);
options |= NativeMethods.FOS_PICKFOLDERS | NativeMethods.FOS_FORCEFILESYSTEM | NativeMethods.FOS_NOVALIDATE | NativeMethods.FOS_NOTESTFILECREATE | NativeMethods.FOS_DONTADDTORECENT;
frm.SetOptions(options);
if (Title != null)
if (!string.IsNullOrEmpty(Title))
{
frm.SetTitle(Title);
if (InitialFolder != null)
}
if (!string.IsNullOrEmpty(InitialFolder))
{
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
if (NativeMethods.SHCreateItemFromParsingName(InitialFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK)
@@ -39,7 +41,7 @@ namespace AssetStudioGUI
frm.SetFolder(directoryShellItem);
}
}
if (DefaultFolder != null)
if (!string.IsNullOrEmpty(DefaultFolder))
{
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
if (NativeMethods.SHCreateItemFromParsingName(DefaultFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK)
+36 -17
View File
@@ -28,6 +28,7 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.OKbutton = new System.Windows.Forms.Button();
this.Cancel = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
@@ -43,6 +44,7 @@
this.tobmp = new System.Windows.Forms.RadioButton();
this.converttexture = 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();
this.exportAnimations = new System.Windows.Forms.CheckBox();
this.scaleFactor = new System.Windows.Forms.NumericUpDown();
@@ -59,6 +61,7 @@
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.groupBox1.SuspendLayout();
this.panel1.SuspendLayout();
this.groupBox2.SuspendLayout();
@@ -69,7 +72,7 @@
//
// OKbutton
//
this.OKbutton.Location = new System.Drawing.Point(308, 320);
this.OKbutton.Location = new System.Drawing.Point(318, 351);
this.OKbutton.Name = "OKbutton";
this.OKbutton.Size = new System.Drawing.Size(75, 21);
this.OKbutton.TabIndex = 6;
@@ -80,7 +83,7 @@
// Cancel
//
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.Cancel.Location = new System.Drawing.Point(389, 320);
this.Cancel.Location = new System.Drawing.Point(399, 351);
this.Cancel.Name = "Cancel";
this.Cancel.Size = new System.Drawing.Size(75, 21);
this.Cancel.TabIndex = 7;
@@ -100,7 +103,7 @@
this.groupBox1.Controls.Add(this.converttexture);
this.groupBox1.Location = new System.Drawing.Point(12, 12);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(232, 302);
this.groupBox1.Size = new System.Drawing.Size(232, 334);
this.groupBox1.TabIndex = 9;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Export";
@@ -182,7 +185,7 @@
this.totga.Name = "totga";
this.totga.Size = new System.Drawing.Size(41, 16);
this.totga.TabIndex = 2;
this.totga.Text = "TGA";
this.totga.Text = "Tga";
this.totga.UseVisualStyleBackColor = true;
//
// tojpg
@@ -192,7 +195,7 @@
this.tojpg.Name = "tojpg";
this.tojpg.Size = new System.Drawing.Size(47, 16);
this.tojpg.TabIndex = 4;
this.tojpg.Text = "JPEG";
this.tojpg.Text = "Jpeg";
this.tojpg.UseVisualStyleBackColor = true;
//
// topng
@@ -204,7 +207,7 @@
this.topng.Size = new System.Drawing.Size(41, 16);
this.topng.TabIndex = 3;
this.topng.TabStop = true;
this.topng.Text = "PNG";
this.topng.Text = "Png";
this.topng.UseVisualStyleBackColor = true;
//
// tobmp
@@ -214,7 +217,7 @@
this.tobmp.Name = "tobmp";
this.tobmp.Size = new System.Drawing.Size(41, 16);
this.tobmp.TabIndex = 2;
this.tobmp.Text = "BMP";
this.tobmp.Text = "Bmp";
this.tobmp.UseVisualStyleBackColor = true;
//
// converttexture
@@ -232,6 +235,7 @@
// groupBox2
//
this.groupBox2.AutoSize = true;
this.groupBox2.Controls.Add(this.exportAllUvsAsDiffuseMaps);
this.groupBox2.Controls.Add(this.exportBlendShape);
this.groupBox2.Controls.Add(this.exportAnimations);
this.groupBox2.Controls.Add(this.scaleFactor);
@@ -250,11 +254,24 @@
this.groupBox2.Controls.Add(this.eulerFilter);
this.groupBox2.Location = new System.Drawing.Point(250, 12);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(214, 302);
this.groupBox2.Size = new System.Drawing.Size(224, 334);
this.groupBox2.TabIndex = 11;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Fbx";
//
// exportAllUvsAsDiffuseMaps
//
this.exportAllUvsAsDiffuseMaps.AccessibleDescription = "";
this.exportAllUvsAsDiffuseMaps.AutoSize = true;
this.exportAllUvsAsDiffuseMaps.Location = new System.Drawing.Point(6, 171);
this.exportAllUvsAsDiffuseMaps.Name = "exportAllUvsAsDiffuseMaps";
this.exportAllUvsAsDiffuseMaps.Size = new System.Drawing.Size(204, 16);
this.exportAllUvsAsDiffuseMaps.TabIndex = 23;
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 " +
"map.");
this.exportAllUvsAsDiffuseMaps.UseVisualStyleBackColor = true;
//
// exportBlendShape
//
this.exportBlendShape.AutoSize = true;
@@ -287,7 +304,7 @@
0,
0,
131072});
this.scaleFactor.Location = new System.Drawing.Point(83, 202);
this.scaleFactor.Location = new System.Drawing.Point(83, 224);
this.scaleFactor.Name = "scaleFactor";
this.scaleFactor.Size = new System.Drawing.Size(60, 21);
this.scaleFactor.TabIndex = 20;
@@ -301,7 +318,7 @@
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(6, 204);
this.label5.Location = new System.Drawing.Point(6, 226);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(71, 12);
this.label5.TabIndex = 19;
@@ -314,7 +331,7 @@
this.fbxFormat.Items.AddRange(new object[] {
"Binary",
"Ascii"});
this.fbxFormat.Location = new System.Drawing.Point(77, 233);
this.fbxFormat.Location = new System.Drawing.Point(77, 254);
this.fbxFormat.Name = "fbxFormat";
this.fbxFormat.Size = new System.Drawing.Size(61, 20);
this.fbxFormat.TabIndex = 18;
@@ -322,7 +339,7 @@
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(6, 236);
this.label4.Location = new System.Drawing.Point(6, 258);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(59, 12);
this.label4.TabIndex = 17;
@@ -339,7 +356,7 @@
"7.3",
"7.4",
"7.5"});
this.fbxVersion.Location = new System.Drawing.Point(77, 262);
this.fbxVersion.Location = new System.Drawing.Point(77, 284);
this.fbxVersion.Name = "fbxVersion";
this.fbxVersion.Size = new System.Drawing.Size(47, 20);
this.fbxVersion.TabIndex = 16;
@@ -347,7 +364,7 @@
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(6, 265);
this.label3.Location = new System.Drawing.Point(6, 287);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(65, 12);
this.label3.TabIndex = 15;
@@ -355,7 +372,7 @@
//
// boneSize
//
this.boneSize.Location = new System.Drawing.Point(65, 175);
this.boneSize.Location = new System.Drawing.Point(65, 197);
this.boneSize.Name = "boneSize";
this.boneSize.Size = new System.Drawing.Size(46, 21);
this.boneSize.TabIndex = 11;
@@ -368,7 +385,7 @@
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(6, 177);
this.label2.Location = new System.Drawing.Point(6, 199);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(53, 12);
this.label2.TabIndex = 10;
@@ -453,7 +470,7 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.Cancel;
this.ClientSize = new System.Drawing.Size(477, 351);
this.ClientSize = new System.Drawing.Size(486, 384);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.Cancel);
@@ -512,5 +529,7 @@
private System.Windows.Forms.Label label6;
private System.Windows.Forms.CheckBox restoreExtensionName;
private System.Windows.Forms.CheckBox openAfterExport;
private System.Windows.Forms.CheckBox exportAllUvsAsDiffuseMaps;
private System.Windows.Forms.ToolTip exportUvsTooltip;
}
}
+8 -10
View File
@@ -1,11 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using AssetStudio;
using System;
using System.Windows.Forms;
namespace AssetStudioGUI
@@ -19,7 +13,7 @@ namespace AssetStudioGUI
restoreExtensionName.Checked = Properties.Settings.Default.restoreExtensionName;
converttexture.Checked = Properties.Settings.Default.convertTexture;
convertAudio.Checked = Properties.Settings.Default.convertAudio;
var str = Properties.Settings.Default.convertType;
var str = Properties.Settings.Default.convertType.ToString();
foreach (Control c in panel1.Controls)
{
if (c.Text == str)
@@ -36,10 +30,12 @@ namespace AssetStudioGUI
exportAnimations.Checked = Properties.Settings.Default.exportAnimations;
exportBlendShape.Checked = Properties.Settings.Default.exportBlendShape;
castToBone.Checked = Properties.Settings.Default.castToBone;
exportAllUvsAsDiffuseMaps.Checked = Properties.Settings.Default.exportAllUvsAsDiffuseMaps;
boneSize.Value = Properties.Settings.Default.boneSize;
scaleFactor.Value = Properties.Settings.Default.scaleFactor;
fbxVersion.SelectedIndex = Properties.Settings.Default.fbxVersion;
fbxFormat.SelectedIndex = Properties.Settings.Default.fbxFormat;
}
private void OKbutton_Click(object sender, EventArgs e)
@@ -52,7 +48,7 @@ namespace AssetStudioGUI
{
if (((RadioButton)c).Checked)
{
Properties.Settings.Default.convertType = c.Text;
Properties.Settings.Default.convertType = (ImageFormat)Enum.Parse(typeof(ImageFormat), c.Text);
break;
}
}
@@ -64,6 +60,7 @@ namespace AssetStudioGUI
Properties.Settings.Default.exportAnimations = exportAnimations.Checked;
Properties.Settings.Default.exportBlendShape = exportBlendShape.Checked;
Properties.Settings.Default.castToBone = castToBone.Checked;
Properties.Settings.Default.exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps.Checked;
Properties.Settings.Default.boneSize = boneSize.Value;
Properties.Settings.Default.scaleFactor = scaleFactor.Value;
Properties.Settings.Default.fbxVersion = fbxVersion.SelectedIndex;
@@ -78,5 +75,6 @@ namespace AssetStudioGUI
DialogResult = DialogResult.Cancel;
Close();
}
}
}
+3
View File
@@ -117,4 +117,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="exportUvsTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
+20 -68
View File
@@ -1,11 +1,9 @@
using System.Collections.Generic;
using System.Drawing.Imaging;
using AssetStudio;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using AssetStudio;
using Newtonsoft.Json;
using TGASharpLib;
namespace AssetStudioGUI
{
@@ -16,40 +14,17 @@ namespace AssetStudioGUI
var m_Texture2D = (Texture2D)item.Asset;
if (Properties.Settings.Default.convertTexture)
{
var bitmap = m_Texture2D.ConvertToBitmap(true);
if (bitmap == null)
var type = Properties.Settings.Default.convertType;
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
return false;
ImageFormat format = null;
var ext = Properties.Settings.Default.convertType;
bool tga = false;
switch (ext)
{
case "BMP":
format = ImageFormat.Bmp;
break;
case "PNG":
format = ImageFormat.Png;
break;
case "JPEG":
format = ImageFormat.Jpeg;
break;
case "TGA":
tga = true;
break;
}
if (!TryExportFile(exportPath, item, "." + ext.ToLower(), out var exportFullPath))
var stream = m_Texture2D.ConvertToStream(type, true);
if (stream == null)
return false;
if (tga)
using (stream)
{
var file = new TGA(bitmap);
file.Save(exportFullPath);
File.WriteAllBytes(exportFullPath, stream.ToArray());
return true;
}
else
{
bitmap.Save(exportFullPath, format);
}
bitmap.Dispose();
return true;
}
else
{
@@ -230,12 +205,11 @@ namespace AssetStudioGUI
public static bool ExportVideoClip(AssetItem item, string exportPath)
{
var m_VideoClip = (VideoClip)item.Asset;
var m_VideoData = m_VideoClip.m_VideoData.GetData();
if (m_VideoData != null && m_VideoData.Length != 0)
if (m_VideoClip.m_ExternalResources.m_Size > 0)
{
if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath))
return false;
File.WriteAllBytes(exportFullPath, m_VideoData);
m_VideoClip.m_VideoData.WriteData(exportFullPath);
return true;
}
return false;
@@ -252,40 +226,17 @@ namespace AssetStudioGUI
public static bool ExportSprite(AssetItem item, string exportPath)
{
ImageFormat format = null;
var type = Properties.Settings.Default.convertType;
bool tga = false;
switch (type)
{
case "BMP":
format = ImageFormat.Bmp;
break;
case "PNG":
format = ImageFormat.Png;
break;
case "JPEG":
format = ImageFormat.Jpeg;
break;
case "TGA":
tga = true;
break;
}
if (!TryExportFile(exportPath, item, "." + type.ToLower(), out var exportFullPath))
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
return false;
var bitmap = ((Sprite)item.Asset).GetImage();
if (bitmap != null)
var stream = ((Sprite)item.Asset).GetImage(type);
if (stream != null)
{
if (tga)
using (stream)
{
var file = new TGA(bitmap);
file.Save(exportFullPath);
File.WriteAllBytes(exportFullPath, stream.ToArray());
return true;
}
else
{
bitmap.Save(exportFullPath, format);
}
bitmap.Dispose();
return true;
}
return false;
}
@@ -359,11 +310,12 @@ namespace AssetStudioGUI
var exportBlendShape = Properties.Settings.Default.exportBlendShape;
var castToBone = Properties.Settings.Default.castToBone;
var boneSize = (int)Properties.Settings.Default.boneSize;
var exportAllUvsAsDiffuseMaps = Properties.Settings.Default.exportAllUvsAsDiffuseMaps;
var scaleFactor = (float)Properties.Settings.Default.scaleFactor;
var fbxVersion = Properties.Settings.Default.fbxVersion;
var fbxFormat = Properties.Settings.Default.fbxFormat;
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision,
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, scaleFactor, fbxVersion, fbxFormat == 1);
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, fbxVersion, fbxFormat == 1);
}
public static bool ExportDumpFile(AssetItem item, string exportPath)
+5 -1
View File
@@ -6,6 +6,7 @@ namespace AssetStudioGUI
{
class GUILogger : ILogger
{
public bool ShowErrorMessage = true;
private Action<string> action;
public GUILogger(Action<string> action)
@@ -18,7 +19,10 @@ namespace AssetStudioGUI
switch (loggerEvent)
{
case LoggerEvent.Error:
MessageBox.Show(message);
if (ShowErrorMessage)
{
MessageBox.Show(message);
}
break;
default:
action(message);
-25
View File
@@ -1,25 +0,0 @@
<configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
<!-- XQuartz compatibility (X11 on Mac) -->
<dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
<dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
<dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
<dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
<dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
<dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
</configuration>
+5 -2
View File
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -9,11 +9,14 @@ namespace AssetStudioGUI
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
#if !NETFRAMEWORK
Application.SetHighDpiMode(HighDpiMode.SystemAware);
#endif
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new AssetStudioGUIForm());
-36
View File
@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AssetStudioGUI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssetStudioGUI")]
[assembly: AssemblyCopyright("Copyright © Perfare 2018-2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("52b196fb-4c8a-499b-b877-1a0eb4f33ec0")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+2 -2
View File
@@ -47,8 +47,8 @@ namespace AssetStudioGUI.Properties {
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性
/// 重写当前线程的 CurrentUICulture 属性
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
+16 -4
View File
@@ -12,7 +12,7 @@ namespace AssetStudioGUI.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -109,10 +109,10 @@ namespace AssetStudioGUI.Properties {
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("PNG")]
public string convertType {
[global::System.Configuration.DefaultSettingValueAttribute("Png")]
public global::AssetStudio.ImageFormat convertType {
get {
return ((string)(this["convertType"]));
return ((global::AssetStudio.ImageFormat)(this["convertType"]));
}
set {
this["convertType"] = value;
@@ -262,5 +262,17 @@ namespace AssetStudioGUI.Properties {
this["restoreExtensionName"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool exportAllUvsAsDiffuseMaps {
get {
return ((bool)(this["exportAllUvsAsDiffuseMaps"]));
}
set {
this["exportAllUvsAsDiffuseMaps"] = value;
}
}
}
}
+5 -2
View File
@@ -23,8 +23,8 @@
<Setting Name="convertAudio" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="convertType" Type="System.String" Scope="User">
<Value Profile="(Default)">PNG</Value>
<Setting Name="convertType" Type="AssetStudio.ImageFormat" Scope="User">
<Value Profile="(Default)">Png</Value>
</Setting>
<Setting Name="eulerFilter" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
@@ -62,5 +62,8 @@
<Setting Name="restoreExtensionName" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="exportAllUvsAsDiffuseMaps" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings>
</SettingsFile>
+14 -14
View File
@@ -72,37 +72,37 @@ namespace AssetStudioGUI
public static int ExtractFile(string fileName, string savePath)
{
int extractedCount = 0;
var type = ImportHelper.CheckFileType(fileName, out var reader);
if (type == FileType.BundleFile)
extractedCount += ExtractBundleFile(fileName, reader, savePath);
else if (type == FileType.WebFile)
extractedCount += ExtractWebDataFile(fileName, reader, savePath);
var reader = new FileReader(fileName);
if (reader.FileType == FileType.BundleFile)
extractedCount += ExtractBundleFile(reader, savePath);
else if (reader.FileType == FileType.WebFile)
extractedCount += ExtractWebDataFile(reader, savePath);
else
reader.Dispose();
return extractedCount;
}
private static int ExtractBundleFile(string bundleFilePath, EndianBinaryReader reader, string savePath)
private static int ExtractBundleFile(FileReader reader, string savePath)
{
StatusStripUpdate($"Decompressing {Path.GetFileName(bundleFilePath)} ...");
var bundleFile = new BundleFile(reader, bundleFilePath);
StatusStripUpdate($"Decompressing {reader.FileName} ...");
var bundleFile = new BundleFile(reader);
reader.Dispose();
if (bundleFile.fileList.Length > 0)
{
var extractPath = Path.Combine(savePath, Path.GetFileName(bundleFilePath) + "_unpacked");
var extractPath = Path.Combine(savePath, reader.FileName + "_unpacked");
return ExtractStreamFile(extractPath, bundleFile.fileList);
}
return 0;
}
private static int ExtractWebDataFile(string webFilePath, EndianBinaryReader reader, string savePath)
private static int ExtractWebDataFile(FileReader reader, string savePath)
{
StatusStripUpdate($"Decompressing {Path.GetFileName(webFilePath)} ...");
StatusStripUpdate($"Decompressing {reader.FileName} ...");
var webFile = new WebFile(reader);
reader.Dispose();
if (webFile.fileList.Length > 0)
{
var extractPath = Path.Combine(savePath, Path.GetFileName(webFilePath) + "_unpacked");
var extractPath = Path.Combine(savePath, reader.FileName + "_unpacked");
return ExtractStreamFile(extractPath, webFile.fileList);
}
return 0;
@@ -531,13 +531,13 @@ namespace AssetStudioGUI
//处理非法文件名
var filename = FixFileName(j.Text);
//每个文件存放在单独的文件夹
var targetPath = $"{savePath}{filename}\\";
var targetPath = $"{savePath}{filename}{Path.DirectorySeparatorChar}";
//重名文件处理
for (int i = 1; ; i++)
{
if (Directory.Exists(targetPath))
{
targetPath = $"{savePath}{filename} ({i})\\";
targetPath = $"{savePath}{filename} ({i}){Path.DirectorySeparatorChar}";
}
else
{
-75
View File
@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="AssetStudioGUI.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<userSettings>
<AssetStudioGUI.Properties.Settings>
<setting name="displayAll" serializeAs="String">
<value>False</value>
</setting>
<setting name="enablePreview" serializeAs="String">
<value>True</value>
</setting>
<setting name="displayInfo" serializeAs="String">
<value>True</value>
</setting>
<setting name="openAfterExport" serializeAs="String">
<value>True</value>
</setting>
<setting name="assetGroupOption" serializeAs="String">
<value>0</value>
</setting>
<setting name="convertTexture" serializeAs="String">
<value>True</value>
</setting>
<setting name="convertAudio" serializeAs="String">
<value>True</value>
</setting>
<setting name="convertType" serializeAs="String">
<value>PNG</value>
</setting>
<setting name="eulerFilter" serializeAs="String">
<value>True</value>
</setting>
<setting name="filterPrecision" serializeAs="String">
<value>0.25</value>
</setting>
<setting name="exportAllNodes" serializeAs="String">
<value>True</value>
</setting>
<setting name="exportSkins" serializeAs="String">
<value>True</value>
</setting>
<setting name="exportAnimations" serializeAs="String">
<value>True</value>
</setting>
<setting name="boneSize" serializeAs="String">
<value>10</value>
</setting>
<setting name="fbxVersion" serializeAs="String">
<value>3</value>
</setting>
<setting name="fbxFormat" serializeAs="String">
<value>0</value>
</setting>
<setting name="scaleFactor" serializeAs="String">
<value>1</value>
</setting>
<setting name="exportBlendShape" serializeAs="String">
<value>True</value>
</setting>
<setting name="castToBone" serializeAs="String">
<value>False</value>
</setting>
<setting name="restoreExtensionName" serializeAs="String">
<value>True</value>
</setting>
</AssetStudioGUI.Properties.Settings>
</userSettings>
</configuration>
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" />
<package id="OpenTK" version="3.1.0" targetFramework="net472" />
<package id="OpenTK.GLControl" version="3.1.0" targetFramework="net472" />
</packages>
+6 -6
View File
@@ -15,18 +15,18 @@ namespace AssetStudio
var resolver = new MyAssemblyResolver();
var readerParameters = new ReaderParameters();
readerParameters.AssemblyResolver = resolver;
try
foreach (var file in files)
{
foreach (var file in files)
try
{
var assembly = AssemblyDefinition.ReadAssembly(file, readerParameters);
resolver.Register(assembly);
moduleDic.Add(assembly.MainModule.Name, assembly.MainModule);
}
}
catch
{
// ignored
catch
{
// ignored
}
}
Loaded = true;
}
+17 -102
View File
@@ -1,108 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{80AEC261-21EE-4E4F-A93B-7A744DC84888}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssetStudioUtility</RootNamespace>
<AssemblyName>AssetStudioUtility</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<Version>0.16.0.0</Version>
<AssemblyVersion>0.16.0.0</AssemblyVersion>
<FileVersion>0.16.0.0</FileVersion>
<Copyright>Copyright © Perfare 2018-2021</Copyright>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Unity.Cecil">
<HintPath>Libraries\Unity.Cecil.dll</HintPath>
</Reference>
<Reference Include="Unity.CecilTools">
<HintPath>Libraries\Unity.CecilTools.dll</HintPath>
</Reference>
<Reference Include="Unity.SerializationLogic">
<HintPath>Libraries\Unity.SerializationLogic.dll</HintPath>
</Reference>
<PackageReference Include="Mono.Cecil" Version="0.11.3" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta13" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyLoader.cs" />
<Compile Include="AudioClipConverter.cs" />
<Compile Include="CSspv\Disassembler.cs" />
<Compile Include="CSspv\EnumValuesExtensions.cs" />
<Compile Include="CSspv\Instruction.cs" />
<Compile Include="CSspv\Module.cs" />
<Compile Include="CSspv\OperandType.cs" />
<Compile Include="CSspv\ParsedInstruction.cs" />
<Compile Include="CSspv\Reader.cs" />
<Compile Include="CSspv\SpirV.Core.Grammar.cs" />
<Compile Include="CSspv\SpirV.Meta.cs" />
<Compile Include="CSspv\Types.cs" />
<Compile Include="FMOD Studio API\fmod.cs" />
<Compile Include="FMOD Studio API\fmod_dsp.cs" />
<Compile Include="FMOD Studio API\fmod_errors.cs" />
<Compile Include="ModelConverter.cs" />
<Compile Include="ModelExporter.cs" />
<Compile Include="MonoBehaviourConverter.cs" />
<Compile Include="SerializedTypeHelper.cs" />
<Compile Include="TGASharpLib.cs" />
<Compile Include="TypeDefinitionConverter.cs" />
<Compile Include="MyAssemblyResolver.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ShaderConverter.cs" />
<Compile Include="Smolv\OpData.cs" />
<Compile Include="Smolv\SmolvDecoder.cs" />
<Compile Include="Smolv\SpvOp.cs" />
<Compile Include="SpirVShaderConverter.cs" />
<Compile Include="SpriteHelper.cs" />
<Compile Include="Texture2DConverter.cs" />
<Compile Include="Texture2DExtensions.cs" />
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
<ProjectReference Include="..\AssetStudioFBXWrapper\AssetStudioFBXWrapper.csproj" />
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj" />
<ProjectReference Include="..\Texture2DDecoderWrapper\Texture2DDecoderWrapper.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj">
<Project>{40c796b5-88ce-4adc-acd6-2f4862b7f136}</Project>
<Name>AssetStudio.PInvoke</Name>
</ProjectReference>
<ProjectReference Include="..\AssetStudioFBXWrapper\AssetStudioFBXWrapper.csproj">
<Project>{bd76e63f-1517-47fa-8233-33e853a3acee}</Project>
<Name>AssetStudioFBXWrapper</Name>
</ProjectReference>
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
<Project>{7662f8c2-7bfd-442e-a948-a43b4f7eb06e}</Project>
<Name>AssetStudio</Name>
</ProjectReference>
<ProjectReference Include="..\Texture2DDecoderWrapper\Texture2DDecoderWrapper.csproj">
<Project>{2afce830-b463-49b3-a026-877e5eafc0a4}</Project>
<Name>Texture2DDecoderWrapper</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
+39
View File
@@ -0,0 +1,39 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.Formats.Tga;
using System.IO;
namespace AssetStudio
{
public static class ImageExtensions
{
public static MemoryStream ConvertToStream(this Image image, ImageFormat imageFormat)
{
var outputStream = new MemoryStream();
switch (imageFormat)
{
case ImageFormat.Jpeg:
image.SaveAsJpeg(outputStream);
break;
case ImageFormat.Png:
image.SaveAsPng(outputStream);
break;
case ImageFormat.Bmp:
image.Save(outputStream, new BmpEncoder
{
BitsPerPixel = BmpBitsPerPixel.Pixel32,
SupportTransparency = true
});
break;
case ImageFormat.Tga:
image.Save(outputStream, new TgaEncoder
{
BitsPerPixel = TgaBitsPerPixel.Pixel32,
Compression = TgaCompression.None
});
break;
}
return outputStream;
}
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace AssetStudio
{
public enum ImageFormat
{
Jpeg,
Png,
Bmp,
Tga
}
}
Binary file not shown.
Binary file not shown.
+108 -123
View File
@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using TGASharpLib;
namespace AssetStudio
{
@@ -17,15 +14,16 @@ namespace AssetStudio
public List<ImportedKeyframedAnimation> AnimationList { get; protected set; } = new List<ImportedKeyframedAnimation>();
public List<ImportedMorph> MorphList { get; protected set; } = new List<ImportedMorph>();
private string imageFormat;
private ImageFormat imageFormat;
private Avatar avatar;
private HashSet<AnimationClip> animationClipHashSet = new HashSet<AnimationClip>();
private Dictionary<AnimationClip, string> boundAnimationPathDic = new Dictionary<AnimationClip, string>();
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
private Dictionary<Texture2D, string> textureNameDictionary = new Dictionary<Texture2D, string>();
private Dictionary<Transform, ImportedFrame> transformDictionary = new Dictionary<Transform, ImportedFrame>();
Dictionary<uint, string> morphChannelNames = new Dictionary<uint, string>();
public ModelConverter(GameObject m_GameObject, string imageFormat, AnimationClip[] animationList = null)
public ModelConverter(GameObject m_GameObject, ImageFormat imageFormat, AnimationClip[] animationList = null)
{
this.imageFormat = imageFormat;
if (m_GameObject.m_Animator != null)
@@ -50,7 +48,7 @@ namespace AssetStudio
ConvertAnimations();
}
public ModelConverter(string rootName, List<GameObject> m_GameObjects, string imageFormat, AnimationClip[] animationList = null)
public ModelConverter(string rootName, List<GameObject> m_GameObjects, ImageFormat imageFormat, AnimationClip[] animationList = null)
{
this.imageFormat = imageFormat;
RootFrame = CreateFrame(rootName, Vector3.Zero, new Quaternion(0, 0, 0, 0), Vector3.One);
@@ -80,7 +78,7 @@ namespace AssetStudio
ConvertAnimations();
}
public ModelConverter(Animator m_Animator, string imageFormat, AnimationClip[] animationList = null)
public ModelConverter(Animator m_Animator, ImageFormat imageFormat, AnimationClip[] animationList = null)
{
this.imageFormat = imageFormat;
InitWithAnimator(m_Animator);
@@ -166,6 +164,10 @@ namespace AssetStudio
{
if (animation.TryGet(out var animationClip))
{
if (!boundAnimationPathDic.ContainsKey(animationClip))
{
boundAnimationPathDic.Add(animationClip, GetTransformPath(m_Transform));
}
animationClipHashSet.Add(animationClip);
}
}
@@ -319,79 +321,8 @@ namespace AssetStudio
}
ImportedMaterial iMat = ConvertMaterial(mat);
iSubmesh.Material = iMat.Name;
iSubmesh.VertexList = new List<ImportedVertex>((int)submesh.vertexCount);
for (var j = mesh.m_SubMeshes[i].firstVertex; j < mesh.m_SubMeshes[i].firstVertex + mesh.m_SubMeshes[i].vertexCount; j++)
{
var iVertex = new ImportedVertex();
//Vertices
int c = 3;
if (mesh.m_Vertices.Length == mesh.m_VertexCount * 4)
{
c = 4;
}
iVertex.Vertex = new Vector3(-mesh.m_Vertices[j * c], mesh.m_Vertices[j * c + 1], mesh.m_Vertices[j * c + 2]);
//Normals
if (iMesh.hasNormal)
{
if (mesh.m_Normals.Length == mesh.m_VertexCount * 3)
{
c = 3;
}
else if (mesh.m_Normals.Length == mesh.m_VertexCount * 4)
{
c = 4;
}
iVertex.Normal = new Vector3(-mesh.m_Normals[j * c], mesh.m_Normals[j * c + 1], mesh.m_Normals[j * c + 2]);
}
//UV
iVertex.UV = new float[8][];
for (int uv = 0; uv < 8; uv++)
{
if (iMesh.hasUV[uv])
{
var m_UV = mesh.GetUV(uv);
if (m_UV.Length == mesh.m_VertexCount * 2)
{
c = 2;
}
else if (m_UV.Length == mesh.m_VertexCount * 3)
{
c = 3;
}
iVertex.UV[uv] = new[] { m_UV[j * c], m_UV[j * c + 1] };
}
}
//Tangent
if (iMesh.hasTangent)
{
iVertex.Tangent = new Vector4(-mesh.m_Tangents[j * 4], mesh.m_Tangents[j * 4 + 1], mesh.m_Tangents[j * 4 + 2], mesh.m_Tangents[j * 4 + 3]);
}
//Colors
if (iMesh.hasColor)
{
if (mesh.m_Colors.Length == mesh.m_VertexCount * 3)
{
iVertex.Color = new Color(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f);
}
else
{
iVertex.Color = new Color(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]);
}
}
//BoneInfluence
if (mesh.m_Skin?.Length > 0)
{
var inf = mesh.m_Skin[j];
iVertex.BoneIndices = new int[4];
iVertex.Weights = new float[4];
for (var k = 0; k < 4; k++)
{
iVertex.BoneIndices[k] = inf.boneIndex[k];
iVertex.Weights[k] = inf.weight[k];
}
}
iSubmesh.VertexList.Add(iVertex);
}
iSubmesh.BaseVertex = (int)mesh.m_SubMeshes[i].firstVertex;
//Face
iSubmesh.FaceList = new List<ImportedFace>(numFaces);
var end = firstFace + numFaces;
@@ -405,9 +336,85 @@ namespace AssetStudio
iSubmesh.FaceList.Add(face);
}
firstFace = end;
iMesh.SubmeshList.Add(iSubmesh);
}
// Shared vertex list
iMesh.VertexList = new List<ImportedVertex>((int)mesh.m_VertexCount);
for (var j = 0; j < mesh.m_VertexCount; j++)
{
var iVertex = new ImportedVertex();
//Vertices
int c = 3;
if (mesh.m_Vertices.Length == mesh.m_VertexCount * 4)
{
c = 4;
}
iVertex.Vertex = new Vector3(-mesh.m_Vertices[j * c], mesh.m_Vertices[j * c + 1], mesh.m_Vertices[j * c + 2]);
//Normals
if (iMesh.hasNormal)
{
if (mesh.m_Normals.Length == mesh.m_VertexCount * 3)
{
c = 3;
}
else if (mesh.m_Normals.Length == mesh.m_VertexCount * 4)
{
c = 4;
}
iVertex.Normal = new Vector3(-mesh.m_Normals[j * c], mesh.m_Normals[j * c + 1], mesh.m_Normals[j * c + 2]);
}
//UV
iVertex.UV = new float[8][];
for (int uv = 0; uv < 8; uv++)
{
if (iMesh.hasUV[uv])
{
var m_UV = mesh.GetUV(uv);
if (m_UV.Length == mesh.m_VertexCount * 2)
{
c = 2;
}
else if (m_UV.Length == mesh.m_VertexCount * 3)
{
c = 3;
}
iVertex.UV[uv] = new[] { m_UV[j * c], m_UV[j * c + 1] };
}
}
//Tangent
if (iMesh.hasTangent)
{
iVertex.Tangent = new Vector4(-mesh.m_Tangents[j * 4], mesh.m_Tangents[j * 4 + 1], mesh.m_Tangents[j * 4 + 2], mesh.m_Tangents[j * 4 + 3]);
}
//Colors
if (iMesh.hasColor)
{
if (mesh.m_Colors.Length == mesh.m_VertexCount * 3)
{
iVertex.Color = new Color(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f);
}
else
{
iVertex.Color = new Color(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]);
}
}
//BoneInfluence
if (mesh.m_Skin?.Length > 0)
{
var inf = mesh.m_Skin[j];
iVertex.BoneIndices = new int[4];
iVertex.Weights = new float[4];
for (var k = 0; k < 4; k++)
{
iVertex.BoneIndices[k] = inf.boneIndex[k];
iVertex.Weights[k] = inf.weight[k];
}
}
iMesh.VertexList.Add(iVertex);
}
if (meshR is SkinnedMeshRenderer sMesh)
{
//Bone
@@ -524,7 +531,7 @@ namespace AssetStudio
keyframe.VertexList.Add(destVertex);
var morphVertex = mesh.m_Shapes.vertices[j];
destVertex.Index = morphVertex.index;
var sourceVertex = GetSourceVertex(iMesh.SubmeshList, (int)morphVertex.index);
var sourceVertex = iMesh.VertexList[(int)morphVertex.index];
destVertex.Vertex = new ImportedVertex();
var morphPos = morphVertex.vertex;
destVertex.Vertex.Vertex = sourceVertex.Vertex + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z);
@@ -598,6 +605,15 @@ namespace AssetStudio
return null;
}
private string FixBonePath(AnimationClip m_AnimationClip, string path)
{
if (boundAnimationPathDic.TryGetValue(m_AnimationClip, out var basePath))
{
path = basePath + "/" + path;
}
return FixBonePath(path);
}
private string FixBonePath(string path)
{
var frame = RootFrame.FindFrameByPath(path);
@@ -694,7 +710,7 @@ namespace AssetStudio
texture.Dest = dest;
var ext = $".{imageFormat.ToLower()}";
var ext = $".{imageFormat.ToString().ToLower()}";
if (textureNameDictionary.TryGetValue(m_Texture2D, out var textureName))
{
texture.Name = textureName;
@@ -740,30 +756,13 @@ namespace AssetStudio
return;
}
var bitmap = m_Texture2D.ConvertToBitmap(true);
if (bitmap != null)
var stream = m_Texture2D.ConvertToStream(imageFormat, true);
if (stream != null)
{
using (var stream = new MemoryStream())
using (stream)
{
switch (imageFormat)
{
case "BMP":
bitmap.Save(stream, ImageFormat.Bmp);
break;
case "PNG":
bitmap.Save(stream, ImageFormat.Png);
break;
case "JPEG":
bitmap.Save(stream, ImageFormat.Jpeg);
break;
case "TGA":
var tga = new TGA(bitmap);
tga.Save(stream);
break;
}
iTex = new ImportedTexture(stream, name);
TextureList.Add(iTex);
bitmap.Dispose();
}
}
}
@@ -794,7 +793,7 @@ namespace AssetStudio
{
foreach (var m_CompressedRotationCurve in animationClip.m_CompressedRotationCurves)
{
var track = iAnim.FindTrack(FixBonePath(m_CompressedRotationCurve.m_Path));
var track = iAnim.FindTrack(FixBonePath(animationClip, m_CompressedRotationCurve.m_Path));
var numKeys = m_CompressedRotationCurve.m_Times.m_NumItems;
var data = m_CompressedRotationCurve.m_Times.UnpackInts();
@@ -816,7 +815,7 @@ namespace AssetStudio
}
foreach (var m_RotationCurve in animationClip.m_RotationCurves)
{
var track = iAnim.FindTrack(FixBonePath(m_RotationCurve.path));
var track = iAnim.FindTrack(FixBonePath(animationClip, m_RotationCurve.path));
foreach (var m_Curve in m_RotationCurve.curve.m_Curve)
{
var value = Fbx.QuaternionToEuler(new Quaternion(m_Curve.value.X, -m_Curve.value.Y, -m_Curve.value.Z, m_Curve.value.W));
@@ -825,7 +824,7 @@ namespace AssetStudio
}
foreach (var m_PositionCurve in animationClip.m_PositionCurves)
{
var track = iAnim.FindTrack(FixBonePath(m_PositionCurve.path));
var track = iAnim.FindTrack(FixBonePath(animationClip, m_PositionCurve.path));
foreach (var m_Curve in m_PositionCurve.curve.m_Curve)
{
track.Translations.Add(new ImportedKeyframe<Vector3>(m_Curve.time, new Vector3(-m_Curve.value.X, m_Curve.value.Y, m_Curve.value.Z)));
@@ -833,7 +832,7 @@ namespace AssetStudio
}
foreach (var m_ScaleCurve in animationClip.m_ScaleCurves)
{
var track = iAnim.FindTrack(FixBonePath(m_ScaleCurve.path));
var track = iAnim.FindTrack(FixBonePath(animationClip, m_ScaleCurve.path));
foreach (var m_Curve in m_ScaleCurve.curve.m_Curve)
{
track.Scalings.Add(new ImportedKeyframe<Vector3>(m_Curve.time, new Vector3(m_Curve.value.X, m_Curve.value.Y, m_Curve.value.Z)));
@@ -843,7 +842,7 @@ namespace AssetStudio
{
foreach (var m_EulerCurve in animationClip.m_EulerCurves)
{
var track = iAnim.FindTrack(FixBonePath(m_EulerCurve.path));
var track = iAnim.FindTrack(FixBonePath(animationClip, m_EulerCurve.path));
foreach (var m_Curve in m_EulerCurve.curve.m_Curve)
{
track.Rotations.Add(new ImportedKeyframe<Vector3>(m_Curve.time, new Vector3(m_Curve.value.X, -m_Curve.value.Y, -m_Curve.value.Z)));
@@ -861,7 +860,7 @@ namespace AssetStudio
channelName = channelName.Substring(dotPos + 1);
}
var path = FixBonePath(m_FloatCurve.path);
var path = FixBonePath(animationClip, m_FloatCurve.path);
if (string.IsNullOrEmpty(path))
{
path = GetPathByChannelName(channelName);
@@ -880,7 +879,7 @@ namespace AssetStudio
{
var m_Clip = animationClip.m_MuscleClip.m_Clip;
var streamedFrames = m_Clip.m_StreamedClip.ReadData();
var m_ClipBindingConstant = animationClip.m_ClipBindingConstant;
var m_ClipBindingConstant = animationClip.m_ClipBindingConstant ?? m_Clip.ConvertValueArrayToGenericBinding();
for (int frameIndex = 1; frameIndex < streamedFrames.Count - 1; frameIndex++)
{
var frame = streamedFrames[frameIndex];
@@ -1014,20 +1013,6 @@ namespace AssetStudio
return boneName;
}
private static ImportedVertex GetSourceVertex(List<ImportedSubmesh> submeshList, int morphVertIndex)
{
foreach (var submesh in submeshList)
{
var vertList = submesh.VertexList;
if (morphVertIndex < vertList.Count)
{
return vertList[morphVertIndex];
}
morphVertIndex -= vertList.Count;
}
return null;
}
private void CreateBonePathHash(Transform m_Transform)
{
var name = GetTransformPathByFather(m_Transform);
+2 -2
View File
@@ -3,9 +3,9 @@
public static class ModelExporter
{
public static void ExportFbx(string path, IImported imported, bool eulerFilter, float filterPrecision,
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii)
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, float scaleFactor, int versionIndex, bool isAscii)
{
Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allNodes, skins, animation, blendShape, castToBone, boneSize, scaleFactor, versionIndex, isAscii);
Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allNodes, skins, animation, blendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, versionIndex, isAscii);
}
}
}
@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AssetStudioUtility")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssetStudioUtility")]
[assembly: AssemblyCopyright("Copyright © Perfare 2018-2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("80aec261-21ee-4e4f-a93b-7a744dc84888")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+331 -62
View File
@@ -1,4 +1,5 @@
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
@@ -229,7 +230,7 @@ namespace AssetStudio
sb.Append(ConvertSerializedTagMap(m_State.m_Tags, 2));
sb.Append(ConvertSerializedShaderRTBlendState(m_State.rtBlend));
sb.Append(ConvertSerializedShaderRTBlendState(m_State.rtBlend, m_State.rtSeparateBlend));
if (m_State.alphaToMask.val > 0f)
{
@@ -300,9 +301,111 @@ namespace AssetStudio
sb.Append($" Offset {m_State.offsetFactor.val}, {m_State.offsetUnits.val}\n");
}
//TODO Stencil
if (m_State.stencilRef.val != 0f ||
m_State.stencilReadMask.val != 255f ||
m_State.stencilWriteMask.val != 255f ||
m_State.stencilOp.pass.val != 0f ||
m_State.stencilOp.fail.val != 0f ||
m_State.stencilOp.zFail.val != 0f ||
m_State.stencilOp.comp.val != 8f ||
m_State.stencilOpFront.pass.val != 0f ||
m_State.stencilOpFront.fail.val != 0f ||
m_State.stencilOpFront.zFail.val != 0f ||
m_State.stencilOpFront.comp.val != 8f ||
m_State.stencilOpBack.pass.val != 0f ||
m_State.stencilOpBack.fail.val != 0f ||
m_State.stencilOpBack.zFail.val != 0f ||
m_State.stencilOpBack.comp.val != 8f)
{
sb.Append(" Stencil {\n");
if (m_State.stencilRef.val != 0f)
{
sb.Append($" Ref {m_State.stencilRef.val}\n");
}
if (m_State.stencilReadMask.val != 255f)
{
sb.Append($" ReadMask {m_State.stencilReadMask.val}\n");
}
if (m_State.stencilWriteMask.val != 255f)
{
sb.Append($" WriteMask {m_State.stencilWriteMask.val}\n");
}
if (m_State.stencilOp.pass.val != 0f ||
m_State.stencilOp.fail.val != 0f ||
m_State.stencilOp.zFail.val != 0f ||
m_State.stencilOp.comp.val != 8f)
{
sb.Append(ConvertSerializedStencilOp(m_State.stencilOp, ""));
}
if (m_State.stencilOpFront.pass.val != 0f ||
m_State.stencilOpFront.fail.val != 0f ||
m_State.stencilOpFront.zFail.val != 0f ||
m_State.stencilOpFront.comp.val != 8f)
{
sb.Append(ConvertSerializedStencilOp(m_State.stencilOpFront, "Front"));
}
if (m_State.stencilOpBack.pass.val != 0f ||
m_State.stencilOpBack.fail.val != 0f ||
m_State.stencilOpBack.zFail.val != 0f ||
m_State.stencilOpBack.comp.val != 8f)
{
sb.Append(ConvertSerializedStencilOp(m_State.stencilOpBack, "Back"));
}
sb.Append(" }\n");
}
//TODO Fog
if (m_State.fogMode != FogMode.kFogUnknown ||
m_State.fogColor.x.val != 0f ||
m_State.fogColor.y.val != 0f ||
m_State.fogColor.z.val != 0f ||
m_State.fogColor.w.val != 0f ||
m_State.fogDensity.val != 0f ||
m_State.fogStart.val != 0f ||
m_State.fogEnd.val != 0f)
{
sb.Append(" Fog {\n");
if (m_State.fogMode != FogMode.kFogUnknown)
{
sb.Append(" Mode ");
switch (m_State.fogMode)
{
case FogMode.kFogDisabled:
sb.Append("Off");
break;
case FogMode.kFogLinear:
sb.Append("Linear");
break;
case FogMode.kFogExp:
sb.Append("Exp");
break;
case FogMode.kFogExp2:
sb.Append("Exp2");
break;
}
sb.Append("\n");
}
if (m_State.fogColor.x.val != 0f ||
m_State.fogColor.y.val != 0f ||
m_State.fogColor.z.val != 0f ||
m_State.fogColor.w.val != 0f)
{
sb.AppendFormat(" Color ({0},{1},{2},{3})\n",
m_State.fogColor.x.val.ToString(CultureInfo.InvariantCulture),
m_State.fogColor.y.val.ToString(CultureInfo.InvariantCulture),
m_State.fogColor.z.val.ToString(CultureInfo.InvariantCulture),
m_State.fogColor.w.val.ToString(CultureInfo.InvariantCulture));
}
if (m_State.fogDensity.val != 0f)
{
sb.Append($" Density {m_State.fogDensity.val.ToString(CultureInfo.InvariantCulture)}\n");
}
if (m_State.fogStart.val != 0f ||
m_State.fogEnd.val != 0f)
{
sb.Append($" Range {m_State.fogStart.val.ToString(CultureInfo.InvariantCulture)}, {m_State.fogEnd.val.ToString(CultureInfo.InvariantCulture)}\n");
}
sb.Append(" }\n");
}
if (m_State.lighting)
{
@@ -314,27 +417,220 @@ namespace AssetStudio
return sb.ToString();
}
private static string ConvertSerializedShaderRTBlendState(SerializedShaderRTBlendState[] rtBlend)
private static string ConvertSerializedStencilOp(SerializedStencilOp stencilOp, string suffix)
{
//TODO Blend
var sb = new StringBuilder();
/*for (var i = 0; i < rtBlend.Length; i++)
sb.Append($" Comp{suffix} {ConvertStencilComp(stencilOp.comp)}\n");
sb.Append($" Pass{suffix} {ConvertStencilOp(stencilOp.pass)}\n");
sb.Append($" Fail{suffix} {ConvertStencilOp(stencilOp.fail)}\n");
sb.Append($" ZFail{suffix} {ConvertStencilOp(stencilOp.zFail)}\n");
return sb.ToString();
}
private static string ConvertStencilOp(SerializedShaderFloatValue op)
{
switch (op.val)
{
case 0f:
default:
return "Keep";
case 1f:
return "Zero";
case 2f:
return "Replace";
case 3f:
return "IncrSat";
case 4f:
return "DecrSat";
case 5f:
return "Invert";
case 6f:
return "IncrWrap";
case 7f:
return "DecrWrap";
}
}
private static string ConvertStencilComp(SerializedShaderFloatValue comp)
{
switch (comp.val)
{
case 0f:
return "Disabled";
case 1f:
return "Never";
case 2f:
return "Less";
case 3f:
return "Equal";
case 4f:
return "LEqual";
case 5f:
return "Greater";
case 6f:
return "NotEqual";
case 7f:
return "GEqual";
case 8f:
default:
return "Always";
}
}
private static string ConvertSerializedShaderRTBlendState(SerializedShaderRTBlendState[] rtBlend, bool rtSeparateBlend)
{
var sb = new StringBuilder();
for (var i = 0; i < rtBlend.Length; i++)
{
var blend = rtBlend[i];
if (!blend.srcBlend.val.Equals(1f) ||
!blend.destBlend.val.Equals(0f) ||
!blend.srcBlendAlpha.val.Equals(1f) ||
!blend.destBlendAlpha.val.Equals(0f))
if (blend.srcBlend.val != 1f ||
blend.destBlend.val != 0f ||
blend.srcBlendAlpha.val != 1f ||
blend.destBlendAlpha.val != 0f)
{
sb.Append(" Blend ");
sb.Append($"{i} ");
sb.Append('\n');
if (i != 0 || rtSeparateBlend)
{
sb.Append($"{i} ");
}
sb.Append($"{ConvertBlendFactor(blend.srcBlend)} {ConvertBlendFactor(blend.destBlend)}");
if (blend.srcBlendAlpha.val != 1f ||
blend.destBlendAlpha.val != 0f)
{
sb.Append($", {ConvertBlendFactor(blend.srcBlendAlpha)} {ConvertBlendFactor(blend.destBlendAlpha)}");
}
sb.Append("\n");
}
}*/
if (blend.blendOp.val != 0f ||
blend.blendOpAlpha.val != 0f)
{
sb.Append(" BlendOp ");
if (i != 0 || rtSeparateBlend)
{
sb.Append($"{i} ");
}
sb.Append(ConvertBlendOp(blend.blendOp));
if (blend.blendOpAlpha.val != 0f)
{
sb.Append($", {ConvertBlendOp(blend.blendOpAlpha)}");
}
sb.Append("\n");
}
var val = (int)blend.colMask.val;
if (val != 0xf)
{
sb.Append(" ColorMask ");
if (val == 0)
{
sb.Append(0);
}
else
{
if ((val & 0x2) != 0)
{
sb.Append("R");
}
if ((val & 0x4) != 0)
{
sb.Append("G");
}
if ((val & 0x8) != 0)
{
sb.Append("B");
}
if ((val & 0x1) != 0)
{
sb.Append("A");
}
}
sb.Append($" {i}\n");
}
}
return sb.ToString();
}
private static string ConvertBlendOp(SerializedShaderFloatValue op)
{
switch (op.val)
{
case 0f:
default:
return "Add";
case 1f:
return "Sub";
case 2f:
return "RevSub";
case 3f:
return "Min";
case 4f:
return "Max";
case 5f:
return "LogicalClear";
case 6f:
return "LogicalSet";
case 7f:
return "LogicalCopy";
case 8f:
return "LogicalCopyInverted";
case 9f:
return "LogicalNoop";
case 10f:
return "LogicalInvert";
case 11f:
return "LogicalAnd";
case 12f:
return "LogicalNand";
case 13f:
return "LogicalOr";
case 14f:
return "LogicalNor";
case 15f:
return "LogicalXor";
case 16f:
return "LogicalEquiv";
case 17f:
return "LogicalAndReverse";
case 18f:
return "LogicalAndInverted";
case 19f:
return "LogicalOrReverse";
case 20f:
return "LogicalOrInverted";
}
}
private static string ConvertBlendFactor(SerializedShaderFloatValue factor)
{
switch (factor.val)
{
case 0f:
return "Zero";
case 1f:
default:
return "One";
case 2f:
return "DstColor";
case 3f:
return "SrcColor";
case 4f:
return "OneMinusDstColor";
case 5f:
return "SrcAlpha";
case 6f:
return "OneMinusSrcColor";
case 7f:
return "DstAlpha";
case 8f:
return "OneMinusDstAlpha";
case 9f:
return "SrcAlphaSaturate";
case 10f:
return "OneMinusSrcAlpha";
}
}
private static string ConvertSerializedTagMap(SerializedTagMap m_Tags, int intent)
{
var sb = new StringBuilder();
@@ -443,12 +739,18 @@ namespace AssetStudio
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM20
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM30;
case ShaderCompilerPlatform.kShaderCompPlatformXbox360:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS;
case ShaderCompilerPlatform.kShaderCompPlatformPS3:
case ShaderCompilerPlatform.kShaderCompPlatformPSP2:
case ShaderCompilerPlatform.kShaderCompPlatformPS4:
case ShaderCompilerPlatform.kShaderCompPlatformXboxOne:
case ShaderCompilerPlatform.kShaderCompPlatformN3DS:
case ShaderCompilerPlatform.kShaderCompPlatformWiiU:
case ShaderCompilerPlatform.kShaderCompPlatformSwitch:
case ShaderCompilerPlatform.kShaderCompPlatformXboxOneD3D12:
case ShaderCompilerPlatform.kShaderCompPlatformGameCoreXboxOne:
case ShaderCompilerPlatform.kShaderCompPlatformGameCoreScarlett:
case ShaderCompilerPlatform.kShaderCompPlatformPS5:
case ShaderCompilerPlatform.kShaderCompPlatformPS5NGGC:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS
@@ -476,24 +778,6 @@ namespace AssetStudio
return programType == ShaderGpuProgramType.kShaderGpuProgramGLES31AEP
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLES31
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLES3;
case ShaderCompilerPlatform.kShaderCompPlatformPSP2:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS;
case ShaderCompilerPlatform.kShaderCompPlatformPS4:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS;
case ShaderCompilerPlatform.kShaderCompPlatformXboxOne:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS;
case ShaderCompilerPlatform.kShaderCompPlatformPSM: //Unknown
throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformMetal:
@@ -503,32 +787,8 @@ namespace AssetStudio
return programType == ShaderGpuProgramType.kShaderGpuProgramGLCore32
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLCore41
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLCore43;
case ShaderCompilerPlatform.kShaderCompPlatformN3DS:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS;
case ShaderCompilerPlatform.kShaderCompPlatformWiiU:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS;
case ShaderCompilerPlatform.kShaderCompPlatformVulkan:
return programType == ShaderGpuProgramType.kShaderGpuProgramSPIRV;
case ShaderCompilerPlatform.kShaderCompPlatformSwitch:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS;
case ShaderCompilerPlatform.kShaderCompPlatformXboxOneD3D12:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS;
default:
throw new NotSupportedException();
}
@@ -580,6 +840,14 @@ namespace AssetStudio
return "switch";
case ShaderCompilerPlatform.kShaderCompPlatformXboxOneD3D12:
return "xboxone_d3d12";
case ShaderCompilerPlatform.kShaderCompPlatformGameCoreXboxOne:
return "xboxone";
case ShaderCompilerPlatform.kShaderCompPlatformGameCoreScarlett:
return "xbox_scarlett";
case ShaderCompilerPlatform.kShaderCompPlatformPS5:
return "ps5";
case ShaderCompilerPlatform.kShaderCompPlatformPS5NGGC:
return "ps5_nggc";
default:
return "unknown";
}
@@ -647,7 +915,8 @@ namespace AssetStudio
//201609010 - Unity 5.6, 2017.1 & 2017.2
//201708220 - Unity 2017.3, Unity 2017.4 & Unity 2018.1
//201802150 - Unity 2018.2 & Unity 2018.3
//201806140 - Unity 2019.1~2020.1
//201806140 - Unity 2019.1~2021.1
//202012090 - Unity 2021.2
m_Version = reader.ReadInt32();
m_ProgramType = (ShaderGpuProgramType)reader.ReadInt32();
reader.BaseStream.Position += 12;
@@ -661,7 +930,7 @@ namespace AssetStudio
{
m_Keywords[i] = reader.ReadAlignedString();
}
if (m_Version >= 201806140)
if (m_Version >= 201806140 && m_Version < 202012090)
{
var m_LocalKeywordsSize = reader.ReadInt32();
m_LocalKeywords = new string[m_LocalKeywordsSize];
+61 -62
View File
@@ -1,15 +1,32 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
namespace AssetStudio
{
public static class SpriteHelper
{
public static Bitmap GetImage(this Sprite m_Sprite)
public static MemoryStream GetImage(this Sprite m_Sprite, ImageFormat imageFormat)
{
var image = GetImage(m_Sprite);
if (image != null)
{
using (image)
{
return image.ConvertToStream(imageFormat);
}
}
return null;
}
public static Image GetImage(this Sprite m_Sprite)
{
if (m_Sprite.m_SpriteAtlas != null && m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlas))
{
@@ -28,46 +45,37 @@ namespace AssetStudio
return null;
}
private static Bitmap CutImage(Texture2D m_Texture2D, Sprite m_Sprite, Rectf textureRect, Vector2 textureRectOffset, SpriteSettings settingsRaw)
private static Image CutImage(Texture2D m_Texture2D, Sprite m_Sprite, Rectf textureRect, Vector2 textureRectOffset, SpriteSettings settingsRaw)
{
var originalImage = m_Texture2D.ConvertToBitmap(false);
var originalImage = m_Texture2D.ConvertToImage(false);
if (originalImage != null)
{
using (originalImage)
{
//var spriteImage = originalImage.Clone(textureRect, PixelFormat.Format32bppArgb);
var rectf = new RectangleF(textureRect.x, textureRect.y, textureRect.width, textureRect.height);
var rect = Rectangle.Round(rectf);
if (rect.Width == 0)
{
rect.Width = 1;
}
if (rect.Height == 0)
{
rect.Height = 1;
}
var spriteImage = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
var destRect = new Rectangle(0, 0, rect.Width, rect.Height);
using (var graphic = Graphics.FromImage(spriteImage))
{
graphic.DrawImage(originalImage, destRect, rect, GraphicsUnit.Pixel);
}
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, m_Texture2D.m_Width);
rectBottom = Math.Min(rectBottom, m_Texture2D.m_Height);
var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY);
var spriteImage = originalImage.Clone(x => x.Crop(rect));
if (settingsRaw.packed == 1)
{
//RotateAndFlip
switch (settingsRaw.packingRotation)
{
case SpritePackingRotation.kSPRFlipHorizontal:
spriteImage.RotateFlip(RotateFlipType.RotateNoneFlipX);
spriteImage.Mutate(x => x.Flip(FlipMode.Horizontal));
break;
case SpritePackingRotation.kSPRFlipVertical:
spriteImage.RotateFlip(RotateFlipType.RotateNoneFlipY);
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
break;
case SpritePackingRotation.kSPRRotate180:
spriteImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
spriteImage.Mutate(x => x.Rotate(180));
break;
case SpritePackingRotation.kSPRRotate90:
spriteImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
spriteImage.Mutate(x => x.Rotate(270));
break;
}
}
@@ -78,41 +86,32 @@ namespace AssetStudio
try
{
var triangles = GetTriangles(m_Sprite.m_RD);
var points = triangles.Select(x => x.Select(y => new PointF(y.X, y.Y)).ToArray());
using (var path = new GraphicsPath())
var polygons = triangles.Select(x => new Polygon(new LinearLineSegment(x.Select(y => new PointF(y.X, y.Y)).ToArray()))).ToArray();
IPathCollection path = new PathCollection(polygons);
var matrix = Matrix3x2.CreateScale(m_Sprite.m_PixelsToUnits);
var version = m_Sprite.version;
if (version[0] < 5
|| (version[0] == 5 && version[1] < 4)
|| (version[0] == 5 && version[1] == 4 && version[2] <= 1)) //5.4.1p3 down
{
foreach (var p in points)
{
path.AddPolygon(p);
}
using (var matr = new Matrix())
{
var version = m_Sprite.version;
if (version[0] < 5
|| (version[0] == 5 && version[1] < 4)
|| (version[0] == 5 && version[1] == 4 && version[2] <= 1)) //5.4.1p3 down
{
matr.Translate(m_Sprite.m_Rect.width * 0.5f - textureRectOffset.X, m_Sprite.m_Rect.height * 0.5f - textureRectOffset.Y);
}
else
{
matr.Translate(m_Sprite.m_Rect.width * m_Sprite.m_Pivot.X - textureRectOffset.X, m_Sprite.m_Rect.height * m_Sprite.m_Pivot.Y - textureRectOffset.Y);
}
matr.Scale(m_Sprite.m_PixelsToUnits, m_Sprite.m_PixelsToUnits);
path.Transform(matr);
var bitmap = new Bitmap(rect.Width, rect.Height);
using (var graphic = Graphics.FromImage(bitmap))
{
using (var brush = new TextureBrush(spriteImage))
{
graphic.FillPath(brush, path);
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
spriteImage.Dispose();
return bitmap;
}
}
}
matrix *= Matrix3x2.CreateTranslation(m_Sprite.m_Rect.width * 0.5f - textureRectOffset.X, m_Sprite.m_Rect.height * 0.5f - textureRectOffset.Y);
}
else
{
matrix *= Matrix3x2.CreateTranslation(m_Sprite.m_Rect.width * m_Sprite.m_Pivot.X - textureRectOffset.X, m_Sprite.m_Rect.height * m_Sprite.m_Pivot.Y - textureRectOffset.Y);
}
path = path.Transform(matrix);
var options = new DrawingOptions
{
GraphicsOptions = new GraphicsOptions()
{
AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
}
};
var rectP = new RectangularPolygon(0, 0, rect.Width, rect.Height);
spriteImage.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, rectP.Clip(path)));
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
return spriteImage;
}
catch
{
@@ -121,7 +120,7 @@ namespace AssetStudio
}
//Rectangle
spriteImage.RotateFlip(RotateFlipType.RotateNoneFlipY);
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
return spriteImage;
}
}
File diff suppressed because it is too large Load Diff
-23
View File
@@ -1,8 +1,5 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using Texture2DDecoder;
namespace AssetStudio
@@ -28,26 +25,6 @@ namespace AssetStudio
platform = m_Texture2D.platform;
}
public Bitmap ConvertToBitmap(bool flip)
{
if (image_data == null || image_data.Length == 0)
return null;
var buff = DecodeTexture2D();
if (buff == null)
{
return null;
}
var bitmap = new Bitmap(m_Width, m_Height, PixelFormat.Format32bppArgb);
var bmpData = bitmap.LockBits(new Rectangle(0, 0, m_Width, m_Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
Marshal.Copy(buff, 0, bmpData.Scan0, buff.Length);
bitmap.UnlockBits(bmpData);
if (flip)
{
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
}
return bitmap;
}
public byte[] DecodeTexture2D()
{
byte[] bytes = null;
+29 -3
View File
@@ -1,13 +1,39 @@
using System.Drawing;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System.IO;
namespace AssetStudio
{
public static class Texture2DExtensions
{
public static Bitmap ConvertToBitmap(this Texture2D m_Texture2D, bool flip)
public static Image ConvertToImage(this Texture2D m_Texture2D, bool flip)
{
var converter = new Texture2DConverter(m_Texture2D);
return converter.ConvertToBitmap(flip);
var bytes = converter.DecodeTexture2D();
if (bytes != null && bytes.Length > 0)
{
var image = Image.LoadPixelData<Bgra32>(bytes, m_Texture2D.m_Width, m_Texture2D.m_Height);
if (flip)
{
image.Mutate(x => x.Flip(FlipMode.Vertical));
}
return image;
}
return null;
}
public static MemoryStream ConvertToStream(this Texture2D m_Texture2D, ImageFormat imageFormat, bool flip)
{
var image = ConvertToImage(m_Texture2D, flip);
if (image != null)
{
using (image)
{
return image.ConvertToStream(imageFormat);
}
}
return null;
}
}
}
+34 -53
View File
@@ -26,22 +26,22 @@ namespace AssetStudio
{
var nodes = new List<TypeTreeNode>();
Stack<TypeReference> baseTypes = new Stack<TypeReference>();
TypeReference baseType = TypeDef.BaseType;
while (!UnitySerializationLogic.IsNonSerialized(baseType))
var baseTypes = new Stack<TypeReference>();
var lastBaseType = TypeDef.BaseType;
while (!UnitySerializationLogic.IsNonSerialized(lastBaseType))
{
GenericInstanceType genericInstanceType = baseType as GenericInstanceType;
var genericInstanceType = lastBaseType as GenericInstanceType;
if (genericInstanceType != null)
{
TypeResolver.Add(genericInstanceType);
}
baseTypes.Push(baseType);
baseType = baseType.Resolve().BaseType;
baseTypes.Push(lastBaseType);
lastBaseType = lastBaseType.Resolve().BaseType;
}
while (baseTypes.Count > 0)
{
TypeReference typeReference = baseTypes.Pop();
TypeDefinition typeDefinition = typeReference.Resolve();
var typeReference = baseTypes.Pop();
var typeDefinition = typeReference.Resolve();
foreach (var fieldDefinition in typeDefinition.Fields.Where(WillUnitySerialize))
{
if (!IsHiddenByParentClass(baseTypes, fieldDefinition, TypeDef))
@@ -50,15 +50,15 @@ namespace AssetStudio
}
}
var genericInstanceType2 = typeReference as GenericInstanceType;
if (genericInstanceType2 != null)
var genericInstanceType = typeReference as GenericInstanceType;
if (genericInstanceType != null)
{
TypeResolver.Remove(genericInstanceType2);
TypeResolver.Remove(genericInstanceType);
}
}
foreach (FieldDefinition fieldDefinition2 in FilteredFields())
foreach (var field in FilteredFields())
{
nodes.AddRange(ProcessingFieldRef(fieldDefinition2));
nodes.AddRange(ProcessingFieldRef(field));
}
return nodes;
@@ -66,75 +66,60 @@ namespace AssetStudio
private bool WillUnitySerialize(FieldDefinition fieldDefinition)
{
bool result;
try
{
TypeReference typeReference = TypeResolver.Resolve(fieldDefinition.FieldType);
if (UnitySerializationLogic.ShouldNotTryToResolve(typeReference))
var resolvedFieldType = TypeResolver.Resolve(fieldDefinition.FieldType);
if (UnitySerializationLogic.ShouldNotTryToResolve(resolvedFieldType))
{
result = false;
return false;
}
else
if (!UnityEngineTypePredicates.IsUnityEngineObject(resolvedFieldType))
{
if (!UnityEngineTypePredicates.IsUnityEngineObject(typeReference))
if (resolvedFieldType.FullName == fieldDefinition.DeclaringType.FullName)
{
if (typeReference.FullName == fieldDefinition.DeclaringType.FullName)
{
return false;
}
return false;
}
result = UnitySerializationLogic.WillUnitySerialize(fieldDefinition, TypeResolver);
}
return UnitySerializationLogic.WillUnitySerialize(fieldDefinition, TypeResolver);
}
catch (Exception ex)
{
throw new Exception(string.Format("Exception while processing {0} {1}, error {2}", fieldDefinition.FieldType.FullName, fieldDefinition.FullName, ex.Message));
}
return result;
}
private static bool IsHiddenByParentClass(IEnumerable<TypeReference> parentTypes, FieldDefinition fieldDefinition, TypeDefinition processingType)
{
return processingType.Fields.Any((FieldDefinition f) => f.Name == fieldDefinition.Name) || parentTypes.Any((TypeReference t) => t.Resolve().Fields.Any((FieldDefinition f) => f.Name == fieldDefinition.Name));
return processingType.Fields.Any(f => f.Name == fieldDefinition.Name) || parentTypes.Any(t => t.Resolve().Fields.Any(f => f.Name == fieldDefinition.Name));
}
private IEnumerable<FieldDefinition> FilteredFields()
{
foreach (var f in TypeDef.Fields.Where(WillUnitySerialize))
{
if (UnitySerializationLogic.IsSupportedCollection(f.FieldType) || !f.FieldType.IsGenericInstance || UnitySerializationLogic.ShouldImplementIDeserializable(f.FieldType.Resolve()))
{
yield return f;
}
}
yield break;
return TypeDef.Fields.Where(WillUnitySerialize).Where(f =>
UnitySerializationLogic.IsSupportedCollection(f.FieldType) ||
!f.FieldType.IsGenericInstance ||
UnitySerializationLogic.ShouldImplementIDeserializable(f.FieldType.Resolve()));
}
private FieldReference ResolveGenericFieldReference(FieldReference fieldRef)
{
FieldReference field = new FieldReference(fieldRef.Name, fieldRef.FieldType, ResolveDeclaringType(fieldRef.DeclaringType));
var field = new FieldReference(fieldRef.Name, fieldRef.FieldType, ResolveDeclaringType(fieldRef.DeclaringType));
return TypeDef.Module.ImportReference(field);
}
private TypeReference ResolveDeclaringType(TypeReference declaringType)
{
TypeDefinition typeDefinition = declaringType.Resolve();
TypeReference result;
var typeDefinition = declaringType.Resolve();
if (typeDefinition == null || !typeDefinition.HasGenericParameters)
{
result = typeDefinition;
return typeDefinition;
}
else
var genericInstanceType = new GenericInstanceType(typeDefinition);
foreach (var genericParameter in typeDefinition.GenericParameters)
{
GenericInstanceType genericInstanceType = new GenericInstanceType(typeDefinition);
foreach (GenericParameter item in typeDefinition.GenericParameters)
{
genericInstanceType.GenericArguments.Add(item);
}
result = TypeResolver.Resolve(genericInstanceType);
genericInstanceType.GenericArguments.Add(genericParameter);
}
return result;
return TypeResolver.Resolve(genericInstanceType);
}
private List<TypeTreeNode> ProcessingFieldRef(FieldReference fieldDef)
@@ -155,7 +140,6 @@ namespace AssetStudio
private static bool RequiresAlignment(TypeReference typeRef)
{
bool result;
switch (typeRef.MetadataType)
{
case MetadataType.Boolean:
@@ -164,13 +148,10 @@ namespace AssetStudio
case MetadataType.Byte:
case MetadataType.Int16:
case MetadataType.UInt16:
result = true;
break;
return true;
default:
result = (UnitySerializationLogic.IsSupportedCollection(typeRef) && RequiresAlignment(CecilUtils.ElementTypeOfCollection(typeRef)));
break;
return UnitySerializationLogic.IsSupportedCollection(typeRef) && RequiresAlignment(CecilUtils.ElementTypeOfCollection(typeRef));
}
return result;
}
private static bool IsSystemString(TypeReference typeRef)
@@ -0,0 +1,65 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Unity.CecilTools.Extensions;
namespace Unity.CecilTools
{
public static class CecilUtils
{
public static MethodDefinition FindInTypeExplicitImplementationFor(MethodDefinition interfaceMethod, TypeDefinition typeDefinition)
{
return typeDefinition.Methods.SingleOrDefault(m => m.Overrides.Any(o => o.CheckedResolve().SameAs(interfaceMethod)));
}
public static IEnumerable<TypeDefinition> AllInterfacesImplementedBy(TypeDefinition typeDefinition)
{
return TypeAndBaseTypesOf(typeDefinition).SelectMany(t => t.Interfaces).Select(i => i.InterfaceType.CheckedResolve()).Distinct();
}
public static IEnumerable<TypeDefinition> TypeAndBaseTypesOf(TypeReference typeReference)
{
while (typeReference != null)
{
var typeDefinition = typeReference.CheckedResolve();
yield return typeDefinition;
typeReference = typeDefinition.BaseType;
}
}
public static IEnumerable<TypeDefinition> BaseTypesOf(TypeReference typeReference)
{
return TypeAndBaseTypesOf(typeReference).Skip(1);
}
public static bool IsGenericList(TypeReference type)
{
return type.Name == "List`1" && type.SafeNamespace() == "System.Collections.Generic";
}
public static bool IsGenericDictionary(TypeReference type)
{
if (type is GenericInstanceType)
type = ((GenericInstanceType)type).ElementType;
return type.Name == "Dictionary`2" && type.SafeNamespace() == "System.Collections.Generic";
}
public static TypeReference ElementTypeOfCollection(TypeReference type)
{
var at = type as ArrayType;
if (at != null)
return at.ElementType;
if (IsGenericList(type))
return ((GenericInstanceType)type).GenericArguments.Single();
throw new ArgumentException();
}
}
}
@@ -0,0 +1,21 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using System;
using Mono.Cecil;
namespace Unity.CecilTools
{
static public class ElementType
{
public static TypeReference For(TypeReference byRefType)
{
var refType = byRefType as TypeSpecification;
if (refType != null)
return refType.ElementType;
throw new ArgumentException(string.Format("TypeReference isn't a TypeSpecification {0} ", byRefType));
}
}
}
@@ -0,0 +1,50 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using Mono.Cecil;
namespace Unity.CecilTools.Extensions
{
static class MethodDefinitionExtensions
{
public static bool SameAs(this MethodDefinition self, MethodDefinition other)
{
// FIXME: should be able to compare MethodDefinition references directly
return self.FullName == other.FullName;
}
public static string PropertyName(this MethodDefinition self)
{
return self.Name.Substring(4);
}
public static bool IsConversionOperator(this MethodDefinition method)
{
if (!method.IsSpecialName)
return false;
return method.Name == "op_Implicit" || method.Name == "op_Explicit";
}
public static bool IsSimpleSetter(this MethodDefinition original)
{
return original.IsSetter && original.Parameters.Count == 1;
}
public static bool IsSimpleGetter(this MethodDefinition original)
{
return original.IsGetter && original.Parameters.Count == 0;
}
public static bool IsSimplePropertyAccessor(this MethodDefinition method)
{
return method.IsSimpleGetter() || method.IsSimpleSetter();
}
public static bool IsDefaultConstructor(MethodDefinition m)
{
return m.IsConstructor && !m.IsStatic && m.Parameters.Count == 0;
}
}
}
@@ -0,0 +1,36 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using System;
using Mono.Cecil;
namespace Unity.CecilTools.Extensions
{
public static class ResolutionExtensions
{
public static TypeDefinition CheckedResolve(this TypeReference type)
{
return Resolve(type, reference => reference.Resolve());
}
public static MethodDefinition CheckedResolve(this MethodReference method)
{
return Resolve(method, reference => reference.Resolve());
}
private static TDefinition Resolve<TReference, TDefinition>(TReference reference, Func<TReference, TDefinition> resolve)
where TReference : MemberReference
where TDefinition : class, IMemberDefinition
{
if (reference.Module == null)
throw new ResolutionException(reference);
var definition = resolve(reference);
if (definition == null)
throw new ResolutionException(reference);
return definition;
}
}
}
@@ -0,0 +1,47 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.Cecil;
namespace Unity.CecilTools.Extensions
{
public static class TypeDefinitionExtensions
{
public static bool IsSubclassOf(this TypeDefinition type, string baseTypeName)
{
var baseType = type.BaseType;
if (baseType == null)
return false;
if (baseType.FullName == baseTypeName)
return true;
var baseTypeDef = baseType.Resolve();
if (baseTypeDef == null)
return false;
return IsSubclassOf(baseTypeDef, baseTypeName);
}
public static bool IsSubclassOf(this TypeDefinition type, params string[] baseTypeNames)
{
var baseType = type.BaseType;
if (baseType == null)
return false;
for (int i = 0; i < baseTypeNames.Length; i++)
if (baseType.FullName == baseTypeNames[i])
return true;
var baseTypeDef = baseType.Resolve();
if (baseTypeDef == null)
return false;
return IsSubclassOf(baseTypeDef, baseTypeNames);
}
}
}
@@ -0,0 +1,53 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using Mono.Cecil;
namespace Unity.CecilTools.Extensions
{
public static class TypeReferenceExtensions
{
public static string SafeNamespace(this TypeReference type)
{
if (type.IsGenericInstance)
return ((GenericInstanceType)type).ElementType.SafeNamespace();
if (type.IsNested)
return type.DeclaringType.SafeNamespace();
return type.Namespace;
}
public static bool IsAssignableTo(this TypeReference typeRef, string typeName)
{
try
{
if (typeRef.IsGenericInstance)
return ElementType.For(typeRef).IsAssignableTo(typeName);
if (typeRef.FullName == typeName)
return true;
return typeRef.CheckedResolve().IsSubclassOf(typeName);
}
catch (AssemblyResolutionException) // If we can't resolve our typeref or one of its base types,
{ // let's assume it is not assignable to our target type
return false;
}
}
public static bool IsEnum(this TypeReference type)
{
return type.IsValueType && !type.IsPrimitive && type.CheckedResolve().IsEnum;
}
public static bool IsStruct(this TypeReference type)
{
return type.IsValueType && !type.IsPrimitive && !type.IsEnum() && !IsSystemDecimal(type);
}
private static bool IsSystemDecimal(TypeReference type)
{
return type.FullName == "System.Decimal";
}
}
}
@@ -0,0 +1,168 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using System.Collections.Generic;
using Unity.CecilTools.Extensions;
using Mono.Cecil;
namespace Unity.SerializationLogic
{
public class UnityEngineTypePredicates
{
private static readonly HashSet<string> TypesThatShouldHaveHadSerializableAttribute = new HashSet<string>
{
"Vector3",
"Vector2",
"Vector4",
"Rect",
"RectInt",
"Quaternion",
"Matrix4x4",
"Color",
"Color32",
"LayerMask",
"Bounds",
"BoundsInt",
"Vector3Int",
"Vector2Int",
};
private const string Gradient = "UnityEngine.Gradient";
private const string GUIStyle = "UnityEngine.GUIStyle";
private const string RectOffset = "UnityEngine.RectOffset";
protected const string UnityEngineObject = "UnityEngine.Object";
public const string MonoBehaviour = "UnityEngine.MonoBehaviour";
public const string ScriptableObject = "UnityEngine.ScriptableObject";
protected const string Matrix4x4 = "UnityEngine.Matrix4x4";
protected const string Color32 = "UnityEngine.Color32";
private const string SerializeFieldAttribute = "UnityEngine.SerializeField";
private const string SerializeReferenceAttribute = "UnityEngine.SerializeReference";
private static string[] serializableClasses = new[]
{
"UnityEngine.AnimationCurve",
"UnityEngine.Gradient",
"UnityEngine.GUIStyle",
"UnityEngine.RectOffset"
};
private static string[] serializableStructs = new[]
{
// NOTE: assumes all types here are NOT interfaces
"UnityEngine.Color32",
"UnityEngine.Matrix4x4",
"UnityEngine.Rendering.SphericalHarmonicsL2",
"UnityEngine.PropertyName",
};
public static bool IsMonoBehaviour(TypeReference type)
{
return IsMonoBehaviour(type.CheckedResolve());
}
private static bool IsMonoBehaviour(TypeDefinition typeDefinition)
{
return typeDefinition.IsSubclassOf(MonoBehaviour);
}
public static bool IsScriptableObject(TypeReference type)
{
return IsScriptableObject(type.CheckedResolve());
}
private static bool IsScriptableObject(TypeDefinition temp)
{
return temp.IsSubclassOf(ScriptableObject);
}
public static bool IsColor32(TypeReference type)
{
return type.IsAssignableTo(Color32);
}
//Do NOT remove these, cil2as still depends on these in 4.x
public static bool IsMatrix4x4(TypeReference type)
{
return type.IsAssignableTo(Matrix4x4);
}
public static bool IsGradient(TypeReference type)
{
return type.IsAssignableTo(Gradient);
}
public static bool IsGUIStyle(TypeReference type)
{
return type.IsAssignableTo(GUIStyle);
}
public static bool IsRectOffset(TypeReference type)
{
return type.IsAssignableTo(RectOffset);
}
public static bool IsSerializableUnityClass(TypeReference type)
{
foreach (var unityClasses in serializableClasses)
{
if (type.IsAssignableTo(unityClasses))
return true;
}
return false;
}
public static bool IsSerializableUnityStruct(TypeReference type)
{
foreach (var unityStruct in serializableStructs)
{
// NOTE: structs cannot inherit from structs, and can only inherit from interfaces
// since we know all types in serializableStructs are not interfaces,
// we can just do a direct comparison.
if (type.FullName == unityStruct)
return true;
}
if (type.FullName.IndexOf("UnityEngine.LazyLoadReference`1") == 0)
return true;
return false;
}
public static bool IsUnityEngineObject(TypeReference type)
{
//todo: somehow solve this elegantly. CheckedResolve() drops the [] of a type.
if (type.IsArray)
return false;
if (type.FullName == UnityEngineObject)
return true;
var typeDefinition = type.Resolve();
if (typeDefinition == null)
return false;
return typeDefinition.IsSubclassOf(UnityEngineObject);
}
public static bool ShouldHaveHadSerializableAttribute(TypeReference type)
{
return IsUnityEngineValueType(type);
}
public static bool IsUnityEngineValueType(TypeReference type)
{
return type.SafeNamespace() == "UnityEngine" && TypesThatShouldHaveHadSerializableAttribute.Contains(type.Name);
}
public static bool IsSerializeFieldAttribute(TypeReference attributeType)
{
return attributeType.FullName == SerializeFieldAttribute;
}
public static bool IsSerializeReferenceAttribute(TypeReference attributeType)
{
return attributeType.FullName == SerializeReferenceAttribute;
}
}
}
@@ -0,0 +1,612 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Mono.Collections.Generic;
using Unity.CecilTools;
using Unity.CecilTools.Extensions;
namespace Unity.SerializationLogic
{
internal class GenericInstanceHolder
{
public int Count;
public IGenericInstance GenericInstance;
}
public class TypeResolver
{
private readonly IGenericInstance _typeDefinitionContext;
private readonly IGenericInstance _methodDefinitionContext;
private readonly Dictionary<string, GenericInstanceHolder> _context = new Dictionary<string, GenericInstanceHolder>();
public TypeResolver()
{
}
public TypeResolver(IGenericInstance typeDefinitionContext)
{
_typeDefinitionContext = typeDefinitionContext;
}
public TypeResolver(GenericInstanceMethod methodDefinitionContext)
{
_methodDefinitionContext = methodDefinitionContext;
}
public TypeResolver(IGenericInstance typeDefinitionContext, IGenericInstance methodDefinitionContext)
{
_typeDefinitionContext = typeDefinitionContext;
_methodDefinitionContext = methodDefinitionContext;
}
public void Add(GenericInstanceType genericInstanceType)
{
Add(ElementTypeFor(genericInstanceType).FullName, genericInstanceType);
}
public void Remove(GenericInstanceType genericInstanceType)
{
Remove(genericInstanceType.ElementType.FullName, genericInstanceType);
}
public void Add(GenericInstanceMethod genericInstanceMethod)
{
Add(ElementTypeFor(genericInstanceMethod).FullName, genericInstanceMethod);
}
private static MemberReference ElementTypeFor(TypeSpecification genericInstanceType)
{
return genericInstanceType.ElementType;
}
private static MemberReference ElementTypeFor(MethodSpecification genericInstanceMethod)
{
return genericInstanceMethod.ElementMethod;
}
public void Remove(GenericInstanceMethod genericInstanceMethod)
{
Remove(genericInstanceMethod.ElementMethod.FullName, genericInstanceMethod);
}
public TypeReference Resolve(TypeReference typeReference)
{
var genericParameter = typeReference as GenericParameter;
if (genericParameter != null)
{
var resolved = ResolveGenericParameter(genericParameter);
if (genericParameter == resolved) // Resolving failed, return what we have.
return resolved;
return Resolve(resolved);
}
var arrayType = typeReference as ArrayType;
if (arrayType != null)
return new ArrayType(Resolve(arrayType.ElementType), arrayType.Rank);
var pointerType = typeReference as PointerType;
if (pointerType != null)
return new PointerType(Resolve(pointerType.ElementType));
var byReferenceType = typeReference as ByReferenceType;
if (byReferenceType != null)
return new ByReferenceType(Resolve(byReferenceType.ElementType));
var genericInstanceType = typeReference as GenericInstanceType;
if (genericInstanceType != null)
{
var newGenericInstanceType = new GenericInstanceType(Resolve(genericInstanceType.ElementType));
foreach (var genericArgument in genericInstanceType.GenericArguments)
newGenericInstanceType.GenericArguments.Add(Resolve(genericArgument));
return newGenericInstanceType;
}
var pinnedType = typeReference as PinnedType;
if (pinnedType != null)
return new PinnedType(Resolve(pinnedType.ElementType));
var reqModifierType = typeReference as RequiredModifierType;
if (reqModifierType != null)
return Resolve(reqModifierType.ElementType);
var optModifierType = typeReference as OptionalModifierType;
if (optModifierType != null)
return new OptionalModifierType(Resolve(optModifierType.ModifierType), Resolve(optModifierType.ElementType));
var sentinelType = typeReference as SentinelType;
if (sentinelType != null)
return new SentinelType(Resolve(sentinelType.ElementType));
var funcPtrType = typeReference as FunctionPointerType;
if (funcPtrType != null)
throw new NotSupportedException("Function pointer types are not supported by the SerializationWeaver");
if (typeReference is TypeSpecification)
throw new NotSupportedException();
return typeReference;
}
private TypeReference ResolveGenericParameter(GenericParameter genericParameter)
{
if (genericParameter.Owner == null)
throw new NotSupportedException();
var memberReference = genericParameter.Owner as MemberReference;
if (memberReference == null)
throw new NotSupportedException();
var key = memberReference.FullName;
if (!_context.ContainsKey(key))
{
if (genericParameter.Type == GenericParameterType.Type)
{
if (_typeDefinitionContext != null)
return _typeDefinitionContext.GenericArguments[genericParameter.Position];
return genericParameter;
}
if (_methodDefinitionContext != null)
return _methodDefinitionContext.GenericArguments[genericParameter.Position];
return genericParameter;
}
return GenericArgumentAt(key, genericParameter.Position);
}
private TypeReference GenericArgumentAt(string key, int position)
{
return _context[key].GenericInstance.GenericArguments[position];
}
private void Add(string key, IGenericInstance value)
{
GenericInstanceHolder oldValue;
if (_context.TryGetValue(key, out oldValue))
{
var memberReference = value as MemberReference;
if (memberReference == null)
throw new NotSupportedException();
var storedValue = (MemberReference)oldValue.GenericInstance;
if (storedValue.FullName != memberReference.FullName)
throw new ArgumentException("Duplicate key!", "key");
oldValue.Count++;
return;
}
_context.Add(key, new GenericInstanceHolder { Count = 1, GenericInstance = value });
}
private void Remove(string key, IGenericInstance value)
{
GenericInstanceHolder oldValue;
if (_context.TryGetValue(key, out oldValue))
{
var memberReference = value as MemberReference;
if (memberReference == null)
throw new NotSupportedException();
var storedValue = (MemberReference)oldValue.GenericInstance;
if (storedValue.FullName != memberReference.FullName)
throw new ArgumentException("Invalid value!", "value");
oldValue.Count--;
if (oldValue.Count == 0)
_context.Remove(key);
return;
}
throw new ArgumentException("Invalid key!", "key");
}
}
public static class UnitySerializationLogic
{
public static bool WillUnitySerialize(FieldDefinition fieldDefinition)
{
return WillUnitySerialize(fieldDefinition, new TypeResolver(null));
}
public static bool WillUnitySerialize(FieldDefinition fieldDefinition, TypeResolver typeResolver)
{
if (fieldDefinition == null)
return false;
//skip static, const and NotSerialized fields before even checking the type
if (fieldDefinition.IsStatic || IsConst(fieldDefinition) || fieldDefinition.IsNotSerialized || fieldDefinition.IsInitOnly)
return false;
// The field must have correct visibility/decoration to be serialized.
if (!fieldDefinition.IsPublic &&
!ShouldHaveHadAllFieldsPublic(fieldDefinition) &&
!HasSerializeFieldAttribute(fieldDefinition) &&
!HasSerializeReferenceAttribute(fieldDefinition))
return false;
// Don't try to resolve types that come from Windows assembly,
// as serialization weaver will fail to resolve that (due to it being in platform specific SDKs)
if (ShouldNotTryToResolve(fieldDefinition.FieldType))
return false;
if (IsFixedBuffer(fieldDefinition))
return true;
// Resolving types is more complex and slower than checking their names or attributes,
// thus keep those checks below
var typeReference = typeResolver.Resolve(fieldDefinition.FieldType);
//the type of the field must be serializable in the first place.
if (typeReference.MetadataType == MetadataType.String)
return true;
if (typeReference.IsValueType)
return IsValueTypeSerializable(typeReference);
if (typeReference is ArrayType || CecilUtils.IsGenericList(typeReference))
{
if (!HasSerializeReferenceAttribute(fieldDefinition))
return IsSupportedCollection(typeReference);
}
if (!IsReferenceTypeSerializable(typeReference) && !HasSerializeReferenceAttribute(fieldDefinition))
return false;
if (IsDelegate(typeReference))
return false;
return true;
}
private static bool IsDelegate(TypeReference typeReference)
{
return typeReference.IsAssignableTo("System.Delegate");
}
public static bool ShouldFieldBePPtrRemapped(FieldDefinition fieldDefinition)
{
return ShouldFieldBePPtrRemapped(fieldDefinition, new TypeResolver(null));
}
public static bool ShouldFieldBePPtrRemapped(FieldDefinition fieldDefinition, TypeResolver typeResolver)
{
if (!WillUnitySerialize(fieldDefinition, typeResolver))
return false;
return CanTypeContainUnityEngineObjectReference(typeResolver.Resolve(fieldDefinition.FieldType));
}
private static bool CanTypeContainUnityEngineObjectReference(TypeReference typeReference)
{
if (IsUnityEngineObject(typeReference))
return true;
if (typeReference.IsEnum())
return false;
if (IsSerializablePrimitive(typeReference))
return false;
if (IsSupportedCollection(typeReference))
return CanTypeContainUnityEngineObjectReference(CecilUtils.ElementTypeOfCollection(typeReference));
var definition = typeReference.Resolve();
if (definition == null)
return false;
return HasFieldsThatCanContainUnityEngineObjectReferences(definition, new TypeResolver(typeReference as GenericInstanceType));
}
private static bool HasFieldsThatCanContainUnityEngineObjectReferences(TypeDefinition definition, TypeResolver typeResolver)
{
return AllFieldsFor(definition, typeResolver).Where(kv => kv.Value.Resolve(kv.Key.FieldType).Resolve() != definition).Any(kv => CanFieldContainUnityEngineObjectReference(definition, kv.Key, kv.Value));
}
private static IEnumerable<KeyValuePair<FieldDefinition, TypeResolver>> AllFieldsFor(TypeDefinition definition, TypeResolver typeResolver)
{
var baseType = definition.BaseType;
if (baseType != null)
{
var genericBaseInstanceType = baseType as GenericInstanceType;
if (genericBaseInstanceType != null)
typeResolver.Add(genericBaseInstanceType);
foreach (var kv in AllFieldsFor(baseType.Resolve(), typeResolver))
yield return kv;
if (genericBaseInstanceType != null)
typeResolver.Remove(genericBaseInstanceType);
}
foreach (var fieldDefinition in definition.Fields)
yield return new KeyValuePair<FieldDefinition, TypeResolver>(fieldDefinition, typeResolver);
}
private static bool CanFieldContainUnityEngineObjectReference(TypeReference typeReference, FieldDefinition t, TypeResolver typeResolver)
{
if (typeResolver.Resolve(t.FieldType) == typeReference)
return false;
if (!WillUnitySerialize(t, typeResolver))
return false;
if (UnityEngineTypePredicates.IsUnityEngineValueType(typeReference))
return false;
return true;
}
private static bool IsConst(FieldDefinition fieldDefinition)
{
return fieldDefinition.IsLiteral && !fieldDefinition.IsInitOnly;
}
public static bool HasSerializeFieldAttribute(FieldDefinition field)
{
//return FieldAttributes(field).Any(UnityEngineTypePredicates.IsSerializeFieldAttribute);
foreach (var attribute in FieldAttributes(field))
if (UnityEngineTypePredicates.IsSerializeFieldAttribute(attribute))
return true;
return false;
}
public static bool HasSerializeReferenceAttribute(FieldDefinition field)
{
foreach (var attribute in FieldAttributes(field))
if (UnityEngineTypePredicates.IsSerializeReferenceAttribute(attribute))
return true;
return false;
}
private static IEnumerable<TypeReference> FieldAttributes(FieldDefinition field)
{
return field.CustomAttributes.Select(_ => _.AttributeType);
}
public static bool ShouldNotTryToResolve(TypeReference typeReference)
{
var typeReferenceScopeName = typeReference.Scope.Name;
if (typeReferenceScopeName == "Windows")
{
return true;
}
if (typeReferenceScopeName == "mscorlib")
{
var resolved = typeReference.Resolve();
return resolved == null;
}
try
{ // This will throw an exception if typereference thinks it's referencing a .dll,
// but actually there's .winmd file in the current directory. RRW will fix this
// at a later step, so we will not try to resolve this type. This is OK, as any
// type defined in a winmd cannot be serialized.
typeReference.Resolve();
}
catch
{
return true;
}
return false;
}
private static bool IsFieldTypeSerializable(TypeReference typeReference, FieldDefinition fieldDefinition)
{
return IsTypeSerializable(typeReference) || IsSupportedCollection(typeReference) || IsFixedBuffer(fieldDefinition);
}
private static bool IsValueTypeSerializable(TypeReference typeReference)
{
if (typeReference.IsPrimitive)
return IsSerializablePrimitive(typeReference);
return UnityEngineTypePredicates.IsSerializableUnityStruct(typeReference) ||
typeReference.IsEnum() ||
ShouldImplementIDeserializable(typeReference);
}
private static bool IsReferenceTypeSerializable(TypeReference typeReference)
{
if (typeReference.MetadataType == MetadataType.String)
return IsSerializablePrimitive(typeReference);
if (IsGenericDictionary(typeReference))
return false;
if (IsUnityEngineObject(typeReference) ||
ShouldImplementIDeserializable(typeReference) ||
UnityEngineTypePredicates.IsSerializableUnityClass(typeReference))
return true;
return false;
}
private static bool IsTypeSerializable(TypeReference typeReference)
{
if (typeReference.MetadataType == MetadataType.String)
return true;
if (typeReference.IsValueType)
return IsValueTypeSerializable(typeReference);
return IsReferenceTypeSerializable(typeReference);
}
private static bool IsGenericDictionary(TypeReference typeReference)
{
var current = typeReference;
if (current != null)
{
if (CecilUtils.IsGenericDictionary(current))
return true;
}
return false;
}
public static bool IsFixedBuffer(FieldDefinition fieldDefinition)
{
return GetFixedBufferAttribute(fieldDefinition) != null;
}
public static CustomAttribute GetFixedBufferAttribute(FieldDefinition fieldDefinition)
{
if (!fieldDefinition.HasCustomAttributes)
return null;
return fieldDefinition.CustomAttributes.SingleOrDefault(a => a.AttributeType.FullName == "System.Runtime.CompilerServices.FixedBufferAttribute");
}
public static int GetFixedBufferLength(FieldDefinition fieldDefinition)
{
var fixedBufferAttribute = GetFixedBufferAttribute(fieldDefinition);
if (fixedBufferAttribute == null)
throw new ArgumentException(string.Format("Field '{0}' is not a fixed buffer field.", fieldDefinition.FullName));
var size = (Int32)fixedBufferAttribute.ConstructorArguments[1].Value;
return size;
}
public static int PrimitiveTypeSize(TypeReference type)
{
switch (type.MetadataType)
{
case MetadataType.Boolean:
case MetadataType.Byte:
case MetadataType.SByte:
return 1;
case MetadataType.Char:
case MetadataType.Int16:
case MetadataType.UInt16:
return 2;
case MetadataType.Int32:
case MetadataType.UInt32:
case MetadataType.Single:
return 4;
case MetadataType.Int64:
case MetadataType.UInt64:
case MetadataType.Double:
return 8;
default:
throw new ArgumentException(string.Format("Unsupported {0}", type.MetadataType));
}
}
private static bool IsSerializablePrimitive(TypeReference typeReference)
{
switch (typeReference.MetadataType)
{
case MetadataType.SByte:
case MetadataType.Byte:
case MetadataType.Char:
case MetadataType.Int16:
case MetadataType.UInt16:
case MetadataType.Int64:
case MetadataType.UInt64:
case MetadataType.Int32:
case MetadataType.UInt32:
case MetadataType.Single:
case MetadataType.Double:
case MetadataType.Boolean:
case MetadataType.String:
return true;
}
return false;
}
public static bool IsSupportedCollection(TypeReference typeReference)
{
if (!(typeReference is ArrayType || CecilUtils.IsGenericList(typeReference)))
return false;
// We don't support arrays like byte[,] etc
if (typeReference.IsArray && ((ArrayType)typeReference).Rank > 1)
return false;
return IsTypeSerializable(CecilUtils.ElementTypeOfCollection(typeReference));
}
private static bool ShouldHaveHadAllFieldsPublic(FieldDefinition field)
{
return UnityEngineTypePredicates.IsUnityEngineValueType(field.DeclaringType);
}
private static bool IsUnityEngineObject(TypeReference typeReference)
{
return UnityEngineTypePredicates.IsUnityEngineObject(typeReference);
}
public static bool IsNonSerialized(TypeReference typeDeclaration)
{
if (typeDeclaration == null)
return true;
if (typeDeclaration.HasGenericParameters)
return true;
if (typeDeclaration.MetadataType == MetadataType.Object)
return true;
var fullName = typeDeclaration.FullName;
if (fullName.StartsWith("System.")) //can this be done better?
return true;
if (typeDeclaration.IsArray)
return true;
if (typeDeclaration.FullName == UnityEngineTypePredicates.MonoBehaviour)
return true;
if (typeDeclaration.FullName == UnityEngineTypePredicates.ScriptableObject)
return true;
if (typeDeclaration.IsEnum())
return true;
return false;
}
public static bool ShouldImplementIDeserializable(TypeReference typeDeclaration)
{
if (typeDeclaration.FullName == "UnityEngine.ExposedReference`1")
return true;
if (IsNonSerialized(typeDeclaration))
return false;
try
{
if (UnityEngineTypePredicates.ShouldHaveHadSerializableAttribute(typeDeclaration))
return true;
var resolvedTypeDeclaration = typeDeclaration.CheckedResolve();
if (resolvedTypeDeclaration.IsValueType)
{
return resolvedTypeDeclaration.IsSerializable && !resolvedTypeDeclaration.CustomAttributes.Any(a => a.AttributeType.FullName.Contains("System.Runtime.CompilerServices.CompilerGenerated"));
}
else
{
return (resolvedTypeDeclaration.IsSerializable && !resolvedTypeDeclaration.CustomAttributes.Any(a => a.AttributeType.FullName.Contains("System.Runtime.CompilerServices.CompilerGenerated"))) ||
resolvedTypeDeclaration.IsSubclassOf(UnityEngineTypePredicates.MonoBehaviour, UnityEngineTypePredicates.ScriptableObject);
}
}
catch (Exception)
{
return false;
}
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ AssetStudio is a tool for exploring, extracting and exporting assets and assetbu
## Features
* Support version:
* 2.5 - 2021.1
* 3.4 - 2021.2
* Support asset types:
* **Texture2D** : convert to png, tga, jpeg, bmp
* **Sprite** : crop Texture2D to png, tga, jpeg, bmp
@@ -1,19 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Texture2DDecoder")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Texture2DDecoder")]
[assembly: AssemblyCopyright("Copyright © Perfare 2020; Copyright © hozuki 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("2afce830-b463-49b3-a026-877e5eafc0a4")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -1,53 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2AFCE830-B463-49B3-A026-877E5EAFC0A4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Texture2DDecoder</RootNamespace>
<AssemblyName>Texture2DDecoderWrapper</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.16.0.0</Version>
<AssemblyVersion>0.16.0.0</AssemblyVersion>
<FileVersion>0.16.0.0</FileVersion>
<Copyright>Copyright © Perfare 2020-2021; Copyright © hozuki 2020</Copyright>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Include="T2DDll.cs" />
<Compile Include="TextureDecoder.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TextureDecoder.PInvoke.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj">
<Project>{40c796b5-88ce-4adc-acd6-2f4862b7f136}</Project>
<Name>AssetStudio.PInvoke</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>