Compare commits

...

78 Commits

Author SHA1 Message Date
Perfare d158e864b5 support 2022.1 2022-06-16 18:41:55 +08:00
Perfare b70b5196e3 update enum 2022-06-16 17:45:54 +08:00
Perfare 4f88841026 Fixed #962 2022-06-01 15:33:01 +08:00
Perfare dc9429feac minor improvements 2022-05-21 21:16:34 +08:00
Kanglai Qian a3c16ed3d6 avoid useless search for non exist files (#967) 2022-05-21 21:10:02 +08:00
Perfare 5b83eebdda support 2021.3 2022-05-21 17:38:40 +08:00
Perfare 1fcf7a4364 BundleFile fix 2022-05-21 17:24:54 +08:00
Perfare 973d50ce8b Fix type conversion bug 2022-05-21 05:46:44 +08:00
Perfare 50485a9bd3 update project file 2022-03-24 10:38:52 +08:00
Perfare dbb3d3fef7 revert 2022-03-24 09:47:36 +08:00
Perfare e1cfff63c3 minor fixes and improvements 2022-03-23 01:41:59 +08:00
Perfare 44514a4e10 Fixed #941 2022-03-22 22:54:49 +08:00
Perfare b1205808e2 Fix and improve Texture2D convert 2022-03-22 01:00:20 +08:00
Perfare 7d3a4a10fc Create build.yml 2022-03-20 02:36:32 +08:00
Perfare b909857820 Fixed #924 2022-03-19 08:06:03 +08:00
Perfare b674e66407 Fixed #929 2022-03-19 07:48:39 +08:00
Perfare d7dcd3f405 improved Sprite export
Fixed #944
Fixed #923
2022-03-19 07:43:53 +08:00
Perfare 44145e0b9c using IProgress 2022-03-19 06:40:51 +08:00
Perfare d4e21f824c Fixed #919 2022-02-17 01:07:24 +08:00
Rudolf Kolbe e7a4604a65 fix apk loading issues (#913)
* fix apk loading issues

Someone contacted me some days ago and notified me that some problems showed up with my APK loading implementation.
Namely:

file reference registration (importFilesHash) was missing
split files weren't handled
external resource files weren't registered
This pr fixes those problems.

* revert weird changes

* fix missing }

* fix formatting

* use entry.FullName for the basePath instead of entry.Name
2022-02-15 11:19:50 +08:00
Rudolf Kolbe 8d193a63cd Zip (including APK) Loading (#902)
* load ZipFile

makes it possible to directly load apk files

* use LoadFile for recursive zip opening

* set System.IO.Compression version

* keep identical format in AssetStudio.csproj

* try/catch the loading of each zip entry

* remove extra new line in FileReader.cs

* apply requested changes
2021-12-27 15:59:18 +08:00
brianpow e61a317185 use FullPath instead of FileName for easier identification of broken file (#900)
* use FullPath instead of FileName for easier identification of broken file.

* use FullPath instead of FileName for easier identification of broken file
2021-12-24 13:23:09 +08:00
scriptkitz 0e1a886e0b 修正UV导出计算错误问题。 (#891) 2021-12-11 15:48:54 +08:00
Perfare 97b5f51f3a Fix build 2021-12-09 20:23:25 +08:00
Perfare 7295feda72 Update README.md 2021-12-09 19:16:13 +08:00
Perfare fe95c91759 Add net6.0 target framework 2021-12-09 19:00:59 +08:00
Perfare d220315d9b Add detailed export progress in the status bar 2021-12-09 18:08:56 +08:00
Perfare a94caa5e34 Update project 2021-12-09 17:21:44 +08:00
Perfare 3660b4ed67 Some improvements 2021-12-09 17:13:21 +08:00
Perfare 3370f93037 Fixed bug 2021-12-06 17:37:59 +08:00
Perfare 80653711cd Performance improvement 2021-12-06 13:36:22 +08:00
Perfare 88c5804586 Fixed #886 2021-12-04 09:23:41 +08:00
Perfare e501940f03 Use a better way to crop Sprite 2021-12-04 08:44:33 +08:00
Perfare d4060cde6d Fixed bug 2021-12-04 02:05:35 +08:00
Perfare 582a779441 Update project file 2021-12-03 19:46:20 +08:00
Perfare 5fa4934787 Add net5.0 target framework 2021-12-03 17:21:24 +08:00
Perfare 18277fbea8 fixed bug 2021-12-03 17:05:06 +08:00
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
Perfare ab98585b6a Fix Shader reading. Close #720 2021-05-29 05:11:05 +08:00
Perfare 075d53a455 small improvement 2021-05-28 23:19:31 +08:00
Perfare 432116d834 Improve SerializedFile reading. 2021-05-28 22:23:07 +08:00
Perfare caa45216ef fix compilation error 2021-05-28 22:16:50 +08:00
Perfare c9394cd957 Fixed #734 2021-05-28 03:49:46 +08:00
Perfare 46c0e8ffe1 Improve stream file processing 2021-05-28 03:43:32 +08:00
Perfare d14c232015 Improve the error message 2021-05-28 03:27:50 +08:00
Perfare 4002bdecb8 Update README.md 2021-05-27 03:55:37 +08:00
StarHeart 17259e00c7 correct grammar (#749) 2021-05-27 03:49:40 +08:00
Perfare 44b02b92d8 fix lzma decompression 2021-05-27 03:46:15 +08:00
108 changed files with 4433 additions and 9493 deletions
+57
View File
@@ -0,0 +1,57 @@
name: AssetStudioBuild
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: microsoft/setup-msbuild@v1.1
- name: Download FBX SDK
run: |
md fbx
cd fbx
Invoke-WebRequest "https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/2020-2-1/fbx202021_fbxsdk_vs2019_win.exe" -OutFile "fbxsdk.exe"
Start-Process -FilePath "fbxsdk.exe" /S -Wait
Invoke-WebRequest "https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/2020-2-1/fbx202021_fbxsdk_vs2019_pdbs.exe" -OutFile "fbxpdb.exe"
Start-Process -FilePath "fbxpdb.exe" /S -Wait
cd ..
- name: Nuget Restore
run: nuget restore
- name: Build .Net472
run: msbuild /p:Configuration=Release /p:TargetFramework=net472 /verbosity:minimal
- name: Build .Net5
run: msbuild /t:AssetStudioGUI:publish /p:Configuration=Release /p:TargetFramework=net5.0-windows /p:SelfContained=false /verbosity:minimal
- name: Build .Net6
run: msbuild /t:AssetStudioGUI:publish /p:Configuration=Release /p:TargetFramework=net6.0-windows /p:SelfContained=false /verbosity:minimal
- name: Upload .Net472 Artifact
uses: actions/upload-artifact@v2
with:
name: AssetStudio.net472
path: AssetStudioGUI/bin/Release/net472
- name: Upload .Net5 Artifact
uses: actions/upload-artifact@v2
with:
name: AssetStudio.net5
path: AssetStudioGUI/bin/Release/net5.0-windows/publish
- name: Upload .Net6 Artifact
uses: actions/upload-artifact@v2
with:
name: AssetStudio.net6
path: AssetStudioGUI/bin/Release/net6.0-windows/publish
+10 -48
View File
@@ -1,51 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<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> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFrameworks>net472;netstandard2.0;net5.0;net6.0</TargetFrameworks>
<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>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <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-2022; Copyright © hozuki 2020</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> </Project>
<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>
@@ -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 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 16
VisualStudioVersion = 16.0.29920.165 VisualStudioVersion = 16.0.31410.357
MinimumVisualStudioVersion = 10.0.40219.1 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 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 EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioFBXWrapper", "AssetStudioFBXWrapper\AssetStudioFBXWrapper.csproj", "{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}"
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}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027} = {11EA25A3-ED68-40EE-A9D0-7FDE3B583027} {11EA25A3-ED68-40EE-A9D0-7FDE3B583027} = {11EA25A3-ED68-40EE-A9D0-7FDE3B583027}
EndProjectSection EndProjectSection
EndProject 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 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 ProjectSection(ProjectDependencies) = postProject
{29356642-C46E-4144-83D8-22DC09D0D7FD} = {29356642-C46E-4144-83D8-22DC09D0D7FD} {29356642-C46E-4144-83D8-22DC09D0D7FD} = {29356642-C46E-4144-83D8-22DC09D0D7FD}
EndProjectSection EndProjectSection
EndProject 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 EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -35,42 +35,78 @@ Global
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|Any CPU.Build.0 = Debug|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.ActiveCfg = Debug|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x64.ActiveCfg = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.Build.0 = Debug|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x64.Build.0 = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.ActiveCfg = Debug|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x86.ActiveCfg = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.Build.0 = Debug|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x86.Build.0 = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|Any CPU.ActiveCfg = Release|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|Any CPU.Build.0 = Release|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|Any CPU.Build.0 = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.ActiveCfg = Release|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x64.ActiveCfg = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.Build.0 = Release|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x64.Build.0 = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.ActiveCfg = Release|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x86.ActiveCfg = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.Build.0 = Release|Any CPU {422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x86.Build.0 = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|Any CPU.Build.0 = Debug|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.ActiveCfg = Debug|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x64.ActiveCfg = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.Build.0 = Debug|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x64.Build.0 = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.ActiveCfg = Debug|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x86.ActiveCfg = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.Build.0 = Debug|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x86.Build.0 = Debug|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|Any CPU.ActiveCfg = Release|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|Any CPU.Build.0 = Release|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Release|Any CPU.Build.0 = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.ActiveCfg = Release|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x64.ActiveCfg = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.Build.0 = Release|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x64.Build.0 = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.ActiveCfg = Release|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x86.ActiveCfg = Release|Any CPU
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.Build.0 = Release|Any CPU {0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x86.Build.0 = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|Any CPU.Build.0 = Debug|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.ActiveCfg = Debug|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x64.ActiveCfg = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.Build.0 = Debug|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x64.Build.0 = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.ActiveCfg = Debug|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x86.ActiveCfg = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.Build.0 = Debug|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x86.Build.0 = Debug|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|Any CPU.ActiveCfg = Release|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|Any CPU.Build.0 = Release|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|Any CPU.Build.0 = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.ActiveCfg = Release|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x64.ActiveCfg = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.Build.0 = Release|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x64.Build.0 = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.ActiveCfg = Release|Any CPU {E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x86.ActiveCfg = Release|Any CPU
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.Build.0 = 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.ActiveCfg = Debug|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|Any CPU.Build.0 = Debug|Win32 {11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|Any CPU.Build.0 = Debug|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x64.ActiveCfg = Debug|x64 {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|x64.Build.0 = Release|x64
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x86.ActiveCfg = Release|Win32 {11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x86.ActiveCfg = Release|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x86.Build.0 = 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.ActiveCfg = Debug|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|Any CPU.Build.0 = Debug|Win32 {29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|Any CPU.Build.0 = Debug|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x64.ActiveCfg = Debug|x64 {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|x64.Build.0 = Release|x64
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x86.ActiveCfg = Release|Win32 {29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x86.ActiveCfg = Release|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x86.Build.0 = 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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F8734F96-97B6-40CA-B791-6D5467F2F713} SolutionGuid = {3C074481-9CDD-4780-B9F6-57BBC5092EA2}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal
+18 -143
View File
@@ -1,147 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<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> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFrameworks>net472;netstandard2.0;net5.0;net6.0</TargetFrameworks>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Version>0.16.0.0</Version>
<ProjectGuid>{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}</ProjectGuid> <AssemblyVersion>0.16.0.0</AssemblyVersion>
<OutputType>Library</OutputType> <FileVersion>0.16.0.0</FileVersion>
<AppDesignerFolder>Properties</AppDesignerFolder> <Copyright>Copyright © Perfare 2018-2022</Copyright>
<RootNamespace>AssetStudio</RootNamespace> <DebugType>embedded</DebugType>
<AssemblyName>AssetStudio</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <ItemGroup Condition=" '$(TargetFramework)' != 'net472' ">
<DebugType>full</DebugType> <PackageReference Include="K4os.Compression.LZ4" Version="1.2.16" />
<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>
<ItemGroup>
<Compile Include="7zip\Common\CommandLineParser.cs" /> <ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<Compile Include="7zip\Common\CRC.cs" /> <PackageReference Include="System.Memory" Version="4.5.4" />
<Compile Include="7zip\Common\InBuffer.cs" /> <PackageReference Include="System.IO.Compression" Version="4.0.0" />
<Compile Include="7zip\Common\OutBuffer.cs" /> <PackageReference Include="K4os.Compression.LZ4" Version="1.1.11" />
<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="SerializedFileHeader.cs" />
<Compile Include="SerializedType.cs" />
<Compile Include="SevenZipHelper.cs" />
<Compile Include="StreamFile.cs" />
<Compile Include="TypeTreeHelper.cs" />
<Compile Include="TypeTreeNode.cs" />
<Compile Include="WebFile.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>
+210 -60
View File
@@ -1,24 +1,29 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Text;
using static AssetStudio.ImportHelper; using static AssetStudio.ImportHelper;
namespace AssetStudio namespace AssetStudio
{ {
public class AssetsManager public class AssetsManager
{ {
public string SpecifyUnityVersion;
public List<SerializedFile> assetsFileList = new List<SerializedFile>(); public List<SerializedFile> assetsFileList = new List<SerializedFile>();
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
internal Dictionary<string, BinaryReader> resourceFileReaders = new Dictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase); internal Dictionary<string, BinaryReader> resourceFileReaders = new Dictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
private List<string> importFiles = new List<string>(); private List<string> importFiles = new List<string>();
private HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
public void LoadFiles(params string[] files) public void LoadFiles(params string[] files)
{ {
var path = Path.GetDirectoryName(files[0]); var path = Path.GetDirectoryName(Path.GetFullPath(files[0]));
MergeSplitAssets(path); MergeSplitAssets(path);
var toReadFile = ProcessingSplitFiles(files.ToList()); var toReadFile = ProcessingSplitFiles(files.ToList());
Load(toReadFile); Load(toReadFile);
@@ -50,6 +55,7 @@ namespace AssetStudio
importFiles.Clear(); importFiles.Clear();
importFilesHash.Clear(); importFilesHash.Clear();
noexistFiles.Clear();
assetsFileListHash.Clear(); assetsFileListHash.Clear();
ReadAssets(); ReadAssets();
@@ -58,121 +64,144 @@ namespace AssetStudio
private void LoadFile(string fullName) 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: case FileType.AssetsFile:
LoadAssetsFile(fullName, reader); LoadAssetsFile(reader);
break; break;
case FileType.BundleFile: case FileType.BundleFile:
LoadBundleFile(fullName, reader); LoadBundleFile(reader);
break; break;
case FileType.WebFile: case FileType.WebFile:
LoadWebFile(fullName, reader); LoadWebFile(reader);
break;
case FileType.GZipFile:
LoadFile(DecompressGZip(reader));
break;
case FileType.BrotliFile:
LoadFile(DecompressBrotli(reader));
break;
case FileType.ZipFile:
LoadZipFile(reader);
break; break;
} }
} }
private void LoadAssetsFile(string fullName, EndianBinaryReader reader) private void LoadAssetsFile(FileReader reader)
{ {
var fileName = Path.GetFileName(fullName); if (!assetsFileListHash.Contains(reader.FileName))
if (!assetsFileListHash.Contains(fileName))
{ {
Logger.Info($"Loading {fileName}"); Logger.Info($"Loading {reader.FullPath}");
try try
{ {
var assetsFile = new SerializedFile(this, fullName, reader); var assetsFile = new SerializedFile(reader, this);
CheckStrippedVersion(assetsFile);
assetsFileList.Add(assetsFile); assetsFileList.Add(assetsFile);
assetsFileListHash.Add(assetsFile.fileName); assetsFileListHash.Add(assetsFile.fileName);
foreach (var sharedFile in assetsFile.m_Externals) foreach (var sharedFile in assetsFile.m_Externals)
{ {
var sharedFilePath = Path.Combine(Path.GetDirectoryName(fullName), sharedFile.fileName);
var sharedFileName = sharedFile.fileName; var sharedFileName = sharedFile.fileName;
if (!importFilesHash.Contains(sharedFileName)) if (!importFilesHash.Contains(sharedFileName))
{ {
if (!File.Exists(sharedFilePath)) var sharedFilePath = Path.Combine(Path.GetDirectoryName(reader.FullPath), sharedFileName);
if (!noexistFiles.Contains(sharedFilePath))
{ {
var findFiles = Directory.GetFiles(Path.GetDirectoryName(fullName), sharedFileName, SearchOption.AllDirectories); if (!File.Exists(sharedFilePath))
if (findFiles.Length > 0)
{ {
sharedFilePath = findFiles[0]; var findFiles = Directory.GetFiles(Path.GetDirectoryName(reader.FullPath), sharedFileName, SearchOption.AllDirectories);
if (findFiles.Length > 0)
{
sharedFilePath = findFiles[0];
}
}
if (File.Exists(sharedFilePath))
{
importFiles.Add(sharedFilePath);
importFilesHash.Add(sharedFileName);
}
else
{
noexistFiles.Add(sharedFilePath);
} }
}
if (File.Exists(sharedFilePath))
{
importFiles.Add(sharedFilePath);
importFilesHash.Add(sharedFileName);
} }
} }
} }
} }
catch catch (Exception e)
{ {
Logger.Error($"Error while reading assets file {reader.FullPath}", e);
reader.Dispose(); reader.Dispose();
//Logger.Warning($"Unable to load assets file {fileName}");
} }
} }
else else
{ {
Logger.Info($"Skipping {reader.FullPath}");
reader.Dispose(); reader.Dispose();
} }
} }
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(reader.FileName))
if (!assetsFileListHash.Contains(fileName))
{ {
try try
{ {
var assetsFile = new SerializedFile(this, fullName, reader); var assetsFile = new SerializedFile(reader, this);
assetsFile.originalPath = originalPath; assetsFile.originalPath = originalPath;
if (assetsFile.header.m_Version < 7) if (!string.IsNullOrEmpty(unityVersion) && assetsFile.header.m_Version < SerializedFileFormatVersion.Unknown_7)
{ {
assetsFile.SetVersion(unityVersion); assetsFile.SetVersion(unityVersion);
} }
CheckStrippedVersion(assetsFile);
assetsFileList.Add(assetsFile); assetsFileList.Add(assetsFile);
assetsFileListHash.Add(assetsFile.fileName); assetsFileListHash.Add(assetsFile.fileName);
} }
catch catch (Exception e)
{ {
//Logger.Error($"Unable to load assets file {fileName} from {Path.GetFileName(originalPath)}"); Logger.Error($"Error while reading assets file {reader.FullPath} from {Path.GetFileName(originalPath)}", e);
resourceFileReaders.Add(fileName, reader); resourceFileReaders.Add(reader.FileName, reader);
} }
} }
else
Logger.Info($"Skipping {originalPath} ({reader.FileName})");
} }
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 " + reader.FullPath);
Logger.Info("Loading " + fileName);
try try
{ {
var bundleFile = new BundleFile(reader, fullName); var bundleFile = new BundleFile(reader);
foreach (var file in bundleFile.fileList) foreach (var file in bundleFile.fileList)
{ {
var subReader = new EndianBinaryReader(file.stream); var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
if (SerializedFile.IsSerializedFile(subReader)) var subReader = new FileReader(dummyPath, file.stream);
if (subReader.FileType == FileType.AssetsFile)
{ {
var dummyPath = Path.GetDirectoryName(fullName) + Path.DirectorySeparatorChar + file.fileName; LoadAssetsFromMemory(subReader, originalPath ?? reader.FullPath, bundleFile.m_Header.unityRevision);
LoadAssetsFromMemory(dummyPath, subReader, parentPath ?? fullName, bundleFile.m_Header.unityRevision);
} }
else else
{ {
resourceFileReaders.Add(file.fileName, subReader); resourceFileReaders[file.fileName] = subReader; //TODO
} }
} }
} }
catch catch (Exception e)
{ {
/*var str = $"Unable to load bundle file {fileName}"; var str = $"Error while reading bundle file {reader.FullPath}";
if (parentPath != null) if (originalPath != null)
{ {
str += $" from {Path.GetFileName(parentPath)}"; str += $" from {Path.GetFileName(originalPath)}";
} }
Logger.Error(str);*/ Logger.Error(str, e);
} }
finally finally
{ {
@@ -180,36 +209,36 @@ namespace AssetStudio
} }
} }
private void LoadWebFile(string fullName, EndianBinaryReader reader) private void LoadWebFile(FileReader reader)
{ {
var fileName = Path.GetFileName(fullName); Logger.Info("Loading " + reader.FullPath);
Logger.Info("Loading " + fileName);
try try
{ {
var webFile = new WebFile(reader); var webFile = new WebFile(reader);
foreach (var file in webFile.fileList) foreach (var file in webFile.fileList)
{ {
var dummyPath = Path.Combine(Path.GetDirectoryName(fullName), file.fileName); var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
switch (CheckFileType(file.stream, out var fileReader)) var subReader = new FileReader(dummyPath, file.stream);
switch (subReader.FileType)
{ {
case FileType.AssetsFile: case FileType.AssetsFile:
LoadAssetsFromMemory(dummyPath, fileReader, fullName); LoadAssetsFromMemory(subReader, reader.FullPath);
break; break;
case FileType.BundleFile: case FileType.BundleFile:
LoadBundleFile(dummyPath, fileReader, fullName); LoadBundleFile(subReader, reader.FullPath);
break; break;
case FileType.WebFile: case FileType.WebFile:
LoadWebFile(dummyPath, fileReader); LoadWebFile(subReader);
break; break;
case FileType.ResourceFile: case FileType.ResourceFile:
resourceFileReaders.Add(file.fileName, fileReader); resourceFileReaders[file.fileName] = subReader; //TODO
break; break;
} }
} }
} }
catch catch (Exception e)
{ {
//Logger.Error($"Unable to load web file {fileName}"); Logger.Error($"Error while reading web file {reader.FullPath}", e);
} }
finally finally
{ {
@@ -217,6 +246,118 @@ namespace AssetStudio
} }
} }
private void LoadZipFile(FileReader reader)
{
Logger.Info("Loading " + reader.FileName);
try
{
using (ZipArchive archive = new ZipArchive(reader.BaseStream, ZipArchiveMode.Read))
{
List<string> splitFiles = new List<string>();
// register all files before parsing the assets so that the external references can be found
// and find split files
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.Name.Contains(".split"))
{
string baseName = Path.GetFileNameWithoutExtension(entry.Name);
string basePath = Path.Combine(Path.GetDirectoryName(entry.FullName), baseName);
if (!splitFiles.Contains(basePath))
{
splitFiles.Add(basePath);
importFilesHash.Add(baseName);
}
}
else
{
importFilesHash.Add(entry.Name);
}
}
// merge split files and load the result
foreach (string basePath in splitFiles)
{
try
{
Stream splitStream = new MemoryStream();
int i = 0;
while (true)
{
string path = $"{basePath}.split{i++}";
ZipArchiveEntry entry = archive.GetEntry(path);
if (entry == null)
break;
using (Stream entryStream = entry.Open())
{
entryStream.CopyTo(splitStream);
}
}
splitStream.Seek(0, SeekOrigin.Begin);
FileReader entryReader = new FileReader(basePath, splitStream);
LoadFile(entryReader);
}
catch (Exception e)
{
Logger.Error($"Error while reading zip split file {basePath}", e);
}
}
// load all entries
foreach (ZipArchiveEntry entry in archive.Entries)
{
try
{
string dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), reader.FileName, entry.FullName);
// create a new stream
// - to store the deflated stream in
// - to keep the data for later extraction
Stream streamReader = new MemoryStream();
using (Stream entryStream = entry.Open())
{
entryStream.CopyTo(streamReader);
}
streamReader.Position = 0;
FileReader entryReader = new FileReader(dummyPath, streamReader);
LoadFile(entryReader);
if (entryReader.FileType == FileType.ResourceFile)
{
entryReader.Position = 0;
if (!resourceFileReaders.ContainsKey(entry.Name))
{
resourceFileReaders.Add(entry.Name, entryReader);
}
}
}
catch (Exception e)
{
Logger.Error($"Error while reading zip entry {entry.FullName}", e);
}
}
}
}
catch (Exception e)
{
Logger.Error($"Error while reading zip file {reader.FileName}", e);
}
finally
{
reader.Dispose();
}
}
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() public void Clear()
{ {
foreach (var assetsFile in assetsFileList) foreach (var assetsFile in assetsFileList)
@@ -344,13 +485,14 @@ namespace AssetStudio
} }
catch (Exception e) catch (Exception e)
{ {
/*var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine("Unable to load object") sb.AppendLine("Unable to load object")
.AppendLine($"Assets {assetsFile.fileName}") .AppendLine($"Assets {assetsFile.fileName}")
.AppendLine($"Path {assetsFile.originalPath}")
.AppendLine($"Type {objectReader.type}") .AppendLine($"Type {objectReader.type}")
.AppendLine($"PathID {objectInfo.m_PathID}") .AppendLine($"PathID {objectInfo.m_PathID}")
.Append(e); .Append(e);
Logger.Error(sb.ToString());*/ Logger.Error(sb.ToString());
} }
Progress.Report(++i, progressCount); Progress.Report(++i, progressCount);
@@ -406,6 +548,14 @@ namespace AssetStudio
{ {
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas); m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
} }
else
{
m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlaOld);
if (m_SpriteAtlaOld.m_IsVariant)
{
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
}
}
} }
} }
} }
@@ -413,4 +563,4 @@ namespace AssetStudio
} }
} }
} }
} }
+10
View File
@@ -0,0 +1,10 @@
using System.Buffers;
namespace AssetStudio
{
public static class BigArrayPool<T>
{
private static readonly ArrayPool<T> s_shared = ArrayPool<T>.Create(64 * 1024 * 1024, 3);
public static ArrayPool<T> Shared => s_shared;
}
}
+6 -1
View File
@@ -8,7 +8,8 @@ namespace AssetStudio
public enum BuildTarget public enum BuildTarget
{ {
NoTarget = -2, NoTarget = -2,
DashboardWidget = 1, AnyPlayer = -1,
ValidPlayer = 1,
StandaloneOSX = 2, StandaloneOSX = 2,
StandaloneOSXPPC = 3, StandaloneOSXPPC = 3,
StandaloneOSXIntel = 4, StandaloneOSXIntel = 4,
@@ -19,8 +20,10 @@ namespace AssetStudio
iOS = 9, iOS = 9,
PS3, PS3,
XBOX360, XBOX360,
Broadcom = 12,
Android = 13, Android = 13,
StandaloneGLESEmu = 14, StandaloneGLESEmu = 14,
StandaloneGLES20Emu = 15,
NaCl = 16, NaCl = 16,
StandaloneLinux = 17, StandaloneLinux = 17,
FlashPlayer = 18, FlashPlayer = 18,
@@ -48,6 +51,8 @@ namespace AssetStudio
GameCoreXboxSeries, GameCoreXboxSeries,
GameCoreXboxOne, GameCoreXboxOne,
PS5, PS5,
EmbeddedLinux,
QNX,
UnknownPlatform = 9999 UnknownPlatform = 9999
} }
} }
+90 -42
View File
@@ -1,11 +1,36 @@
using System; using K4os.Compression.LZ4;
using System.Collections.Generic; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Lz4;
namespace AssetStudio namespace AssetStudio
{ {
[Flags]
public enum ArchiveFlags
{
CompressionTypeMask = 0x3f,
BlocksAndDirectoryInfoCombined = 0x40,
BlocksInfoAtTheEnd = 0x80,
OldWebPluginCompatibility = 0x100,
BlockInfoNeedPaddingAtStart = 0x200
}
[Flags]
public enum StorageBlockFlags
{
CompressionTypeMask = 0x3f,
Streamed = 0x40
}
public enum CompressionType
{
None,
Lzma,
Lz4,
Lz4HC,
Lzham
}
public class BundleFile public class BundleFile
{ {
public class Header public class Header
@@ -17,14 +42,14 @@ namespace AssetStudio
public long size; public long size;
public uint compressedBlocksInfoSize; public uint compressedBlocksInfoSize;
public uint uncompressedBlocksInfoSize; public uint uncompressedBlocksInfoSize;
public uint flags; public ArchiveFlags flags;
} }
public class StorageBlock public class StorageBlock
{ {
public uint compressedSize; public uint compressedSize;
public uint uncompressedSize; public uint uncompressedSize;
public ushort flags; public StorageBlockFlags flags;
} }
public class Node public class Node
@@ -41,7 +66,7 @@ namespace AssetStudio
public StreamFile[] fileList; public StreamFile[] fileList;
public BundleFile(EndianBinaryReader reader, string path) public BundleFile(FileReader reader)
{ {
m_Header = new Header(); m_Header = new Header();
m_Header.signature = reader.ReadStringToNull(); m_Header.signature = reader.ReadStringToNull();
@@ -59,19 +84,19 @@ namespace AssetStudio
goto case "UnityFS"; goto case "UnityFS";
} }
ReadHeaderAndBlocksInfo(reader); ReadHeaderAndBlocksInfo(reader);
using (var blocksStream = CreateBlocksStream(path)) using (var blocksStream = CreateBlocksStream(reader.FullPath))
{ {
ReadBlocksAndDirectory(reader, blocksStream); ReadBlocksAndDirectory(reader, blocksStream);
ReadFiles(blocksStream, path); ReadFiles(blocksStream, reader.FullPath);
} }
break; break;
case "UnityFS": case "UnityFS":
ReadHeader(reader); ReadHeader(reader);
ReadBlocksInfoAndDirectory(reader); ReadBlocksInfoAndDirectory(reader);
using (var blocksStream = CreateBlocksStream(path)) using (var blocksStream = CreateBlocksStream(reader.FullPath))
{ {
ReadBlocks(reader, blocksStream); ReadBlocks(reader, blocksStream);
ReadFiles(blocksStream, path); ReadFiles(blocksStream, reader.FullPath);
} }
break; break;
} }
@@ -79,7 +104,6 @@ namespace AssetStudio
private void ReadHeaderAndBlocksInfo(EndianBinaryReader reader) private void ReadHeaderAndBlocksInfo(EndianBinaryReader reader)
{ {
var isCompressed = m_Header.signature == "UnityWeb";
if (m_Header.version >= 4) if (m_Header.version >= 4)
{ {
var hash = reader.ReadBytes(16); var hash = reader.ReadBytes(16);
@@ -96,7 +120,6 @@ namespace AssetStudio
{ {
compressedSize = reader.ReadUInt32(), compressedSize = reader.ReadUInt32(),
uncompressedSize = reader.ReadUInt32(), uncompressedSize = reader.ReadUInt32(),
flags = (ushort)(isCompressed ? 1 : 0)
}; };
if (i == levelCount - 1) if (i == levelCount - 1)
{ {
@@ -120,7 +143,7 @@ namespace AssetStudio
var uncompressedSizeSum = m_BlocksInfo.Sum(x => x.uncompressedSize); var uncompressedSizeSum = m_BlocksInfo.Sum(x => x.uncompressedSize);
if (uncompressedSizeSum >= int.MaxValue) if (uncompressedSizeSum >= int.MaxValue)
{ {
/*var memoryMappedFile = MemoryMappedFile.CreateNew(Path.GetFileName(path), uncompressedSizeSum); /*var memoryMappedFile = MemoryMappedFile.CreateNew(null, uncompressedSizeSum);
assetsDataStream = memoryMappedFile.CreateViewStream();*/ assetsDataStream = memoryMappedFile.CreateViewStream();*/
blocksStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose); blocksStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
} }
@@ -133,10 +156,11 @@ namespace AssetStudio
private void ReadBlocksAndDirectory(EndianBinaryReader reader, Stream blocksStream) private void ReadBlocksAndDirectory(EndianBinaryReader reader, Stream blocksStream)
{ {
var isCompressed = m_Header.signature == "UnityWeb";
foreach (var blockInfo in m_BlocksInfo) foreach (var blockInfo in m_BlocksInfo)
{ {
var uncompressedBytes = reader.ReadBytes((int)blockInfo.compressedSize); var uncompressedBytes = reader.ReadBytes((int)blockInfo.compressedSize);
if (blockInfo.flags == 1) if (isCompressed)
{ {
using (var memoryStream = new MemoryStream(uncompressedBytes)) using (var memoryStream = new MemoryStream(uncompressedBytes))
{ {
@@ -171,10 +195,11 @@ namespace AssetStudio
var node = m_DirectoryInfo[i]; var node = m_DirectoryInfo[i];
var file = new StreamFile(); var file = new StreamFile();
fileList[i] = file; fileList[i] = file;
file.path = node.path;
file.fileName = Path.GetFileName(node.path); file.fileName = Path.GetFileName(node.path);
if (node.size >= int.MaxValue) if (node.size >= int.MaxValue)
{ {
/*var memoryMappedFile = MemoryMappedFile.CreateNew(file.fileName, entryinfo_size); /*var memoryMappedFile = MemoryMappedFile.CreateNew(null, entryinfo_size);
file.stream = memoryMappedFile.CreateViewStream();*/ file.stream = memoryMappedFile.CreateViewStream();*/
var extractPath = path + "_unpacked" + Path.DirectorySeparatorChar; var extractPath = path + "_unpacked" + Path.DirectorySeparatorChar;
Directory.CreateDirectory(extractPath); Directory.CreateDirectory(extractPath);
@@ -195,7 +220,7 @@ namespace AssetStudio
m_Header.size = reader.ReadInt64(); m_Header.size = reader.ReadInt64();
m_Header.compressedBlocksInfoSize = reader.ReadUInt32(); m_Header.compressedBlocksInfoSize = reader.ReadUInt32();
m_Header.uncompressedBlocksInfoSize = reader.ReadUInt32(); m_Header.uncompressedBlocksInfoSize = reader.ReadUInt32();
m_Header.flags = reader.ReadUInt32(); m_Header.flags = (ArchiveFlags)reader.ReadUInt32();
if (m_Header.signature != "UnityFS") if (m_Header.signature != "UnityFS")
{ {
reader.ReadByte(); reader.ReadByte();
@@ -209,43 +234,51 @@ namespace AssetStudio
{ {
reader.AlignStream(16); reader.AlignStream(16);
} }
if ((m_Header.flags & 0x80) != 0) //kArchiveBlocksInfoAtTheEnd if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
{ {
var position = reader.Position; var position = reader.Position;
reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize; reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize); blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
reader.Position = position; reader.Position = position;
} }
else //0x40 kArchiveBlocksAndDirectoryInfoCombined else //0x40 BlocksAndDirectoryInfoCombined
{ {
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize); blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
} }
var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
MemoryStream blocksInfoUncompresseddStream; MemoryStream blocksInfoUncompresseddStream;
switch (m_Header.flags & 0x3F) //kArchiveCompressionTypeMask var uncompressedSize = m_Header.uncompressedBlocksInfoSize;
var compressionType = (CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask);
switch (compressionType)
{ {
default: //None case CompressionType.None:
{ {
blocksInfoUncompresseddStream = blocksInfoCompressedStream; blocksInfoUncompresseddStream = new MemoryStream(blocksInfoBytes);
break; break;
} }
case 1: //LZMA case CompressionType.Lzma:
{ {
blocksInfoUncompresseddStream = SevenZipHelper.StreamDecompress(blocksInfoCompressedStream); blocksInfoUncompresseddStream = new MemoryStream((int)(uncompressedSize));
blocksInfoCompressedStream.Close(); using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
break;
}
case 2: //LZ4
case 3: //LZ4HC
{
var uncompressedBytes = new byte[m_Header.uncompressedBlocksInfoSize];
using (var decoder = new Lz4DecoderStream(blocksInfoCompressedStream))
{ {
decoder.Read(uncompressedBytes, 0, uncompressedBytes.Length); SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompresseddStream, m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
}
blocksInfoUncompresseddStream.Position = 0;
break;
}
case CompressionType.Lz4:
case CompressionType.Lz4HC:
{
var uncompressedBytes = new byte[uncompressedSize];
var numWrite = LZ4Codec.Decode(blocksInfoBytes, uncompressedBytes);
if (numWrite != uncompressedSize)
{
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
} }
blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes); blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
break; break;
} }
default:
throw new IOException($"Unsupported compression type {compressionType}");
} }
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream)) using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
{ {
@@ -258,7 +291,7 @@ namespace AssetStudio
{ {
uncompressedSize = blocksInfoReader.ReadUInt32(), uncompressedSize = blocksInfoReader.ReadUInt32(),
compressedSize = blocksInfoReader.ReadUInt32(), compressedSize = blocksInfoReader.ReadUInt32(),
flags = blocksInfoReader.ReadUInt16() flags = (StorageBlockFlags)blocksInfoReader.ReadUInt16()
}; };
} }
@@ -275,34 +308,49 @@ namespace AssetStudio
}; };
} }
} }
if ((m_Header.flags & ArchiveFlags.BlockInfoNeedPaddingAtStart) != 0)
{
reader.AlignStream(16);
}
} }
private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream) private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
{ {
foreach (var blockInfo in m_BlocksInfo) foreach (var blockInfo in m_BlocksInfo)
{ {
switch (blockInfo.flags & 0x3F) //kStorageBlockCompressionTypeMask var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
switch (compressionType)
{ {
default: //None case CompressionType.None:
{ {
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize); reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
break; break;
} }
case 1: //LZMA case CompressionType.Lzma:
{ {
SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize); SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
break; break;
} }
case 2: //LZ4 case CompressionType.Lz4:
case 3: //LZ4HC case CompressionType.Lz4HC:
{ {
var compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize)); var compressedSize = (int)blockInfo.compressedSize;
using (var lz4Stream = new Lz4DecoderStream(compressedStream)) var compressedBytes = BigArrayPool<byte>.Shared.Rent(compressedSize);
reader.Read(compressedBytes, 0, compressedSize);
var uncompressedSize = (int)blockInfo.uncompressedSize;
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
var numWrite = LZ4Codec.Decode(compressedBytes, 0, compressedSize, uncompressedBytes, 0, uncompressedSize);
if (numWrite != uncompressedSize)
{ {
lz4Stream.CopyTo(blocksStream, blockInfo.uncompressedSize); throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
} }
blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
BigArrayPool<byte>.Shared.Return(compressedBytes);
BigArrayPool<byte>.Shared.Return(uncompressedBytes);
break; break;
} }
default:
throw new IOException($"Unsupported compression type {compressionType}");
} }
} }
blocksStream.Position = 0; blocksStream.Position = 0;
+57 -4
View File
@@ -637,6 +637,50 @@ namespace AssetStudio
m_Binding = new ValueArrayConstant(reader); 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 public class ValueDelta
@@ -753,6 +797,9 @@ namespace AssetStudio
public ClassIDType typeID; public ClassIDType typeID;
public byte customType; public byte customType;
public byte isPPtrCurve; public byte isPPtrCurve;
public byte isIntCurve;
public GenericBinding() { }
public GenericBinding(ObjectReader reader) public GenericBinding(ObjectReader reader)
{ {
@@ -770,6 +817,10 @@ namespace AssetStudio
} }
customType = reader.ReadByte(); customType = reader.ReadByte();
isPPtrCurve = reader.ReadByte(); isPPtrCurve = reader.ReadByte();
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
{
isIntCurve = reader.ReadByte();
}
reader.AlignStream(); reader.AlignStream();
} }
} }
@@ -779,6 +830,8 @@ namespace AssetStudio
public GenericBinding[] genericBindings; public GenericBinding[] genericBindings;
public PPtr<Object>[] pptrCurveMapping; public PPtr<Object>[] pptrCurveMapping;
public AnimationClipBindingConstant() { }
public AnimationClipBindingConstant(ObjectReader reader) public AnimationClipBindingConstant(ObjectReader reader)
{ {
int numBindings = reader.ReadInt32(); int numBindings = reader.ReadInt32();
@@ -861,9 +914,9 @@ namespace AssetStudio
public enum AnimationType public enum AnimationType
{ {
kLegacy = 1, Legacy = 1,
kGeneric = 2, Generic = 2,
kHumanoid = 3 Humanoid = 3
}; };
public sealed class AnimationClip : NamedObject public sealed class AnimationClip : NamedObject
@@ -897,7 +950,7 @@ namespace AssetStudio
else if (version[0] >= 4)//4.0 and up else if (version[0] >= 4)//4.0 and up
{ {
m_AnimationType = (AnimationType)reader.ReadInt32(); m_AnimationType = (AnimationType)reader.ReadInt32();
if (m_AnimationType == AnimationType.kLegacy) if (m_AnimationType == AnimationType.Legacy)
m_Legacy = true; m_Legacy = true;
} }
else else
+4
View File
@@ -31,6 +31,10 @@ namespace AssetStudio
if (version[0] >= 5) //5.0 and up if (version[0] >= 5) //5.0 and up
{ {
var m_LinearVelocityBlending = reader.ReadBoolean(); 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(); reader.AlignStream();
} }
+44 -27
View File
@@ -9,7 +9,7 @@ namespace AssetStudio
public sealed class AudioClip : NamedObject public sealed class AudioClip : NamedObject
{ {
public int m_Format; public int m_Format;
public AudioType m_Type; public FMODSoundType m_Type;
public bool m_3D; public bool m_3D;
public bool m_UseHardware; public bool m_UseHardware;
@@ -27,8 +27,8 @@ namespace AssetStudio
public AudioCompressionFormat m_CompressionFormat; public AudioCompressionFormat m_CompressionFormat;
public string m_Source; public string m_Source;
public ulong m_Offset; public long m_Offset; //ulong
public long m_Size; public long m_Size; //ulong
public ResourceReader m_AudioData; public ResourceReader m_AudioData;
public AudioClip(ObjectReader reader) : base(reader) public AudioClip(ObjectReader reader) : base(reader)
@@ -36,7 +36,7 @@ namespace AssetStudio
if (version[0] < 5) if (version[0] < 5)
{ {
m_Format = reader.ReadInt32(); m_Format = reader.ReadInt32();
m_Type = (AudioType)reader.ReadInt32(); m_Type = (FMODSoundType)reader.ReadInt32();
m_3D = reader.ReadBoolean(); m_3D = reader.ReadBoolean();
m_UseHardware = reader.ReadBoolean(); m_UseHardware = reader.ReadBoolean();
reader.AlignStream(); reader.AlignStream();
@@ -74,7 +74,7 @@ namespace AssetStudio
//StreamedResource m_Resource //StreamedResource m_Resource
m_Source = reader.ReadAlignedString(); m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadUInt64(); m_Offset = reader.ReadInt64();
m_Size = reader.ReadInt64(); m_Size = reader.ReadInt64();
m_CompressionFormat = (AudioCompressionFormat)reader.ReadInt32(); m_CompressionFormat = (AudioCompressionFormat)reader.ReadInt32();
} }
@@ -82,44 +82,61 @@ namespace AssetStudio
ResourceReader resourceReader; ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_Source)) 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 else
{ {
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size); resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_Size);
} }
m_AudioData = resourceReader; m_AudioData = resourceReader;
} }
} }
public enum AudioType public enum FMODSoundType
{ {
UNKNOWN, UNKNOWN = 0,
ACC, ACC = 1,
AIFF, AIFF = 2,
ASF = 3,
AT3 = 4,
CDDA = 5,
DLS = 6,
FLAC = 7,
FSB = 8,
GCADPCM = 9,
IT = 10, IT = 10,
MIDI = 11,
MOD = 12, MOD = 12,
MPEG, MPEG = 13,
OGGVORBIS, OGGVORBIS = 14,
PLAYLIST = 15,
RAW = 16,
S3M = 17, S3M = 17,
SF2 = 18,
USER = 19,
WAV = 20, WAV = 20,
XM, XM = 21,
XMA, XMA = 22,
VAG, VAG = 23,
AUDIOQUEUE AUDIOQUEUE = 24,
XWMA = 25,
BCWAV = 26,
AT9 = 27,
VORBIS = 28,
MEDIA_FOUNDATION = 29
} }
public enum AudioCompressionFormat public enum AudioCompressionFormat
{ {
PCM, PCM = 0,
Vorbis, Vorbis = 1,
ADPCM, ADPCM = 2,
MP3, MP3 = 3,
VAG, PSMVAG = 4,
HEVAG, HEVAG = 5,
XMA, XMA = 6,
AAC, AAC = 7,
GCADPCM, GCADPCM = 8,
ATRAC9 ATRAC9 = 9
} }
} }
+10 -1
View File
@@ -74,9 +74,18 @@ namespace AssetStudio
var m_ShaderKeywords = reader.ReadStringArray(); var m_ShaderKeywords = reader.ReadStringArray();
} }
if (version[0] >= 5) //5.0 and up if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 3)) //2021.3 and up
{
var m_ValidKeywords = reader.ReadStringArray();
var m_InvalidKeywords = reader.ReadStringArray();
}
else if (version[0] >= 5) //5.0 ~ 2021.2
{ {
var m_ShaderKeywords = reader.ReadAlignedString(); var m_ShaderKeywords = reader.ReadAlignedString();
}
if (version[0] >= 5) //5.0 and up
{
var m_LightmapFlags = reader.ReadUInt32(); var m_LightmapFlags = reader.ReadUInt32();
} }
+107 -102
View File
@@ -396,14 +396,14 @@ namespace AssetStudio
} }
} }
public enum GfxPrimitiveType : int public enum GfxPrimitiveType
{ {
kPrimitiveTriangles = 0, Triangles = 0,
kPrimitiveTriangleStrip = 1, TriangleStrip = 1,
kPrimitiveQuads = 2, Quads = 2,
kPrimitiveLines = 3, Lines = 3,
kPrimitiveLineStrip = 4, LineStrip = 4,
kPrimitivePoints = 5, Points = 5
}; };
public class SubMesh public class SubMesh
@@ -651,6 +651,11 @@ namespace AssetStudio
int m_MeshUsageFlags = reader.ReadInt32(); int m_MeshUsageFlags = reader.ReadInt32();
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
{
int m_CookingOptions = reader.ReadInt32();
}
if (version[0] >= 5) //5.0 and up if (version[0] >= 5) //5.0 and up
{ {
var m_BakedConvexCollisionMesh = reader.ReadUInt8Array(); var m_BakedConvexCollisionMesh = reader.ReadUInt8Array();
@@ -681,7 +686,7 @@ namespace AssetStudio
{ {
if (m_VertexData.m_VertexCount > 0) 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(); m_VertexData.m_DataSize = resourceReader.GetData();
} }
} }
@@ -729,7 +734,7 @@ namespace AssetStudio
} }
} }
if (reader.endian == EndianType.BigEndian && componentByteSize > 1) //swap bytes if (reader.Endian == EndianType.BigEndian && componentByteSize > 1) //swap bytes
{ {
for (var i = 0; i < componentBytes.Length / componentByteSize; i++) for (var i = 0; i < componentBytes.Length / componentByteSize; i++)
{ {
@@ -1060,7 +1065,7 @@ namespace AssetStudio
} }
var indexCount = m_SubMesh.indexCount; var indexCount = m_SubMesh.indexCount;
var topology = m_SubMesh.topology; var topology = m_SubMesh.topology;
if (topology == GfxPrimitiveType.kPrimitiveTriangles) if (topology == GfxPrimitiveType.Triangles)
{ {
for (int i = 0; i < indexCount; i += 3) for (int i = 0; i < indexCount; i += 3)
{ {
@@ -1069,7 +1074,7 @@ namespace AssetStudio
m_Indices.Add(m_IndexBuffer[firstIndex + i + 2]); m_Indices.Add(m_IndexBuffer[firstIndex + i + 2]);
} }
} }
else if (version[0] < 4 || topology == GfxPrimitiveType.kPrimitiveTriangleStrip) else if (version[0] < 4 || topology == GfxPrimitiveType.TriangleStrip)
{ {
// de-stripify : // de-stripify :
uint triIndex = 0; uint triIndex = 0;
@@ -1100,7 +1105,7 @@ namespace AssetStudio
//fix indexCount //fix indexCount
m_SubMesh.indexCount = triIndex; m_SubMesh.indexCount = triIndex;
} }
else if (topology == GfxPrimitiveType.kPrimitiveQuads) else if (topology == GfxPrimitiveType.Quads)
{ {
for (int q = 0; q < indexCount; q += 4) for (int q = 0; q < indexCount; q += 4)
{ {
@@ -1193,44 +1198,44 @@ namespace AssetStudio
{ {
public enum VertexChannelFormat public enum VertexChannelFormat
{ {
kChannelFormatFloat, Float,
kChannelFormatFloat16, Float16,
kChannelFormatColor, Color,
kChannelFormatByte, Byte,
kChannelFormatUInt32 UInt32
} }
public enum VertexFormat2017 public enum VertexFormat2017
{ {
kVertexFormatFloat, Float,
kVertexFormatFloat16, Float16,
kVertexFormatColor, Color,
kVertexFormatUNorm8, UNorm8,
kVertexFormatSNorm8, SNorm8,
kVertexFormatUNorm16, UNorm16,
kVertexFormatSNorm16, SNorm16,
kVertexFormatUInt8, UInt8,
kVertexFormatSInt8, SInt8,
kVertexFormatUInt16, UInt16,
kVertexFormatSInt16, SInt16,
kVertexFormatUInt32, UInt32,
kVertexFormatSInt32 SInt32
} }
public enum VertexFormat public enum VertexFormat
{ {
kVertexFormatFloat, Float,
kVertexFormatFloat16, Float16,
kVertexFormatUNorm8, UNorm8,
kVertexFormatSNorm8, SNorm8,
kVertexFormatUNorm16, UNorm16,
kVertexFormatSNorm16, SNorm16,
kVertexFormatUInt8, UInt8,
kVertexFormatSInt8, SInt8,
kVertexFormatUInt16, UInt16,
kVertexFormatSInt16, SInt16,
kVertexFormatUInt32, UInt32,
kVertexFormatSInt32 SInt32
} }
public static VertexFormat ToVertexFormat(int format, int[] version) public static VertexFormat ToVertexFormat(int format, int[] version)
@@ -1239,16 +1244,16 @@ namespace AssetStudio
{ {
switch ((VertexChannelFormat)format) switch ((VertexChannelFormat)format)
{ {
case VertexChannelFormat.kChannelFormatFloat: case VertexChannelFormat.Float:
return VertexFormat.kVertexFormatFloat; return VertexFormat.Float;
case VertexChannelFormat.kChannelFormatFloat16: case VertexChannelFormat.Float16:
return VertexFormat.kVertexFormatFloat16; return VertexFormat.Float16;
case VertexChannelFormat.kChannelFormatColor: //in 4.x is size 4 case VertexChannelFormat.Color: //in 4.x is size 4
return VertexFormat.kVertexFormatUNorm8; return VertexFormat.UNorm8;
case VertexChannelFormat.kChannelFormatByte: case VertexChannelFormat.Byte:
return VertexFormat.kVertexFormatUInt8; return VertexFormat.UInt8;
case VertexChannelFormat.kChannelFormatUInt32: //in 5.x case VertexChannelFormat.UInt32: //in 5.x
return VertexFormat.kVertexFormatUInt32; return VertexFormat.UInt32;
default: default:
throw new ArgumentOutOfRangeException(nameof(format), format, null); throw new ArgumentOutOfRangeException(nameof(format), format, null);
} }
@@ -1257,31 +1262,31 @@ namespace AssetStudio
{ {
switch ((VertexFormat2017)format) switch ((VertexFormat2017)format)
{ {
case VertexFormat2017.kVertexFormatFloat: case VertexFormat2017.Float:
return VertexFormat.kVertexFormatFloat; return VertexFormat.Float;
case VertexFormat2017.kVertexFormatFloat16: case VertexFormat2017.Float16:
return VertexFormat.kVertexFormatFloat16; return VertexFormat.Float16;
case VertexFormat2017.kVertexFormatColor: case VertexFormat2017.Color:
case VertexFormat2017.kVertexFormatUNorm8: case VertexFormat2017.UNorm8:
return VertexFormat.kVertexFormatUNorm8; return VertexFormat.UNorm8;
case VertexFormat2017.kVertexFormatSNorm8: case VertexFormat2017.SNorm8:
return VertexFormat.kVertexFormatSNorm8; return VertexFormat.SNorm8;
case VertexFormat2017.kVertexFormatUNorm16: case VertexFormat2017.UNorm16:
return VertexFormat.kVertexFormatUNorm16; return VertexFormat.UNorm16;
case VertexFormat2017.kVertexFormatSNorm16: case VertexFormat2017.SNorm16:
return VertexFormat.kVertexFormatSNorm16; return VertexFormat.SNorm16;
case VertexFormat2017.kVertexFormatUInt8: case VertexFormat2017.UInt8:
return VertexFormat.kVertexFormatUInt8; return VertexFormat.UInt8;
case VertexFormat2017.kVertexFormatSInt8: case VertexFormat2017.SInt8:
return VertexFormat.kVertexFormatSInt8; return VertexFormat.SInt8;
case VertexFormat2017.kVertexFormatUInt16: case VertexFormat2017.UInt16:
return VertexFormat.kVertexFormatUInt16; return VertexFormat.UInt16;
case VertexFormat2017.kVertexFormatSInt16: case VertexFormat2017.SInt16:
return VertexFormat.kVertexFormatSInt16; return VertexFormat.SInt16;
case VertexFormat2017.kVertexFormatUInt32: case VertexFormat2017.UInt32:
return VertexFormat.kVertexFormatUInt32; return VertexFormat.UInt32;
case VertexFormat2017.kVertexFormatSInt32: case VertexFormat2017.SInt32:
return VertexFormat.kVertexFormatSInt32; return VertexFormat.SInt32;
default: default:
throw new ArgumentOutOfRangeException(nameof(format), format, null); throw new ArgumentOutOfRangeException(nameof(format), format, null);
} }
@@ -1297,20 +1302,20 @@ namespace AssetStudio
{ {
switch (format) switch (format)
{ {
case VertexFormat.kVertexFormatFloat: case VertexFormat.Float:
case VertexFormat.kVertexFormatUInt32: case VertexFormat.UInt32:
case VertexFormat.kVertexFormatSInt32: case VertexFormat.SInt32:
return 4u; return 4u;
case VertexFormat.kVertexFormatFloat16: case VertexFormat.Float16:
case VertexFormat.kVertexFormatUNorm16: case VertexFormat.UNorm16:
case VertexFormat.kVertexFormatSNorm16: case VertexFormat.SNorm16:
case VertexFormat.kVertexFormatUInt16: case VertexFormat.UInt16:
case VertexFormat.kVertexFormatSInt16: case VertexFormat.SInt16:
return 2u; return 2u;
case VertexFormat.kVertexFormatUNorm8: case VertexFormat.UNorm8:
case VertexFormat.kVertexFormatSNorm8: case VertexFormat.SNorm8:
case VertexFormat.kVertexFormatUInt8: case VertexFormat.UInt8:
case VertexFormat.kVertexFormatSInt8: case VertexFormat.SInt8:
return 1u; return 1u;
default: default:
throw new ArgumentOutOfRangeException(nameof(format), format, null); throw new ArgumentOutOfRangeException(nameof(format), format, null);
@@ -1319,7 +1324,7 @@ namespace AssetStudio
public static bool IsIntFormat(VertexFormat format) public static bool IsIntFormat(VertexFormat format)
{ {
return format >= VertexFormat.kVertexFormatUInt8; return format >= VertexFormat.UInt8;
} }
public static float[] BytesToFloatArray(byte[] inputBytes, VertexFormat format) public static float[] BytesToFloatArray(byte[] inputBytes, VertexFormat format)
@@ -1331,22 +1336,22 @@ namespace AssetStudio
{ {
switch (format) switch (format)
{ {
case VertexFormat.kVertexFormatFloat: case VertexFormat.Float:
result[i] = BitConverter.ToSingle(inputBytes, i * 4); result[i] = BitConverter.ToSingle(inputBytes, i * 4);
break; break;
case VertexFormat.kVertexFormatFloat16: case VertexFormat.Float16:
result[i] = Half.ToHalf(inputBytes, i * 2); result[i] = Half.ToHalf(inputBytes, i * 2);
break; break;
case VertexFormat.kVertexFormatUNorm8: case VertexFormat.UNorm8:
result[i] = inputBytes[i] / 255f; result[i] = inputBytes[i] / 255f;
break; break;
case VertexFormat.kVertexFormatSNorm8: case VertexFormat.SNorm8:
result[i] = Math.Max((sbyte)inputBytes[i] / 127f, -1f); result[i] = Math.Max((sbyte)inputBytes[i] / 127f, -1f);
break; break;
case VertexFormat.kVertexFormatUNorm16: case VertexFormat.UNorm16:
result[i] = BitConverter.ToUInt16(inputBytes, i * 2) / 65535f; result[i] = BitConverter.ToUInt16(inputBytes, i * 2) / 65535f;
break; break;
case VertexFormat.kVertexFormatSNorm16: case VertexFormat.SNorm16:
result[i] = Math.Max(BitConverter.ToInt16(inputBytes, i * 2) / 32767f, -1f); result[i] = Math.Max(BitConverter.ToInt16(inputBytes, i * 2) / 32767f, -1f);
break; break;
} }
@@ -1363,16 +1368,16 @@ namespace AssetStudio
{ {
switch (format) switch (format)
{ {
case VertexFormat.kVertexFormatUInt8: case VertexFormat.UInt8:
case VertexFormat.kVertexFormatSInt8: case VertexFormat.SInt8:
result[i] = inputBytes[i]; result[i] = inputBytes[i];
break; break;
case VertexFormat.kVertexFormatUInt16: case VertexFormat.UInt16:
case VertexFormat.kVertexFormatSInt16: case VertexFormat.SInt16:
result[i] = BitConverter.ToInt16(inputBytes, i * 2); result[i] = BitConverter.ToInt16(inputBytes, i * 2);
break; break;
case VertexFormat.kVertexFormatUInt32: case VertexFormat.UInt32:
case VertexFormat.kVertexFormatSInt32: case VertexFormat.SInt32:
result[i] = BitConverter.ToInt32(inputBytes, i * 4); result[i] = BitConverter.ToInt32(inputBytes, i * 4);
break; break;
} }
+11 -23
View File
@@ -1,7 +1,4 @@
using System.Collections.Generic; using System.Collections.Specialized;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
namespace AssetStudio namespace AssetStudio
{ {
@@ -36,47 +33,38 @@ namespace AssetStudio
} }
} }
protected bool HasStructMember(string name)
{
return serializedType?.m_Nodes != null && serializedType.m_Nodes.Any(x => x.m_Name == name);
}
public string Dump() public string Dump()
{ {
if (serializedType?.m_Nodes != null) if (serializedType?.m_Type != null)
{ {
var sb = new StringBuilder(); return TypeTreeHelper.ReadTypeString(serializedType.m_Type, reader);
TypeTreeHelper.ReadTypeString(sb, serializedType.m_Nodes, reader);
return sb.ToString();
} }
return null; return null;
} }
public string Dump(List<TypeTreeNode> m_Nodes) public string Dump(TypeTree m_Type)
{ {
if (m_Nodes != null) if (m_Type != null)
{ {
var sb = new StringBuilder(); return TypeTreeHelper.ReadTypeString(m_Type, reader);
TypeTreeHelper.ReadTypeString(sb, m_Nodes, reader);
return sb.ToString();
} }
return null; return null;
} }
public OrderedDictionary ToType() public OrderedDictionary ToType()
{ {
if (serializedType?.m_Nodes != null) if (serializedType?.m_Type != null)
{ {
return TypeTreeHelper.ReadType(serializedType.m_Nodes, reader); return TypeTreeHelper.ReadType(serializedType.m_Type, reader);
} }
return null; return null;
} }
public OrderedDictionary ToType(List<TypeTreeNode> m_Nodes) public OrderedDictionary ToType(TypeTree m_Type)
{ {
if (m_Nodes != null) if (m_Type != null)
{ {
return TypeTreeHelper.ReadType(m_Nodes, reader); return TypeTreeHelper.ReadType(m_Type, reader);
} }
return null; return null;
} }
+1 -1
View File
@@ -13,7 +13,7 @@ namespace AssetStudio
public PPtr(ObjectReader reader) public PPtr(ObjectReader reader)
{ {
m_FileID = reader.ReadInt32(); m_FileID = reader.ReadInt32();
m_PathID = reader.m_Version < 14 ? reader.ReadInt32() : reader.ReadInt64(); m_PathID = reader.m_Version < SerializedFileFormatVersion.Unknown_14 ? reader.ReadInt32() : reader.ReadInt64();
assetsFile = reader.assetsFile; assetsFile = reader.assetsFile;
} }
+283 -130
View File
@@ -56,15 +56,14 @@ namespace AssetStudio
} }
public enum TextureDimension public enum TextureDimension
{ {
kTexDimUnknown = -1, Unknown = -1,
kTexDimNone = 0, None = 0,
kTexDimAny = 1, Any = 1,
kTexDim2D = 2, Tex2D = 2,
kTexDim3D = 3, Tex3D = 3,
kTexDimCUBE = 4, Cube = 4,
kTexDim2DArray = 5, Tex2DArray = 5,
kTexDimCubeArray = 6, CubeArray = 6
kTexDimForce32Bit = 2147483647
}; };
public class SerializedTextureProperty public class SerializedTextureProperty
@@ -81,11 +80,12 @@ namespace AssetStudio
public enum SerializedPropertyType public enum SerializedPropertyType
{ {
kColor = 0, Color = 0,
kVector = 1, Vector = 1,
kFloat = 2, Float = 2,
kRange = 3, Range = 3,
kTexture = 4 Texture = 4,
Int = 5
}; };
public class SerializedProperty public class SerializedProperty
@@ -195,11 +195,11 @@ namespace AssetStudio
public enum FogMode public enum FogMode
{ {
kFogUnknown = -1, Unknown = -1,
kFogDisabled = 0, Disabled = 0,
kFogLinear = 1, Linear = 1,
kFogExp = 2, Exp = 2,
kFogExp2 = 3 Exp2 = 3
}; };
public class SerializedShaderState public class SerializedShaderState
@@ -394,6 +394,7 @@ namespace AssetStudio
public VectorParameter[] m_VectorParams; public VectorParameter[] m_VectorParams;
public StructParameter[] m_StructParams; public StructParameter[] m_StructParams;
public int m_Size; public int m_Size;
public bool m_IsPartialCB;
public ConstantBuffer(ObjectReader reader) public ConstantBuffer(ObjectReader reader)
{ {
@@ -424,6 +425,16 @@ namespace AssetStudio
} }
} }
m_Size = reader.ReadInt32(); m_Size = reader.ReadInt32();
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] > 2021) ||
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
{
m_IsPartialCB = reader.ReadBoolean();
reader.AlignStream();
}
} }
} }
@@ -443,47 +454,43 @@ namespace AssetStudio
public enum ShaderGpuProgramType public enum ShaderGpuProgramType
{ {
kShaderGpuProgramUnknown = 0, Unknown = 0,
kShaderGpuProgramGLLegacy = 1, GLLegacy = 1,
kShaderGpuProgramGLES31AEP = 2, GLES31AEP = 2,
kShaderGpuProgramGLES31 = 3, GLES31 = 3,
kShaderGpuProgramGLES3 = 4, GLES3 = 4,
kShaderGpuProgramGLES = 5, GLES = 5,
kShaderGpuProgramGLCore32 = 6, GLCore32 = 6,
kShaderGpuProgramGLCore41 = 7, GLCore41 = 7,
kShaderGpuProgramGLCore43 = 8, GLCore43 = 8,
kShaderGpuProgramDX9VertexSM20 = 9, DX9VertexSM20 = 9,
kShaderGpuProgramDX9VertexSM30 = 10, DX9VertexSM30 = 10,
kShaderGpuProgramDX9PixelSM20 = 11, DX9PixelSM20 = 11,
kShaderGpuProgramDX9PixelSM30 = 12, DX9PixelSM30 = 12,
kShaderGpuProgramDX10Level9Vertex = 13, DX10Level9Vertex = 13,
kShaderGpuProgramDX10Level9Pixel = 14, DX10Level9Pixel = 14,
kShaderGpuProgramDX11VertexSM40 = 15, DX11VertexSM40 = 15,
kShaderGpuProgramDX11VertexSM50 = 16, DX11VertexSM50 = 16,
kShaderGpuProgramDX11PixelSM40 = 17, DX11PixelSM40 = 17,
kShaderGpuProgramDX11PixelSM50 = 18, DX11PixelSM50 = 18,
kShaderGpuProgramDX11GeometrySM40 = 19, DX11GeometrySM40 = 19,
kShaderGpuProgramDX11GeometrySM50 = 20, DX11GeometrySM50 = 20,
kShaderGpuProgramDX11HullSM50 = 21, DX11HullSM50 = 21,
kShaderGpuProgramDX11DomainSM50 = 22, DX11DomainSM50 = 22,
kShaderGpuProgramMetalVS = 23, MetalVS = 23,
kShaderGpuProgramMetalFS = 24, MetalFS = 24,
kShaderGpuProgramSPIRV = 25, SPIRV = 25,
kShaderGpuProgramConsoleVS = 26, ConsoleVS = 26,
kShaderGpuProgramConsoleFS = 27, ConsoleFS = 27,
kShaderGpuProgramConsoleHS = 28, ConsoleHS = 28,
kShaderGpuProgramConsoleDS = 29, ConsoleDS = 29,
kShaderGpuProgramConsoleGS = 30, ConsoleGS = 30,
kShaderGpuProgramRayTracing = 31, RayTracing = 31,
PS5NGGC = 32
}; };
public class SerializedSubProgram public class SerializedProgramParameters
{ {
public uint m_BlobIndex;
public ParserBindChannels m_Channels;
public ushort[] m_KeywordIndices;
public sbyte m_ShaderHardwareTier;
public ShaderGpuProgramType m_GpuProgramType;
public VectorParameter[] m_VectorParams; public VectorParameter[] m_VectorParams;
public MatrixParameter[] m_MatrixParams; public MatrixParameter[] m_MatrixParams;
public TextureParameter[] m_TextureParams; public TextureParameter[] m_TextureParams;
@@ -493,33 +500,8 @@ namespace AssetStudio
public UAVParameter[] m_UAVParams; public UAVParameter[] m_UAVParams;
public SamplerParameter[] m_Samplers; public SamplerParameter[] m_Samplers;
public SerializedSubProgram(ObjectReader reader) public SerializedProgramParameters(ObjectReader reader)
{ {
var version = reader.version;
m_BlobIndex = reader.ReadUInt32();
m_Channels = new ParserBindChannels(reader);
if (version[0] >= 2019) //2019 and up
{
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
var m_LocalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
}
else
{
m_KeywordIndices = reader.ReadUInt16Array();
if (version[0] >= 2017) //2017 and up
{
reader.AlignStream();
}
}
m_ShaderHardwareTier = reader.ReadSByte();
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
reader.AlignStream();
int numVectorParams = reader.ReadInt32(); int numVectorParams = reader.ReadInt32();
m_VectorParams = new VectorParameter[numVectorParams]; m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++) for (int i = 0; i < numVectorParams; i++)
@@ -569,15 +551,129 @@ namespace AssetStudio
m_UAVParams[i] = new UAVParameter(reader); m_UAVParams[i] = new UAVParameter(reader);
} }
if (version[0] >= 2017) //2017 and up int numSamplers = reader.ReadInt32();
m_Samplers = new SamplerParameter[numSamplers];
for (int i = 0; i < numSamplers; i++)
{ {
int numSamplers = reader.ReadInt32(); m_Samplers[i] = new SamplerParameter(reader);
m_Samplers = new SamplerParameter[numSamplers]; }
for (int i = 0; i < numSamplers; i++) }
}
public class SerializedSubProgram
{
public uint m_BlobIndex;
public ParserBindChannels m_Channels;
public ushort[] m_KeywordIndices;
public sbyte m_ShaderHardwareTier;
public ShaderGpuProgramType m_GpuProgramType;
public SerializedProgramParameters m_Parameters;
public VectorParameter[] m_VectorParams;
public MatrixParameter[] m_MatrixParams;
public TextureParameter[] m_TextureParams;
public BufferBinding[] m_BufferParams;
public ConstantBuffer[] m_ConstantBuffers;
public BufferBinding[] m_ConstantBufferBindings;
public UAVParameter[] m_UAVParams;
public SamplerParameter[] m_Samplers;
public SerializedSubProgram(ObjectReader reader)
{
var version = reader.version;
m_BlobIndex = reader.ReadUInt32();
m_Channels = new ParserBindChannels(reader);
if ((version[0] >= 2019 && version[0] < 2021) || (version[0] == 2021 && version[1] < 2)) //2019 ~2021.1
{
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
var m_LocalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
}
else
{
m_KeywordIndices = reader.ReadUInt16Array();
if (version[0] >= 2017) //2017 and up
{ {
m_Samplers[i] = new SamplerParameter(reader); reader.AlignStream();
} }
} }
m_ShaderHardwareTier = reader.ReadSByte();
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
reader.AlignStream();
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] > 2021) ||
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
{
m_Parameters = new SerializedProgramParameters(reader);
}
else
{
int numVectorParams = reader.ReadInt32();
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams[i] = new VectorParameter(reader);
}
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new MatrixParameter[numMatrixParams];
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams[i] = new MatrixParameter(reader);
}
int numTextureParams = reader.ReadInt32();
m_TextureParams = new TextureParameter[numTextureParams];
for (int i = 0; i < numTextureParams; i++)
{
m_TextureParams[i] = new TextureParameter(reader);
}
int numBufferParams = reader.ReadInt32();
m_BufferParams = new BufferBinding[numBufferParams];
for (int i = 0; i < numBufferParams; i++)
{
m_BufferParams[i] = new BufferBinding(reader);
}
int numConstantBuffers = reader.ReadInt32();
m_ConstantBuffers = new ConstantBuffer[numConstantBuffers];
for (int i = 0; i < numConstantBuffers; i++)
{
m_ConstantBuffers[i] = new ConstantBuffer(reader);
}
int numConstantBufferBindings = reader.ReadInt32();
m_ConstantBufferBindings = new BufferBinding[numConstantBufferBindings];
for (int i = 0; i < numConstantBufferBindings; i++)
{
m_ConstantBufferBindings[i] = new BufferBinding(reader);
}
int numUAVParams = reader.ReadInt32();
m_UAVParams = new UAVParameter[numUAVParams];
for (int i = 0; i < numUAVParams; i++)
{
m_UAVParams[i] = new UAVParameter(reader);
}
if (version[0] >= 2017) //2017 and up
{
int numSamplers = reader.ReadInt32();
m_Samplers = new SamplerParameter[numSamplers];
for (int i = 0; i < numSamplers; i++)
{
m_Samplers[i] = new SamplerParameter(reader);
}
}
}
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{ {
if (version[0] >= 2021) //2021.1 and up if (version[0] >= 2021) //2021.1 and up
@@ -595,23 +691,42 @@ namespace AssetStudio
public class SerializedProgram public class SerializedProgram
{ {
public SerializedSubProgram[] m_SubPrograms; public SerializedSubProgram[] m_SubPrograms;
public SerializedProgramParameters m_CommonParameters;
public ushort[] m_SerializedKeywordStateMask;
public SerializedProgram(ObjectReader reader) public SerializedProgram(ObjectReader reader)
{ {
var version = reader.version;
int numSubPrograms = reader.ReadInt32(); int numSubPrograms = reader.ReadInt32();
m_SubPrograms = new SerializedSubProgram[numSubPrograms]; m_SubPrograms = new SerializedSubProgram[numSubPrograms];
for (int i = 0; i < numSubPrograms; i++) for (int i = 0; i < numSubPrograms; i++)
{ {
m_SubPrograms[i] = new SerializedSubProgram(reader); m_SubPrograms[i] = new SerializedSubProgram(reader);
} }
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] > 2021) ||
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
{
m_CommonParameters = new SerializedProgramParameters(reader);
}
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
{
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
reader.AlignStream();
}
} }
} }
public enum PassType public enum PassType
{ {
kPassTypeNormal = 0, Normal = 0,
kPassTypeUse = 1, Use = 1,
kPassTypeGrab = 2 Grab = 2
}; };
public class SerializedPass public class SerializedPass
@@ -635,6 +750,7 @@ namespace AssetStudio
public string m_Name; public string m_Name;
public string m_TextureName; public string m_TextureName;
public SerializedTagMap m_Tags; public SerializedTagMap m_Tags;
public ushort[] m_SerializedKeywordStateMask;
public SerializedPass(ObjectReader reader) public SerializedPass(ObjectReader reader)
{ {
@@ -651,10 +767,13 @@ namespace AssetStudio
reader.AlignStream(); reader.AlignStream();
m_Platforms = reader.ReadUInt8Array(); m_Platforms = reader.ReadUInt8Array();
reader.AlignStream(); reader.AlignStream();
m_LocalKeywordMask = reader.ReadUInt16Array(); if (version[0] < 2021 || (version[0] == 2021 && version[1] < 2)) //2021.1 and down
reader.AlignStream(); {
m_GlobalKeywordMask = reader.ReadUInt16Array(); m_LocalKeywordMask = reader.ReadUInt16Array();
reader.AlignStream(); reader.AlignStream();
m_GlobalKeywordMask = reader.ReadUInt16Array();
reader.AlignStream();
}
} }
int numIndices = reader.ReadInt32(); int numIndices = reader.ReadInt32();
@@ -686,6 +805,11 @@ namespace AssetStudio
m_Name = reader.ReadAlignedString(); m_Name = reader.ReadAlignedString();
m_TextureName = reader.ReadAlignedString(); m_TextureName = reader.ReadAlignedString();
m_Tags = new SerializedTagMap(reader); m_Tags = new SerializedTagMap(reader);
if (version[0] == 2021 && version[1] >= 2) //2021.2 ~2021.x
{
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
reader.AlignStream();
}
} }
} }
@@ -752,6 +876,8 @@ namespace AssetStudio
{ {
public SerializedProperties m_PropInfo; public SerializedProperties m_PropInfo;
public SerializedSubShader[] m_SubShaders; public SerializedSubShader[] m_SubShaders;
public string[] m_KeywordNames;
public byte[] m_KeywordFlags;
public string m_Name; public string m_Name;
public string m_CustomEditorName; public string m_CustomEditorName;
public string m_FallbackName; public string m_FallbackName;
@@ -772,6 +898,13 @@ namespace AssetStudio
m_SubShaders[i] = new SerializedSubShader(reader); 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_Name = reader.ReadAlignedString();
m_CustomEditorName = reader.ReadAlignedString(); m_CustomEditorName = reader.ReadAlignedString();
m_FallbackName = reader.ReadAlignedString(); m_FallbackName = reader.ReadAlignedString();
@@ -800,32 +933,32 @@ namespace AssetStudio
public enum ShaderCompilerPlatform public enum ShaderCompilerPlatform
{ {
kShaderCompPlatformNone = -1, None = -1,
kShaderCompPlatformGL = 0, GL = 0,
kShaderCompPlatformD3D9 = 1, D3D9 = 1,
kShaderCompPlatformXbox360 = 2, Xbox360 = 2,
kShaderCompPlatformPS3 = 3, PS3 = 3,
kShaderCompPlatformD3D11 = 4, D3D11 = 4,
kShaderCompPlatformGLES20 = 5, GLES20 = 5,
kShaderCompPlatformNaCl = 6, NaCl = 6,
kShaderCompPlatformFlash = 7, Flash = 7,
kShaderCompPlatformD3D11_9x = 8, D3D11_9x = 8,
kShaderCompPlatformGLES3Plus = 9, GLES3Plus = 9,
kShaderCompPlatformPSP2 = 10, PSP2 = 10,
kShaderCompPlatformPS4 = 11, PS4 = 11,
kShaderCompPlatformXboxOne = 12, XboxOne = 12,
kShaderCompPlatformPSM = 13, PSM = 13,
kShaderCompPlatformMetal = 14, Metal = 14,
kShaderCompPlatformOpenGLCore = 15, OpenGLCore = 15,
kShaderCompPlatformN3DS = 16, N3DS = 16,
kShaderCompPlatformWiiU = 17, WiiU = 17,
kShaderCompPlatformVulkan = 18, Vulkan = 18,
kShaderCompPlatformSwitch = 19, Switch = 19,
kShaderCompPlatformXboxOneD3D12 = 20, XboxOneD3D12 = 20,
kShaderCompPlatformGameCoreXboxOne = 21, GameCoreXboxOne = 21,
kShaderCompPlatformGameCoreScarlett = 22, GameCoreScarlett = 22,
kShaderCompPlatformPS5 = 23, PS5 = 23,
kShaderCompPlatformPS5NGGC = 24, PS5NGGC = 24
}; };
public class Shader : NamedObject public class Shader : NamedObject
@@ -837,9 +970,9 @@ namespace AssetStudio
//5.5 and up //5.5 and up
public SerializedShader m_ParsedForm; public SerializedShader m_ParsedForm;
public ShaderCompilerPlatform[] platforms; public ShaderCompilerPlatform[] platforms;
public uint[] offsets; public uint[][] offsets;
public uint[] compressedLengths; public uint[][] compressedLengths;
public uint[] decompressedLengths; public uint[][] decompressedLengths;
public byte[] compressedBlob; public byte[] compressedBlob;
public Shader(ObjectReader reader) : base(reader) public Shader(ObjectReader reader) : base(reader)
@@ -850,17 +983,37 @@ namespace AssetStudio
platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray(); platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{ {
offsets = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray(); offsets = reader.ReadUInt32ArrayArray();
compressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray(); compressedLengths = reader.ReadUInt32ArrayArray();
decompressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray(); decompressedLengths = reader.ReadUInt32ArrayArray();
} }
else else
{ {
offsets = reader.ReadUInt32Array(); offsets = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
compressedLengths = reader.ReadUInt32Array(); compressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
decompressedLengths = reader.ReadUInt32Array(); decompressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
} }
compressedBlob = reader.ReadUInt8Array(); compressedBlob = reader.ReadUInt8Array();
reader.AlignStream();
var m_DependenciesCount = reader.ReadInt32();
for (int i = 0; i < m_DependenciesCount; i++)
{
new PPtr<Shader>(reader);
}
if (version[0] >= 2018)
{
var m_NonModifiableTexturesCount = reader.ReadInt32();
for (int i = 0; i < m_NonModifiableTexturesCount; i++)
{
var first = reader.ReadAlignedString();
new PPtr<Texture>(reader);
}
}
var m_ShaderIsBaked = reader.ReadBoolean();
reader.AlignStream();
} }
else else
{ {
+10 -10
View File
@@ -18,23 +18,23 @@ namespace AssetStudio
public enum SpritePackingRotation public enum SpritePackingRotation
{ {
kSPRNone = 0, None = 0,
kSPRFlipHorizontal = 1, FlipHorizontal = 1,
kSPRFlipVertical = 2, FlipVertical = 2,
kSPRRotate180 = 3, Rotate180 = 3,
kSPRRotate90 = 4 Rotate90 = 4
}; };
public enum SpritePackingMode public enum SpritePackingMode
{ {
kSPMTight = 0, Tight = 0,
kSPMRectangle Rectangle
}; };
public enum SpriteMeshType public enum SpriteMeshType
{ {
kSpriteMeshTypeFullRect, FullRect,
kSpriteMeshTypeTight Tight
}; };
public class SpriteSettings public class SpriteSettings
@@ -197,7 +197,7 @@ namespace AssetStudio
public Vector2 m_Offset; public Vector2 m_Offset;
public Vector4 m_Border; public Vector4 m_Border;
public float m_PixelsToUnits; public float m_PixelsToUnits;
public Vector2 m_Pivot; public Vector2 m_Pivot = new Vector2(0.5f, 0.5f);
public uint m_Extrude; public uint m_Extrude;
public bool m_IsPolygon; public bool m_IsPolygon;
public KeyValuePair<Guid, long> m_RenderDataKey; public KeyValuePair<Guid, long> m_RenderDataKey;
+4 -2
View File
@@ -46,6 +46,7 @@ namespace AssetStudio
{ {
public PPtr<Sprite>[] m_PackedSprites; public PPtr<Sprite>[] m_PackedSprites;
public Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> m_RenderDataMap; public Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> m_RenderDataMap;
public bool m_IsVariant;
public SpriteAtlas(ObjectReader reader) : base(reader) public SpriteAtlas(ObjectReader reader) : base(reader)
{ {
@@ -67,8 +68,9 @@ namespace AssetStudio
var value = new SpriteAtlasData(reader); var value = new SpriteAtlasData(reader);
m_RenderDataMap.Add(new KeyValuePair<Guid, long>(first, second), value); m_RenderDataMap.Add(new KeyValuePair<Guid, long>(first, second), value);
} }
//string m_Tag var m_Tag = reader.ReadAlignedString();
//bool m_IsVariant m_IsVariant = reader.ReadBoolean();
reader.AlignStream();
} }
} }
} }
+14 -10
View File
@@ -4,7 +4,7 @@ namespace AssetStudio
{ {
public class StreamingInfo public class StreamingInfo
{ {
public ulong offset; public long offset; //ulong
public uint size; public uint size;
public string path; public string path;
@@ -14,7 +14,7 @@ namespace AssetStudio
if (version[0] >= 2020) //2020.1 and up if (version[0] >= 2020) //2020.1 and up
{ {
offset = reader.ReadUInt64(); offset = reader.ReadInt64();
} }
else else
{ {
@@ -134,7 +134,7 @@ namespace AssetStudio
ResourceReader resourceReader; ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_StreamData?.path)) 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 else
{ {
@@ -151,10 +151,13 @@ namespace AssetStudio
RGB24, RGB24,
RGBA32, RGBA32,
ARGB32, ARGB32,
RGB565 = 7, ARGBFloat,
R16 = 9, RGB565,
BGR24,
R16,
DXT1, DXT1,
DXT5 = 12, DXT3,
DXT5,
RGBA4444, RGBA4444,
BGRA32, BGRA32,
RHalf, RHalf,
@@ -165,11 +168,12 @@ namespace AssetStudio
RGBAFloat, RGBAFloat,
YUY2, YUY2,
RGB9e5Float, RGB9e5Float,
BC4 = 26, RGBFloat,
BC5, BC6H,
BC6H = 24,
BC7, BC7,
DXT1Crunched = 28, BC4,
BC5,
DXT1Crunched,
DXT5Crunched, DXT5Crunched,
PVRTC_RGB2, PVRTC_RGB2,
PVRTC_RGBA2, PVRTC_RGBA2,
+6 -6
View File
@@ -5,14 +5,14 @@ namespace AssetStudio
public class StreamedResource public class StreamedResource
{ {
public string m_Source; public string m_Source;
public ulong m_Offset; public long m_Offset; //ulong
public ulong m_Size; public long m_Size; //ulong
public StreamedResource(BinaryReader reader) public StreamedResource(BinaryReader reader)
{ {
m_Source = reader.ReadAlignedString(); m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadUInt64(); m_Offset = reader.ReadInt64();
m_Size = reader.ReadUInt64(); m_Size = reader.ReadInt64();
} }
} }
@@ -60,11 +60,11 @@ namespace AssetStudio
ResourceReader resourceReader; ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_ExternalResources.m_Source)) 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 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; m_VideoData = resourceReader;
} }
+32 -42
View File
@@ -1,23 +1,19 @@
using System; using System;
using System.Collections.Generic; using System.Buffers.Binary;
using System.Text;
using System.IO; using System.IO;
namespace AssetStudio namespace AssetStudio
{ {
public enum EndianType
{
LittleEndian,
BigEndian
}
public class EndianBinaryReader : BinaryReader public class EndianBinaryReader : BinaryReader
{ {
public EndianType endian; private readonly byte[] buffer;
public EndianType Endian;
public EndianBinaryReader(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream) public EndianBinaryReader(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream)
{ {
this.endian = endian; Endian = endian;
buffer = new byte[8];
} }
public long Position public long Position
@@ -28,88 +24,82 @@ namespace AssetStudio
public override short ReadInt16() public override short ReadInt16()
{ {
if (endian == EndianType.BigEndian) if (Endian == EndianType.BigEndian)
{ {
var buff = ReadBytes(2); Read(buffer, 0, 2);
Array.Reverse(buff); return BinaryPrimitives.ReadInt16BigEndian(buffer);
return BitConverter.ToInt16(buff, 0);
} }
return base.ReadInt16(); return base.ReadInt16();
} }
public override int ReadInt32() public override int ReadInt32()
{ {
if (endian == EndianType.BigEndian) if (Endian == EndianType.BigEndian)
{ {
var buff = ReadBytes(4); Read(buffer, 0, 4);
Array.Reverse(buff); return BinaryPrimitives.ReadInt32BigEndian(buffer);
return BitConverter.ToInt32(buff, 0);
} }
return base.ReadInt32(); return base.ReadInt32();
} }
public override long ReadInt64() public override long ReadInt64()
{ {
if (endian == EndianType.BigEndian) if (Endian == EndianType.BigEndian)
{ {
var buff = ReadBytes(8); Read(buffer, 0, 8);
Array.Reverse(buff); return BinaryPrimitives.ReadInt64BigEndian(buffer);
return BitConverter.ToInt64(buff, 0);
} }
return base.ReadInt64(); return base.ReadInt64();
} }
public override ushort ReadUInt16() public override ushort ReadUInt16()
{ {
if (endian == EndianType.BigEndian) if (Endian == EndianType.BigEndian)
{ {
var buff = ReadBytes(2); Read(buffer, 0, 2);
Array.Reverse(buff); return BinaryPrimitives.ReadUInt16BigEndian(buffer);
return BitConverter.ToUInt16(buff, 0);
} }
return base.ReadUInt16(); return base.ReadUInt16();
} }
public override uint ReadUInt32() public override uint ReadUInt32()
{ {
if (endian == EndianType.BigEndian) if (Endian == EndianType.BigEndian)
{ {
var buff = ReadBytes(4); Read(buffer, 0, 4);
Array.Reverse(buff); return BinaryPrimitives.ReadUInt32BigEndian(buffer);
return BitConverter.ToUInt32(buff, 0);
} }
return base.ReadUInt32(); return base.ReadUInt32();
} }
public override ulong ReadUInt64() public override ulong ReadUInt64()
{ {
if (endian == EndianType.BigEndian) if (Endian == EndianType.BigEndian)
{ {
var buff = ReadBytes(8); Read(buffer, 0, 8);
Array.Reverse(buff); return BinaryPrimitives.ReadUInt64BigEndian(buffer);
return BitConverter.ToUInt64(buff, 0);
} }
return base.ReadUInt64(); return base.ReadUInt64();
} }
public override float ReadSingle() public override float ReadSingle()
{ {
if (endian == EndianType.BigEndian) if (Endian == EndianType.BigEndian)
{ {
var buff = ReadBytes(4); Read(buffer, 0, 4);
Array.Reverse(buff); Array.Reverse(buffer, 0, 4);
return BitConverter.ToSingle(buff, 0); return BitConverter.ToSingle(buffer, 0);
} }
return base.ReadSingle(); return base.ReadSingle();
} }
public override double ReadDouble() public override double ReadDouble()
{ {
if (endian == EndianType.BigEndian) if (Endian == EndianType.BigEndian)
{ {
var buff = ReadBytes(8); Read(buffer, 0, 8);
Array.Reverse(buff); Array.Reverse(buffer);
return BitConverter.ToUInt64(buff, 0); return BitConverter.ToDouble(buffer, 0);
} }
return base.ReadDouble(); return base.ReadDouble();
} }
+14
View File
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AssetStudio
{
public enum EndianType
{
LittleEndian,
BigEndian
}
}
+103
View File
@@ -0,0 +1,103 @@
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 };
private static readonly byte[] zipMagic = { 0x50, 0x4B, 0x03, 0x04 };
private static readonly byte[] zipSpannedMagic = { 0x50, 0x4B, 0x07, 0x08 };
public FileReader(string path) : this(path, File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { }
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:
{
byte[] 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;
}
magic = ReadBytes(4);
Position = 0;
if (zipMagic.SequenceEqual(magic) || zipSpannedMagic.SequenceEqual(magic))
return FileType.ZipFile;
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;
}
}
}
+19
View File
@@ -0,0 +1,19 @@
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,
ZipFile
}
}
+24 -1
View File
@@ -73,6 +73,28 @@ namespace AssetStudio
return null; return null;
} }
public ImportedFrame FindRelativeFrameWithPath(string path)
{
var subs = path.Split(new[] { '/' }, 2);
foreach (var child in children)
{
if (child.Name == subs[0])
{
if (subs.Length == 1)
{
return child;
}
else
{
var result = child.FindRelativeFrameWithPath(subs[1]);
if (result != null)
return result;
}
}
}
return null;
}
public ImportedFrame FindFrame(string name) public ImportedFrame FindFrame(string name)
{ {
if (Name == name) if (Name == name)
@@ -132,6 +154,7 @@ namespace AssetStudio
public class ImportedMesh public class ImportedMesh
{ {
public string Path { get; set; } public string Path { get; set; }
public List<ImportedVertex> VertexList { get; set; }
public List<ImportedSubmesh> SubmeshList { get; set; } public List<ImportedSubmesh> SubmeshList { get; set; }
public List<ImportedBone> BoneList { get; set; } public List<ImportedBone> BoneList { get; set; }
public bool hasNormal { get; set; } public bool hasNormal { get; set; }
@@ -142,9 +165,9 @@ namespace AssetStudio
public class ImportedSubmesh public class ImportedSubmesh
{ {
public List<ImportedVertex> VertexList { get; set; }
public List<ImportedFace> FaceList { get; set; } public List<ImportedFace> FaceList { get; set; }
public string Material { get; set; } public string Material { get; set; }
public int BaseVertex { get; set; }
} }
public class ImportedVertex public class ImportedVertex
-17
View File
@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public interface IProgress
{
void Report(int value);
}
public sealed class DummyProgress : IProgress
{
public void Report(int value) { }
}
}
+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;
using System.IO.Compression;
using System.Linq; using System.Linq;
namespace AssetStudio namespace AssetStudio
{ {
public enum FileType
{
AssetsFile,
BundleFile,
WebFile,
ResourceFile
}
public static class ImportHelper public static class ImportHelper
{ {
public static void MergeSplitAssets(string path, bool allDirectories = false) public static void MergeSplitAssets(string path, bool allDirectories = false)
@@ -57,55 +51,31 @@ namespace AssetStudio
return selectFile.Distinct().ToArray(); return selectFile.Distinct().ToArray();
} }
public static FileType CheckFileType(Stream stream, out EndianBinaryReader reader) public static FileReader DecompressGZip(FileReader reader)
{ {
reader = new EndianBinaryReader(stream); using (reader)
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)
{ {
case "UnityWeb": var stream = new MemoryStream();
case "UnityRaw": using (var gs = new GZipStream(reader.BaseStream, CompressionMode.Decompress))
case "UnityArchive": {
case "UnityFS": gs.CopyTo(stream);
return FileType.BundleFile; }
case "UnityWebData1.0": stream.Position = 0;
return FileType.WebFile; return new FileReader(reader.FullPath, stream);
default: }
{ }
var magic = reader.ReadBytes(2);
reader.Position = 0; public static FileReader DecompressBrotli(FileReader reader)
if (WebFile.gzipMagic.SequenceEqual(magic)) {
{ using (reader)
return FileType.WebFile; {
} var stream = new MemoryStream();
reader.Position = 0x20; using (var brotliStream = new BrotliInputStream(reader.BaseStream))
magic = reader.ReadBytes(6); {
reader.Position = 0; brotliStream.CopyTo(stream);
if (WebFile.brotliMagic.SequenceEqual(magic)) }
{ stream.Position = 0;
return FileType.WebFile; return new FileReader(reader.FullPath, stream);
}
if (SerializedFile.IsSerializedFile(reader))
{
return FileType.AssetsFile;
}
else
{
return FileType.ResourceFile;
}
}
} }
} }
} }
+8
View File
@@ -14,5 +14,13 @@ namespace AssetStudio
public static void Info(string message) => Default.Log(LoggerEvent.Info, message); public static void Info(string message) => Default.Log(LoggerEvent.Info, message);
public static void Warning(string message) => Default.Log(LoggerEvent.Warning, message); public static void Warning(string message) => Default.Log(LoggerEvent.Warning, message);
public static void Error(string message) => Default.Log(LoggerEvent.Error, message); public static void Error(string message) => Default.Log(LoggerEvent.Error, message);
public static void Error(string message, Exception e)
{
var sb = new StringBuilder();
sb.AppendLine(message);
sb.AppendLine(e.ToString());
Default.Log(LoggerEvent.Error, sb.ToString());
}
} }
} }
-540
View File
@@ -1,540 +0,0 @@
#define CHECK_ARGS
#define CHECK_EOF
//#define LOCAL_SHADOW
using System;
using System.IO;
namespace Lz4
{
public class Lz4DecoderStream : Stream
{
public Lz4DecoderStream(Stream input, long inputLength = long.MaxValue)
{
Reset(input, inputLength);
}
private void Reset(Stream input, long inputLength = long.MaxValue)
{
this.inputLength = inputLength;
this.input = input;
phase = DecodePhase.ReadToken;
decodeBufferPos = 0;
litLen = 0;
matLen = 0;
matDst = 0;
inBufPos = DecBufLen;
inBufEnd = DecBufLen;
}
protected override void Dispose(bool disposing)
{
try
{
if (disposing && input != null)
{
input.Close();
}
input = null;
decodeBuffer = null;
}
finally
{
base.Dispose(disposing);
}
}
private long inputLength;
private Stream input;
//because we might not be able to match back across invocations,
//we have to keep the last window's worth of bytes around for reuse
//we use a circular buffer for this - every time we write into this
//buffer, we also write the same into our output buffer
private const int DecBufLen = 0x10000;
private const int DecBufMask = 0xFFFF;
private const int InBufLen = 128;
private byte[] decodeBuffer = new byte[DecBufLen + InBufLen];
private int decodeBufferPos, inBufPos, inBufEnd;
//we keep track of which phase we're in so that we can jump right back
//into the correct part of decoding
private DecodePhase phase;
private enum DecodePhase
{
ReadToken,
ReadExLiteralLength,
CopyLiteral,
ReadOffset,
ReadExMatchLength,
CopyMatch,
}
//state within interruptable phases and across phase boundaries is
//kept here - again, so that we can punt out and restart freely
private int litLen, matLen, matDst;
public override int Read(byte[] buffer, int offset, int count)
{
#if CHECK_ARGS
if (buffer == null)
throw new ArgumentNullException("buffer");
if (offset < 0 || count < 0 || buffer.Length - count < offset)
throw new ArgumentOutOfRangeException();
if (input == null)
throw new InvalidOperationException();
#endif
int nRead, nToRead = count;
var decBuf = decodeBuffer;
//the stringy gotos are obnoxious, but their purpose is to
//make it *blindingly* obvious how the state machine transitions
//back and forth as it reads - remember, we can yield out of
//this routine in several places, and we must be able to re-enter
//and pick up where we left off!
#if LOCAL_SHADOW
var phase = this.phase;
var inBufPos = this.inBufPos;
var inBufEnd = this.inBufEnd;
#endif
switch (phase)
{
case DecodePhase.ReadToken:
goto readToken;
case DecodePhase.ReadExLiteralLength:
goto readExLiteralLength;
case DecodePhase.CopyLiteral:
goto copyLiteral;
case DecodePhase.ReadOffset:
goto readOffset;
case DecodePhase.ReadExMatchLength:
goto readExMatchLength;
case DecodePhase.CopyMatch:
goto copyMatch;
}
readToken:
int tok;
if (inBufPos < inBufEnd)
{
tok = decBuf[inBufPos++];
}
else
{
#if LOCAL_SHADOW
this.inBufPos = inBufPos;
#endif
tok = ReadByteCore();
#if LOCAL_SHADOW
inBufPos = this.inBufPos;
inBufEnd = this.inBufEnd;
#endif
#if CHECK_EOF
if (tok == -1)
goto finish;
#endif
}
litLen = tok >> 4;
matLen = (tok & 0xF) + 4;
switch (litLen)
{
case 0:
phase = DecodePhase.ReadOffset;
goto readOffset;
case 0xF:
phase = DecodePhase.ReadExLiteralLength;
goto readExLiteralLength;
default:
phase = DecodePhase.CopyLiteral;
goto copyLiteral;
}
readExLiteralLength:
int exLitLen;
if (inBufPos < inBufEnd)
{
exLitLen = decBuf[inBufPos++];
}
else
{
#if LOCAL_SHADOW
this.inBufPos = inBufPos;
#endif
exLitLen = ReadByteCore();
#if LOCAL_SHADOW
inBufPos = this.inBufPos;
inBufEnd = this.inBufEnd;
#endif
#if CHECK_EOF
if (exLitLen == -1)
goto finish;
#endif
}
litLen += exLitLen;
if (exLitLen == 255)
goto readExLiteralLength;
phase = DecodePhase.CopyLiteral;
goto copyLiteral;
copyLiteral:
int nReadLit = litLen < nToRead ? litLen : nToRead;
if (nReadLit != 0)
{
if (inBufPos + nReadLit <= inBufEnd)
{
int ofs = offset;
for (int c = nReadLit; c-- != 0;)
buffer[ofs++] = decBuf[inBufPos++];
nRead = nReadLit;
}
else
{
#if LOCAL_SHADOW
this.inBufPos = inBufPos;
#endif
nRead = ReadCore(buffer, offset, nReadLit);
#if LOCAL_SHADOW
inBufPos = this.inBufPos;
inBufEnd = this.inBufEnd;
#endif
#if CHECK_EOF
if (nRead == 0)
goto finish;
#endif
}
offset += nRead;
nToRead -= nRead;
litLen -= nRead;
if (litLen != 0)
goto copyLiteral;
}
if (nToRead == 0)
goto finish;
phase = DecodePhase.ReadOffset;
goto readOffset;
readOffset:
if (inBufPos + 1 < inBufEnd)
{
matDst = (decBuf[inBufPos + 1] << 8) | decBuf[inBufPos];
inBufPos += 2;
}
else
{
#if LOCAL_SHADOW
this.inBufPos = inBufPos;
#endif
matDst = ReadOffsetCore();
#if LOCAL_SHADOW
inBufPos = this.inBufPos;
inBufEnd = this.inBufEnd;
#endif
#if CHECK_EOF
if (matDst == -1)
goto finish;
#endif
}
if (matLen == 15 + 4)
{
phase = DecodePhase.ReadExMatchLength;
goto readExMatchLength;
}
else
{
phase = DecodePhase.CopyMatch;
goto copyMatch;
}
readExMatchLength:
int exMatLen;
if (inBufPos < inBufEnd)
{
exMatLen = decBuf[inBufPos++];
}
else
{
#if LOCAL_SHADOW
this.inBufPos = inBufPos;
#endif
exMatLen = ReadByteCore();
#if LOCAL_SHADOW
inBufPos = this.inBufPos;
inBufEnd = this.inBufEnd;
#endif
#if CHECK_EOF
if (exMatLen == -1)
goto finish;
#endif
}
matLen += exMatLen;
if (exMatLen == 255)
goto readExMatchLength;
phase = DecodePhase.CopyMatch;
goto copyMatch;
copyMatch:
int nCpyMat = matLen < nToRead ? matLen : nToRead;
if (nCpyMat != 0)
{
nRead = count - nToRead;
int bufDst = matDst - nRead;
if (bufDst > 0)
{
//offset is fairly far back, we need to pull from the buffer
int bufSrc = decodeBufferPos - bufDst;
if (bufSrc < 0)
bufSrc += DecBufLen;
int bufCnt = bufDst < nCpyMat ? bufDst : nCpyMat;
for (int c = bufCnt; c-- != 0;)
buffer[offset++] = decBuf[bufSrc++ & DecBufMask];
}
else
{
bufDst = 0;
}
int sOfs = offset - matDst;
for (int i = bufDst; i < nCpyMat; i++)
buffer[offset++] = buffer[sOfs++];
nToRead -= nCpyMat;
matLen -= nCpyMat;
}
if (nToRead == 0)
goto finish;
phase = DecodePhase.ReadToken;
goto readToken;
finish:
nRead = count - nToRead;
int nToBuf = nRead < DecBufLen ? nRead : DecBufLen;
int repPos = offset - nToBuf;
if (nToBuf == DecBufLen)
{
Buffer.BlockCopy(buffer, repPos, decBuf, 0, DecBufLen);
decodeBufferPos = 0;
}
else
{
int decPos = decodeBufferPos;
while (nToBuf-- != 0)
decBuf[decPos++ & DecBufMask] = buffer[repPos++];
decodeBufferPos = decPos & DecBufMask;
}
#if LOCAL_SHADOW
this.phase = phase;
this.inBufPos = inBufPos;
#endif
return nRead;
}
private int ReadByteCore()
{
var buf = decodeBuffer;
if (inBufPos == inBufEnd)
{
int nRead = input.Read(buf, DecBufLen,
InBufLen < inputLength ? InBufLen : (int)inputLength);
#if CHECK_EOF
if (nRead == 0)
return -1;
#endif
inputLength -= nRead;
inBufPos = DecBufLen;
inBufEnd = DecBufLen + nRead;
}
return buf[inBufPos++];
}
private int ReadOffsetCore()
{
var buf = decodeBuffer;
if (inBufPos == inBufEnd)
{
int nRead = input.Read(buf, DecBufLen,
InBufLen < inputLength ? InBufLen : (int)inputLength);
#if CHECK_EOF
if (nRead == 0)
return -1;
#endif
inputLength -= nRead;
inBufPos = DecBufLen;
inBufEnd = DecBufLen + nRead;
}
if (inBufEnd - inBufPos == 1)
{
buf[DecBufLen] = buf[inBufPos];
int nRead = input.Read(buf, DecBufLen + 1,
InBufLen - 1 < inputLength ? InBufLen - 1 : (int)inputLength);
#if CHECK_EOF
if (nRead == 0)
{
inBufPos = DecBufLen;
inBufEnd = DecBufLen + 1;
return -1;
}
#endif
inputLength -= nRead;
inBufPos = DecBufLen;
inBufEnd = DecBufLen + nRead + 1;
}
int ret = (buf[inBufPos + 1] << 8) | buf[inBufPos];
inBufPos += 2;
return ret;
}
private int ReadCore(byte[] buffer, int offset, int count)
{
int nToRead = count;
var buf = decodeBuffer;
int inBufLen = inBufEnd - inBufPos;
int fromBuf = nToRead < inBufLen ? nToRead : inBufLen;
if (fromBuf != 0)
{
var bufPos = inBufPos;
for (int c = fromBuf; c-- != 0;)
buffer[offset++] = buf[bufPos++];
inBufPos = bufPos;
nToRead -= fromBuf;
}
if (nToRead != 0)
{
int nRead;
if (nToRead >= InBufLen)
{
nRead = input.Read(buffer, offset,
nToRead < inputLength ? nToRead : (int)inputLength);
nToRead -= nRead;
}
else
{
nRead = input.Read(buf, DecBufLen,
InBufLen < inputLength ? InBufLen : (int)inputLength);
inBufPos = DecBufLen;
inBufEnd = DecBufLen + nRead;
fromBuf = nToRead < nRead ? nToRead : nRead;
var bufPos = inBufPos;
for (int c = fromBuf; c-- != 0;)
buffer[offset++] = buf[bufPos++];
inBufPos = bufPos;
nToRead -= fromBuf;
}
inputLength -= nRead;
}
return count - nToRead;
}
#region Stream internals
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override void Flush()
{
}
public override long Length => throw new NotSupportedException();
public override long Position
{
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
#endregion
}
}
+3 -3
View File
@@ -1,8 +1,8 @@
using System.Diagnostics; using System;
using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Runtime.InteropServices;
namespace System namespace AssetStudio
{ {
/// <summary> /// <summary>
/// Represents a half-precision floating point number. /// 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> /// <summary>
/// Helper class for Half conversions and some low level operations. /// Helper class for Half conversions and some low level operations.
+2
View File
@@ -11,6 +11,8 @@ namespace AssetStudio
public uint byteSize; public uint byteSize;
public int typeID; public int typeID;
public int classID; public int classID;
public ushort isDestroyed;
public byte stripped;
public long m_PathID; public long m_PathID;
public SerializedType serializedType; public SerializedType serializedType;
+2 -2
View File
@@ -15,12 +15,12 @@ namespace AssetStudio
public ClassIDType type; public ClassIDType type;
public SerializedType serializedType; public SerializedType serializedType;
public BuildTarget platform; public BuildTarget platform;
public uint m_Version; public SerializedFileFormatVersion m_Version;
public int[] version => assetsFile.version; public int[] version => assetsFile.version;
public BuildType buildType => assetsFile.buildType; public BuildType buildType => assetsFile.buildType;
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.endian) public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.Endian)
{ {
this.assetsFile = assetsFile; this.assetsFile = assetsFile;
m_PathID = objectInfo.m_PathID; m_PathID = objectInfo.m_PathID;
+4 -2
View File
@@ -1,8 +1,10 @@
namespace AssetStudio using System;
namespace AssetStudio
{ {
public static class Progress public static class Progress
{ {
public static IProgress Default = new DummyProgress(); public static IProgress<int> Default = new Progress<int>();
private static int preValue; private static int preValue;
public static void Reset() public static void Reset()
-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")]
+37 -16
View File
@@ -8,41 +8,39 @@ namespace AssetStudio
private string path; private string path;
private SerializedFile assetsFile; private SerializedFile assetsFile;
private long offset; private long offset;
private int size; private long size;
private BinaryReader reader; private BinaryReader reader;
public int Size { get => (int)size; }
public ResourceReader(string path, SerializedFile assetsFile, ulong offset, int size) public ResourceReader(string path, SerializedFile assetsFile, long offset, long size)
{ {
needSearch = true; needSearch = true;
this.path = path; this.path = path;
this.assetsFile = assetsFile; this.assetsFile = assetsFile;
this.offset = (long)offset; this.offset = offset;
this.size = size; this.size = size;
} }
public ResourceReader(BinaryReader reader, long offset, int size) public ResourceReader(BinaryReader reader, long offset, long size)
{ {
this.reader = reader; this.reader = reader;
this.offset = offset; this.offset = offset;
this.size = size; this.size = size;
} }
public byte[] GetData() private BinaryReader GetReader()
{ {
if (needSearch) if (needSearch)
{ {
var resourceFileName = Path.GetFileName(path); var resourceFileName = Path.GetFileName(path);
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader)) if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader))
{ {
needSearch = false; needSearch = false;
reader.BaseStream.Position = offset; return reader;
return reader.ReadBytes(size);
} }
var assetsFileDirectory = Path.GetDirectoryName(assetsFile.fullName); var assetsFileDirectory = Path.GetDirectoryName(assetsFile.fullName);
var resourceFilePath = assetsFileDirectory + Path.DirectorySeparatorChar + resourceFileName; var resourceFilePath = Path.Combine(assetsFileDirectory, resourceFileName);
if (!File.Exists(resourceFilePath)) if (!File.Exists(resourceFilePath))
{ {
var findFiles = Directory.GetFiles(assetsFileDirectory, resourceFileName, SearchOption.AllDirectories); var findFiles = Directory.GetFiles(assetsFileDirectory, resourceFileName, SearchOption.AllDirectories);
@@ -53,18 +51,41 @@ namespace AssetStudio
} }
if (File.Exists(resourceFilePath)) if (File.Exists(resourceFilePath))
{ {
reader = new BinaryReader(File.OpenRead(resourceFilePath));
needSearch = false; needSearch = false;
reader = new BinaryReader(File.OpenRead(resourceFilePath));
assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader); assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader);
reader.BaseStream.Position = offset; return reader;
return reader.ReadBytes(size);
} }
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}"); throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
} }
else
{
return reader;
}
}
reader.BaseStream.Position = offset; public byte[] GetData()
return reader.ReadBytes(size); {
var binaryReader = GetReader();
binaryReader.BaseStream.Position = offset;
return binaryReader.ReadBytes((int)size);
}
public void GetData(byte[] buff)
{
var binaryReader = GetReader();
binaryReader.BaseStream.Position = offset;
binaryReader.Read(buff, 0, (int)size);
}
public void WriteData(string path)
{
var binaryReader = GetReader();
binaryReader.BaseStream.Position = offset;
using (var writer = File.OpenWrite(path))
{
binaryReader.BaseStream.CopyTo(writer, size);
}
} }
} }
} }
+94 -112
View File
@@ -9,7 +9,7 @@ namespace AssetStudio
public class SerializedFile public class SerializedFile
{ {
public AssetsManager assetsManager; public AssetsManager assetsManager;
public EndianBinaryReader reader; public FileReader reader;
public string fullName; public string fullName;
public string originalPath; public string originalPath;
public string fileName; public string fileName;
@@ -19,43 +19,45 @@ namespace AssetStudio
public Dictionary<long, Object> ObjectsDic; public Dictionary<long, Object> ObjectsDic;
public SerializedFileHeader header; public SerializedFileHeader header;
private EndianType m_FileEndianess; private byte m_FileEndianess;
public string unityVersion = "2.5.0f5"; public string unityVersion = "2.5.0f5";
public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform; public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform;
private bool m_EnableTypeTree = true; private bool m_EnableTypeTree = true;
public List<SerializedType> m_Types; public List<SerializedType> m_Types;
public List<SerializedType> m_RefTypes; public int bigIDEnabled = 0;
public List<ObjectInfo> m_Objects; public List<ObjectInfo> m_Objects;
private List<LocalSerializedObjectIdentifier> m_ScriptTypes; private List<LocalSerializedObjectIdentifier> m_ScriptTypes;
public List<FileIdentifier> m_Externals; public List<FileIdentifier> m_Externals;
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.assetsManager = assetsManager;
this.reader = reader; this.reader = reader;
this.fullName = fullName; fullName = reader.FullPath;
fileName = Path.GetFileName(fullName); fileName = reader.FileName;
//ReadHeader // ReadHeader
header = new SerializedFileHeader(); header = new SerializedFileHeader();
header.m_MetadataSize = reader.ReadUInt32(); header.m_MetadataSize = reader.ReadUInt32();
header.m_FileSize = reader.ReadUInt32(); header.m_FileSize = reader.ReadUInt32();
header.m_Version = reader.ReadUInt32(); header.m_Version = (SerializedFileFormatVersion)reader.ReadUInt32();
header.m_DataOffset = reader.ReadUInt32(); header.m_DataOffset = reader.ReadUInt32();
if (header.m_Version >= 9) if (header.m_Version >= SerializedFileFormatVersion.Unknown_9)
{ {
header.m_Endianess = reader.ReadByte(); header.m_Endianess = reader.ReadByte();
header.m_Reserved = reader.ReadBytes(3); header.m_Reserved = reader.ReadBytes(3);
m_FileEndianess = (EndianType)header.m_Endianess; m_FileEndianess = header.m_Endianess;
} }
else else
{ {
reader.Position = header.m_FileSize - header.m_MetadataSize; reader.Position = header.m_FileSize - header.m_MetadataSize;
m_FileEndianess = (EndianType)reader.ReadByte(); m_FileEndianess = reader.ReadByte();
} }
if (header.m_Version >= 22) if (header.m_Version >= SerializedFileFormatVersion.LargeFilesSupport)
{ {
header.m_MetadataSize = reader.ReadUInt32(); header.m_MetadataSize = reader.ReadUInt32();
header.m_FileSize = reader.ReadInt64(); header.m_FileSize = reader.ReadInt64();
@@ -63,17 +65,17 @@ namespace AssetStudio
reader.ReadInt64(); // unknown reader.ReadInt64(); // unknown
} }
//ReadMetadata // ReadMetadata
if (m_FileEndianess == EndianType.LittleEndian) if (m_FileEndianess == 0)
{ {
reader.endian = EndianType.LittleEndian; reader.Endian = EndianType.LittleEndian;
} }
if (header.m_Version >= 7) if (header.m_Version >= SerializedFileFormatVersion.Unknown_7)
{ {
unityVersion = reader.ReadStringToNull(); unityVersion = reader.ReadStringToNull();
SetVersion(unityVersion); SetVersion(unityVersion);
} }
if (header.m_Version >= 8) if (header.m_Version >= SerializedFileFormatVersion.Unknown_8)
{ {
m_TargetPlatform = (BuildTarget)reader.ReadInt32(); m_TargetPlatform = (BuildTarget)reader.ReadInt32();
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform)) if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
@@ -81,26 +83,25 @@ namespace AssetStudio
m_TargetPlatform = BuildTarget.UnknownPlatform; m_TargetPlatform = BuildTarget.UnknownPlatform;
} }
} }
if (header.m_Version >= 13) if (header.m_Version >= SerializedFileFormatVersion.HasTypeTreeHashes)
{ {
m_EnableTypeTree = reader.ReadBoolean(); m_EnableTypeTree = reader.ReadBoolean();
} }
//ReadTypes // Read Types
int typeCount = reader.ReadInt32(); int typeCount = reader.ReadInt32();
m_Types = new List<SerializedType>(typeCount); m_Types = new List<SerializedType>(typeCount);
for (int i = 0; i < typeCount; i++) for (int i = 0; i < typeCount; i++)
{ {
m_Types.Add(ReadSerializedType()); m_Types.Add(ReadSerializedType(false));
} }
var bigIDEnabled = 0; if (header.m_Version >= SerializedFileFormatVersion.Unknown_7 && header.m_Version < SerializedFileFormatVersion.Unknown_14)
if (header.m_Version >= 7 && header.m_Version < 14)
{ {
bigIDEnabled = reader.ReadInt32(); bigIDEnabled = reader.ReadInt32();
} }
//ReadObjects // Read Objects
int objectCount = reader.ReadInt32(); int objectCount = reader.ReadInt32();
m_Objects = new List<ObjectInfo>(objectCount); m_Objects = new List<ObjectInfo>(objectCount);
Objects = new List<Object>(objectCount); Objects = new List<Object>(objectCount);
@@ -112,7 +113,7 @@ namespace AssetStudio
{ {
objectInfo.m_PathID = reader.ReadInt64(); objectInfo.m_PathID = reader.ReadInt64();
} }
else if (header.m_Version < 14) else if (header.m_Version < SerializedFileFormatVersion.Unknown_14)
{ {
objectInfo.m_PathID = reader.ReadInt32(); objectInfo.m_PathID = reader.ReadInt32();
} }
@@ -122,7 +123,7 @@ namespace AssetStudio
objectInfo.m_PathID = reader.ReadInt64(); objectInfo.m_PathID = reader.ReadInt64();
} }
if (header.m_Version >= 22) if (header.m_Version >= SerializedFileFormatVersion.LargeFilesSupport)
objectInfo.byteStart = reader.ReadInt64(); objectInfo.byteStart = reader.ReadInt64();
else else
objectInfo.byteStart = reader.ReadUInt32(); objectInfo.byteStart = reader.ReadUInt32();
@@ -130,7 +131,7 @@ namespace AssetStudio
objectInfo.byteStart += header.m_DataOffset; objectInfo.byteStart += header.m_DataOffset;
objectInfo.byteSize = reader.ReadUInt32(); objectInfo.byteSize = reader.ReadUInt32();
objectInfo.typeID = reader.ReadInt32(); objectInfo.typeID = reader.ReadInt32();
if (header.m_Version < 16) if (header.m_Version < SerializedFileFormatVersion.RefactoredClassId)
{ {
objectInfo.classID = reader.ReadUInt16(); objectInfo.classID = reader.ReadUInt16();
objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID); objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
@@ -141,24 +142,24 @@ namespace AssetStudio
objectInfo.serializedType = type; objectInfo.serializedType = type;
objectInfo.classID = type.classID; objectInfo.classID = type.classID;
} }
if (header.m_Version < 11) if (header.m_Version < SerializedFileFormatVersion.HasScriptTypeIndex)
{ {
var isDestroyed = reader.ReadUInt16(); objectInfo.isDestroyed = reader.ReadUInt16();
} }
if (header.m_Version >= 11 && header.m_Version < 17) if (header.m_Version >= SerializedFileFormatVersion.HasScriptTypeIndex && header.m_Version < SerializedFileFormatVersion.RefactorTypeData)
{ {
var m_ScriptTypeIndex = reader.ReadInt16(); var m_ScriptTypeIndex = reader.ReadInt16();
if (objectInfo.serializedType != null) if (objectInfo.serializedType != null)
objectInfo.serializedType.m_ScriptTypeIndex = m_ScriptTypeIndex; objectInfo.serializedType.m_ScriptTypeIndex = m_ScriptTypeIndex;
} }
if (header.m_Version == 15 || header.m_Version == 16) if (header.m_Version == SerializedFileFormatVersion.SupportsStrippedObject || header.m_Version == SerializedFileFormatVersion.RefactoredClassId)
{ {
var stripped = reader.ReadByte(); objectInfo.stripped = reader.ReadByte();
} }
m_Objects.Add(objectInfo); m_Objects.Add(objectInfo);
} }
if (header.m_Version >= 11) if (header.m_Version >= SerializedFileFormatVersion.HasScriptTypeIndex)
{ {
int scriptCount = reader.ReadInt32(); int scriptCount = reader.ReadInt32();
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount); m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount);
@@ -166,7 +167,7 @@ namespace AssetStudio
{ {
var m_ScriptType = new LocalSerializedObjectIdentifier(); var m_ScriptType = new LocalSerializedObjectIdentifier();
m_ScriptType.localSerializedFileIndex = reader.ReadInt32(); m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
if (header.m_Version < 14) if (header.m_Version < SerializedFileFormatVersion.Unknown_14)
{ {
m_ScriptType.localIdentifierInFile = reader.ReadInt32(); m_ScriptType.localIdentifierInFile = reader.ReadInt32();
} }
@@ -184,11 +185,11 @@ namespace AssetStudio
for (int i = 0; i < externalsCount; i++) for (int i = 0; i < externalsCount; i++)
{ {
var m_External = new FileIdentifier(); var m_External = new FileIdentifier();
if (header.m_Version >= 6) if (header.m_Version >= SerializedFileFormatVersion.Unknown_6)
{ {
var tempEmpty = reader.ReadStringToNull(); var tempEmpty = reader.ReadStringToNull();
} }
if (header.m_Version >= 5) if (header.m_Version >= SerializedFileFormatVersion.Unknown_5)
{ {
m_External.guid = new Guid(reader.ReadBytes(16)); m_External.guid = new Guid(reader.ReadBytes(16));
m_External.type = reader.ReadInt32(); m_External.type = reader.ReadInt32();
@@ -198,19 +199,19 @@ namespace AssetStudio
m_Externals.Add(m_External); m_Externals.Add(m_External);
} }
if (header.m_Version >= 20) if (header.m_Version >= SerializedFileFormatVersion.SupportsRefObject)
{ {
int refTypesCount = reader.ReadInt32(); int refTypesCount = reader.ReadInt32();
m_RefTypes = new List<SerializedType>(refTypesCount); m_RefTypes = new List<SerializedType>(refTypesCount);
for (int i = 0; i < refTypesCount; i++) for (int i = 0; i < refTypesCount; i++)
{ {
m_RefTypes.Add(ReadSerializedType()); m_RefTypes.Add(ReadSerializedType(true));
} }
} }
if (header.m_Version >= 5) if (header.m_Version >= SerializedFileFormatVersion.Unknown_5)
{ {
var userInformation = reader.ReadStringToNull(); userInformation = reader.ReadStringToNull();
} }
//reader.AlignStream(16); //reader.AlignStream(16);
@@ -218,80 +219,94 @@ namespace AssetStudio
public void SetVersion(string stringVersion) public void SetVersion(string stringVersion)
{ {
unityVersion = stringVersion; if (stringVersion != strippedVersion)
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries); {
buildType = new BuildType(buildSplit[0]); unityVersion = stringVersion;
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries); var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
version = versionSplit.Select(int.Parse).ToArray(); buildType = new BuildType(buildSplit[0]);
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
version = versionSplit.Select(int.Parse).ToArray();
}
} }
private SerializedType ReadSerializedType() private SerializedType ReadSerializedType(bool isRefType)
{ {
var type = new SerializedType(); var type = new SerializedType();
type.classID = reader.ReadInt32(); type.classID = reader.ReadInt32();
if (header.m_Version >= 16) if (header.m_Version >= SerializedFileFormatVersion.RefactoredClassId)
{ {
type.m_IsStrippedType = reader.ReadBoolean(); type.m_IsStrippedType = reader.ReadBoolean();
} }
if (header.m_Version >= 17) if (header.m_Version >= SerializedFileFormatVersion.RefactorTypeData)
{ {
type.m_ScriptTypeIndex = reader.ReadInt16(); type.m_ScriptTypeIndex = reader.ReadInt16();
} }
if (header.m_Version >= 13) if (header.m_Version >= SerializedFileFormatVersion.HasTypeTreeHashes)
{ {
if ((header.m_Version < 16 && type.classID < 0) || (header.m_Version >= 16 && type.classID == 114)) if (isRefType && type.m_ScriptTypeIndex >= 0)
{ {
type.m_ScriptID = reader.ReadBytes(16); //Hash128 type.m_ScriptID = reader.ReadBytes(16);
} }
type.m_OldTypeHash = reader.ReadBytes(16); //Hash128 else if ((header.m_Version < SerializedFileFormatVersion.RefactoredClassId && type.classID < 0) || (header.m_Version >= SerializedFileFormatVersion.RefactoredClassId && type.classID == 114))
{
type.m_ScriptID = reader.ReadBytes(16);
}
type.m_OldTypeHash = reader.ReadBytes(16);
} }
if (m_EnableTypeTree) if (m_EnableTypeTree)
{ {
var typeTree = new List<TypeTreeNode>(); type.m_Type = new TypeTree();
if (header.m_Version >= 12 || header.m_Version == 10) type.m_Type.m_Nodes = new List<TypeTreeNode>();
if (header.m_Version >= SerializedFileFormatVersion.Unknown_12 || header.m_Version == SerializedFileFormatVersion.Unknown_10)
{ {
TypeTreeBlobRead(typeTree); TypeTreeBlobRead(type.m_Type);
} }
else else
{ {
ReadTypeTree(typeTree); ReadTypeTree(type.m_Type);
} }
if (header.m_Version >= SerializedFileFormatVersion.StoresTypeDependencies)
if (header.m_Version >= 21)
{ {
type.m_TypeDependencies = reader.ReadInt32Array(); if (isRefType)
{
type.m_KlassName = reader.ReadStringToNull();
type.m_NameSpace = reader.ReadStringToNull();
type.m_AsmName = reader.ReadStringToNull();
}
else
{
type.m_TypeDependencies = reader.ReadInt32Array();
}
} }
type.m_Nodes = typeTree;
} }
return type; return type;
} }
private void ReadTypeTree(List<TypeTreeNode> typeTree, int level = 0) private void ReadTypeTree(TypeTree m_Type, int level = 0)
{ {
var typeTreeNode = new TypeTreeNode(); var typeTreeNode = new TypeTreeNode();
typeTree.Add(typeTreeNode); m_Type.m_Nodes.Add(typeTreeNode);
typeTreeNode.m_Level = level; typeTreeNode.m_Level = level;
typeTreeNode.m_Type = reader.ReadStringToNull(); typeTreeNode.m_Type = reader.ReadStringToNull();
typeTreeNode.m_Name = reader.ReadStringToNull(); typeTreeNode.m_Name = reader.ReadStringToNull();
typeTreeNode.m_ByteSize = reader.ReadInt32(); typeTreeNode.m_ByteSize = reader.ReadInt32();
if (header.m_Version == 2) if (header.m_Version == SerializedFileFormatVersion.Unknown_2)
{ {
var variableCount = reader.ReadInt32(); var variableCount = reader.ReadInt32();
} }
if (header.m_Version != 3) if (header.m_Version != SerializedFileFormatVersion.Unknown_3)
{ {
typeTreeNode.m_Index = reader.ReadInt32(); typeTreeNode.m_Index = reader.ReadInt32();
} }
typeTreeNode.m_IsArray = reader.ReadInt32(); typeTreeNode.m_TypeFlags = reader.ReadInt32();
typeTreeNode.m_Version = reader.ReadInt32(); typeTreeNode.m_Version = reader.ReadInt32();
if (header.m_Version != 3) if (header.m_Version != SerializedFileFormatVersion.Unknown_3)
{ {
typeTreeNode.m_MetaFlag = reader.ReadInt32(); typeTreeNode.m_MetaFlag = reader.ReadInt32();
} }
@@ -299,40 +314,40 @@ namespace AssetStudio
int childrenCount = reader.ReadInt32(); int childrenCount = reader.ReadInt32();
for (int i = 0; i < childrenCount; i++) for (int i = 0; i < childrenCount; i++)
{ {
ReadTypeTree(typeTree, level + 1); ReadTypeTree(m_Type, level + 1);
} }
} }
private void TypeTreeBlobRead(List<TypeTreeNode> typeTree) private void TypeTreeBlobRead(TypeTree m_Type)
{ {
int numberOfNodes = reader.ReadInt32(); int numberOfNodes = reader.ReadInt32();
int stringBufferSize = reader.ReadInt32(); int stringBufferSize = reader.ReadInt32();
for (int i = 0; i < numberOfNodes; i++) for (int i = 0; i < numberOfNodes; i++)
{ {
var typeTreeNode = new TypeTreeNode(); var typeTreeNode = new TypeTreeNode();
typeTree.Add(typeTreeNode); m_Type.m_Nodes.Add(typeTreeNode);
typeTreeNode.m_Version = reader.ReadUInt16(); typeTreeNode.m_Version = reader.ReadUInt16();
typeTreeNode.m_Level = reader.ReadByte(); typeTreeNode.m_Level = reader.ReadByte();
typeTreeNode.m_IsArray = reader.ReadBoolean() ? 1 : 0; typeTreeNode.m_TypeFlags = reader.ReadByte();
typeTreeNode.m_TypeStrOffset = reader.ReadUInt32(); typeTreeNode.m_TypeStrOffset = reader.ReadUInt32();
typeTreeNode.m_NameStrOffset = reader.ReadUInt32(); typeTreeNode.m_NameStrOffset = reader.ReadUInt32();
typeTreeNode.m_ByteSize = reader.ReadInt32(); typeTreeNode.m_ByteSize = reader.ReadInt32();
typeTreeNode.m_Index = reader.ReadInt32(); typeTreeNode.m_Index = reader.ReadInt32();
typeTreeNode.m_MetaFlag = reader.ReadInt32(); typeTreeNode.m_MetaFlag = reader.ReadInt32();
if (header.m_Version >= 19) if (header.m_Version >= SerializedFileFormatVersion.TypeTreeNodeWithTypeFlags)
{ {
typeTreeNode.m_RefTypeHash = reader.ReadUInt64(); typeTreeNode.m_RefTypeHash = reader.ReadUInt64();
} }
} }
var m_StringBuffer = reader.ReadBytes(stringBufferSize); m_Type.m_StringBuffer = reader.ReadBytes(stringBufferSize);
using (var stringBufferReader = new BinaryReader(new MemoryStream(m_StringBuffer))) using (var stringBufferReader = new BinaryReader(new MemoryStream(m_Type.m_StringBuffer)))
{ {
for (int i = 0; i < numberOfNodes; i++) for (int i = 0; i < numberOfNodes; i++)
{ {
var typeTreeNode = typeTree[i]; var m_Node = m_Type.m_Nodes[i];
typeTreeNode.m_Type = ReadString(stringBufferReader, typeTreeNode.m_TypeStrOffset); m_Node.m_Type = ReadString(stringBufferReader, m_Node.m_TypeStrOffset);
typeTreeNode.m_Name = ReadString(stringBufferReader, typeTreeNode.m_NameStrOffset); m_Node.m_Name = ReadString(stringBufferReader, m_Node.m_NameStrOffset);
} }
} }
@@ -359,41 +374,8 @@ namespace AssetStudio
ObjectsDic.Add(obj.m_PathID, obj); ObjectsDic.Add(obj.m_PathID, obj);
} }
public static bool IsSerializedFile(EndianBinaryReader reader) public bool IsVersionStripped => unityVersion == strippedVersion;
{
var fileSize = reader.BaseStream.Length; private const string strippedVersion = "0.0.0";
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;
}
} }
} }
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AssetStudio
{
public enum SerializedFileFormatVersion
{
Unsupported = 1,
Unknown_2 = 2,
Unknown_3 = 3,
/// <summary>
/// 1.2.0 to 2.0.0
/// </summary>
Unknown_5 = 5,
/// <summary>
/// 2.1.0 to 2.6.1
/// </summary>
Unknown_6 = 6,
/// <summary>
/// 3.0.0b
/// </summary>
Unknown_7 = 7,
/// <summary>
/// 3.0.0 to 3.4.2
/// </summary>
Unknown_8 = 8,
/// <summary>
/// 3.5.0 to 4.7.2
/// </summary>
Unknown_9 = 9,
/// <summary>
/// 5.0.0aunk1
/// </summary>
Unknown_10 = 10,
/// <summary>
/// 5.0.0aunk2
/// </summary>
HasScriptTypeIndex = 11,
/// <summary>
/// 5.0.0aunk3
/// </summary>
Unknown_12 = 12,
/// <summary>
/// 5.0.0aunk4
/// </summary>
HasTypeTreeHashes = 13,
/// <summary>
/// 5.0.0unk
/// </summary>
Unknown_14 = 14,
/// <summary>
/// 5.0.1 to 5.4.0
/// </summary>
SupportsStrippedObject = 15,
/// <summary>
/// 5.5.0a
/// </summary>
RefactoredClassId = 16,
/// <summary>
/// 5.5.0unk to 2018.4
/// </summary>
RefactorTypeData = 17,
/// <summary>
/// 2019.1a
/// </summary>
RefactorShareableTypeTreeData = 18,
/// <summary>
/// 2019.1unk
/// </summary>
TypeTreeNodeWithTypeFlags = 19,
/// <summary>
/// 2019.2
/// </summary>
SupportsRefObject = 20,
/// <summary>
/// 2019.3 to 2019.4
/// </summary>
StoresTypeDependencies = 21,
/// <summary>
/// 2020.1 to x
/// </summary>
LargeFilesSupport = 22
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace AssetStudio
{ {
public uint m_MetadataSize; public uint m_MetadataSize;
public long m_FileSize; public long m_FileSize;
public uint m_Version; public SerializedFileFormatVersion m_Version;
public long m_DataOffset; public long m_DataOffset;
public byte m_Endianess; public byte m_Endianess;
public byte[] m_Reserved; public byte[] m_Reserved;
+4 -1
View File
@@ -10,9 +10,12 @@ namespace AssetStudio
public int classID; public int classID;
public bool m_IsStrippedType; public bool m_IsStrippedType;
public short m_ScriptTypeIndex = -1; public short m_ScriptTypeIndex = -1;
public List<TypeTreeNode> m_Nodes; public TypeTree m_Type;
public byte[] m_ScriptID; //Hash128 public byte[] m_ScriptID; //Hash128
public byte[] m_OldTypeHash; //Hash128 public byte[] m_OldTypeHash; //Hash128
public int[] m_TypeDependencies; public int[] m_TypeDependencies;
public string m_KlassName;
public string m_NameSpace;
public string m_AsmName;
} }
} }
+5 -4
View File
@@ -34,15 +34,16 @@ namespace AssetStudio
return newOutStream; return newOutStream;
} }
public static void StreamDecompress(Stream inStream, Stream outStream, long inSize, long outSize) public static void StreamDecompress(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize)
{ {
var basePosition = compressedStream.Position;
var decoder = new Decoder(); var decoder = new Decoder();
var properties = new byte[5]; var properties = new byte[5];
if (inStream.Read(properties, 0, 5) != 5) if (compressedStream.Read(properties, 0, 5) != 5)
throw new Exception("input .lzma is too short"); throw new Exception("input .lzma is too short");
decoder.SetDecoderProperties(properties); decoder.SetDecoderProperties(properties);
inSize -= 5L; decoder.Code(compressedStream, decompressedStream, compressedSize - 5, decompressedSize, null);
decoder.Code(inStream, outStream, inSize, outSize, null); compressedStream.Position = basePosition + compressedSize;
} }
} }
} }
+1
View File
@@ -4,6 +4,7 @@ namespace AssetStudio
{ {
public class StreamFile public class StreamFile
{ {
public string path;
public string fileName; public string fileName;
public Stream stream; public Stream stream;
} }
+14
View File
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AssetStudio
{
public class TypeTree
{
public List<TypeTreeNode> m_Nodes;
public byte[] m_StringBuffer;
}
}
+61 -50
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.IO; using System.IO;
using System.Text; using System.Text;
@@ -7,38 +8,43 @@ namespace AssetStudio
{ {
public static class TypeTreeHelper public static class TypeTreeHelper
{ {
public static void ReadTypeString(StringBuilder sb, List<TypeTreeNode> members, ObjectReader reader) public static string ReadTypeString(TypeTree m_Type, ObjectReader reader)
{ {
reader.Reset(); reader.Reset();
for (int i = 0; i < members.Count; i++) var sb = new StringBuilder();
var m_Nodes = m_Type.m_Nodes;
for (int i = 0; i < m_Nodes.Count; i++)
{ {
ReadStringValue(sb, members, reader, ref i); ReadStringValue(sb, m_Nodes, reader, ref i);
} }
var readed = reader.Position - reader.byteStart; var readed = reader.Position - reader.byteStart;
if (readed != reader.byteSize) if (readed != reader.byteSize)
{ {
Logger.Error($"Error while read type, read {readed} bytes but expected {reader.byteSize} bytes"); Logger.Info($"Error while read type, read {readed} bytes but expected {reader.byteSize} bytes");
} }
return sb.ToString();
} }
private static void ReadStringValue(StringBuilder sb, List<TypeTreeNode> members, BinaryReader reader, ref int i) private static void ReadStringValue(StringBuilder sb, List<TypeTreeNode> m_Nodes, BinaryReader reader, ref int i)
{ {
var member = members[i]; var m_Node = m_Nodes[i];
var level = member.m_Level; var level = m_Node.m_Level;
var varTypeStr = member.m_Type; var varTypeStr = m_Node.m_Type;
var varNameStr = member.m_Name; var varNameStr = m_Node.m_Name;
object value = null; object value = null;
var append = true; var append = true;
var align = (member.m_MetaFlag & 0x4000) != 0; var align = (m_Node.m_MetaFlag & 0x4000) != 0;
switch (varTypeStr) switch (varTypeStr)
{ {
case "SInt8": case "SInt8":
value = reader.ReadSByte(); value = reader.ReadSByte();
break; break;
case "UInt8": case "UInt8":
case "char":
value = reader.ReadByte(); value = reader.ReadByte();
break; break;
case "char":
value = BitConverter.ToChar(reader.ReadBytes(2), 0);
break;
case "short": case "short":
case "SInt16": case "SInt16":
value = reader.ReadInt16(); value = reader.ReadInt16();
@@ -78,22 +84,23 @@ namespace AssetStudio
append = false; append = false;
var str = reader.ReadAlignedString(); var str = reader.ReadAlignedString();
sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str); sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str);
i += 3; var toSkip = GetNodes(m_Nodes, i);
i += toSkip.Count - 1;
break; break;
case "map": case "map":
{ {
if ((members[i + 1].m_MetaFlag & 0x4000) != 0) if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
align = true; align = true;
append = false; append = false;
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array"); sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array");
var size = reader.ReadInt32(); var size = reader.ReadInt32();
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size); sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size);
var map = GetMembers(members, i); var map = GetNodes(m_Nodes, i);
i += map.Count - 1; i += map.Count - 1;
var first = GetMembers(map, 4); var first = GetNodes(map, 4);
var next = 4 + first.Count; var next = 4 + first.Count;
var second = GetMembers(map, next); var second = GetNodes(map, next);
for (int j = 0; j < size; j++) for (int j = 0; j < size; j++)
{ {
sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j); sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j);
@@ -117,16 +124,16 @@ namespace AssetStudio
} }
default: default:
{ {
if (i < members.Count - 1 && members[i + 1].m_Type == "Array") //Array if (i < m_Nodes.Count - 1 && m_Nodes[i + 1].m_Type == "Array") //Array
{ {
if ((members[i + 1].m_MetaFlag & 0x4000) != 0) if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
align = true; align = true;
append = false; append = false;
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array"); sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array");
var size = reader.ReadInt32(); var size = reader.ReadInt32();
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size); sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size);
var vector = GetMembers(members, i); var vector = GetNodes(m_Nodes, i);
i += vector.Count - 1; i += vector.Count - 1;
for (int j = 0; j < size; j++) for (int j = 0; j < size; j++)
{ {
@@ -140,7 +147,7 @@ namespace AssetStudio
{ {
append = false; append = false;
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
var @class = GetMembers(members, i); var @class = GetNodes(m_Nodes, i);
i += @class.Count - 1; i += @class.Count - 1;
for (int j = 1; j < @class.Count; j++) for (int j = 1; j < @class.Count; j++)
{ {
@@ -156,39 +163,42 @@ namespace AssetStudio
reader.AlignStream(); reader.AlignStream();
} }
public static OrderedDictionary ReadType(List<TypeTreeNode> members, ObjectReader reader) public static OrderedDictionary ReadType(TypeTree m_Types, ObjectReader reader)
{ {
reader.Reset(); reader.Reset();
var obj = new OrderedDictionary(); var obj = new OrderedDictionary();
for (int i = 1; i < members.Count; i++) var m_Nodes = m_Types.m_Nodes;
for (int i = 1; i < m_Nodes.Count; i++)
{ {
var member = members[i]; var m_Node = m_Nodes[i];
var varNameStr = member.m_Name; var varNameStr = m_Node.m_Name;
obj[varNameStr] = ReadValue(members, reader, ref i); obj[varNameStr] = ReadValue(m_Nodes, reader, ref i);
} }
var readed = reader.Position - reader.byteStart; var readed = reader.Position - reader.byteStart;
if (readed != reader.byteSize) if (readed != reader.byteSize)
{ {
Logger.Error($"Error while read type, read {readed} bytes but expected {reader.byteSize} bytes"); Logger.Info($"Error while read type, read {readed} bytes but expected {reader.byteSize} bytes");
} }
return obj; return obj;
} }
private static object ReadValue(List<TypeTreeNode> members, BinaryReader reader, ref int i) private static object ReadValue(List<TypeTreeNode> m_Nodes, BinaryReader reader, ref int i)
{ {
var member = members[i]; var m_Node = m_Nodes[i];
var varTypeStr = member.m_Type; var varTypeStr = m_Node.m_Type;
object value; object value;
var align = (member.m_MetaFlag & 0x4000) != 0; var align = (m_Node.m_MetaFlag & 0x4000) != 0;
switch (varTypeStr) switch (varTypeStr)
{ {
case "SInt8": case "SInt8":
value = reader.ReadSByte(); value = reader.ReadSByte();
break; break;
case "UInt8": case "UInt8":
case "char":
value = reader.ReadByte(); value = reader.ReadByte();
break; break;
case "char":
value = BitConverter.ToChar(reader.ReadBytes(2), 0);
break;
case "short": case "short":
case "SInt16": case "SInt16":
value = reader.ReadInt16(); value = reader.ReadInt16();
@@ -226,17 +236,18 @@ namespace AssetStudio
break; break;
case "string": case "string":
value = reader.ReadAlignedString(); value = reader.ReadAlignedString();
i += 3; var toSkip = GetNodes(m_Nodes, i);
i += toSkip.Count - 1;
break; break;
case "map": case "map":
{ {
if ((members[i + 1].m_MetaFlag & 0x4000) != 0) if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
align = true; align = true;
var map = GetMembers(members, i); var map = GetNodes(m_Nodes, i);
i += map.Count - 1; i += map.Count - 1;
var first = GetMembers(map, 4); var first = GetNodes(map, 4);
var next = 4 + first.Count; var next = 4 + first.Count;
var second = GetMembers(map, next); var second = GetNodes(map, next);
var size = reader.ReadInt32(); var size = reader.ReadInt32();
var dic = new List<KeyValuePair<object, object>>(size); var dic = new List<KeyValuePair<object, object>>(size);
for (int j = 0; j < size; j++) for (int j = 0; j < size; j++)
@@ -257,11 +268,11 @@ namespace AssetStudio
} }
default: default:
{ {
if (i < members.Count - 1 && members[i + 1].m_Type == "Array") //Array if (i < m_Nodes.Count - 1 && m_Nodes[i + 1].m_Type == "Array") //Array
{ {
if ((members[i + 1].m_MetaFlag & 0x4000) != 0) if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
align = true; align = true;
var vector = GetMembers(members, i); var vector = GetNodes(m_Nodes, i);
i += vector.Count - 1; i += vector.Count - 1;
var size = reader.ReadInt32(); var size = reader.ReadInt32();
var list = new List<object>(size); var list = new List<object>(size);
@@ -275,7 +286,7 @@ namespace AssetStudio
} }
else //Class else //Class
{ {
var @class = GetMembers(members, i); var @class = GetNodes(m_Nodes, i);
i += @class.Count - 1; i += @class.Count - 1;
var obj = new OrderedDictionary(); var obj = new OrderedDictionary();
for (int j = 1; j < @class.Count; j++) for (int j = 1; j < @class.Count; j++)
@@ -294,22 +305,22 @@ namespace AssetStudio
return value; return value;
} }
private static List<TypeTreeNode> GetMembers(List<TypeTreeNode> members, int index) private static List<TypeTreeNode> GetNodes(List<TypeTreeNode> m_Nodes, int index)
{ {
var member2 = new List<TypeTreeNode>(); var nodes = new List<TypeTreeNode>();
member2.Add(members[index]); nodes.Add(m_Nodes[index]);
var level = members[index].m_Level; var level = m_Nodes[index].m_Level;
for (int i = index + 1; i < members.Count; i++) for (int i = index + 1; i < m_Nodes.Count; i++)
{ {
var member = members[i]; var member = m_Nodes[i];
var level2 = member.m_Level; var level2 = member.m_Level;
if (level2 <= level) if (level2 <= level)
{ {
return member2; return nodes;
} }
member2.Add(member); nodes.Add(member);
} }
return member2; return nodes;
} }
} }
} }
+1 -1
View File
@@ -11,7 +11,7 @@ namespace AssetStudio
public string m_Name; public string m_Name;
public int m_ByteSize; public int m_ByteSize;
public int m_Index; public int m_Index;
public int m_IsArray; //m_TypeFlags public int m_TypeFlags; //m_IsArray
public int m_Version; public int m_Version;
public int m_MetaFlag; public int m_MetaFlag;
public int m_Level; public int m_Level;
+3 -50
View File
@@ -1,17 +1,11 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text; using System.Text;
using Org.Brotli.Dec;
namespace AssetStudio namespace AssetStudio
{ {
public class WebFile public class WebFile
{ {
public static byte[] gzipMagic = { 0x1f, 0x8b };
public static byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
public StreamFile[] fileList; public StreamFile[] fileList;
private class WebData private class WebData
@@ -23,50 +17,8 @@ namespace AssetStudio
public WebFile(EndianBinaryReader reader) public WebFile(EndianBinaryReader reader)
{ {
var magic = reader.ReadBytes(2); reader.Endian = EndianType.LittleEndian;
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)
{
var signature = reader.ReadStringToNull(); var signature = reader.ReadStringToNull();
if (signature != "UnityWebData1.0")
return;
var headLength = reader.ReadInt32(); var headLength = reader.ReadInt32();
var dataList = new List<WebData>(); var dataList = new List<WebData>();
while (reader.BaseStream.Position < headLength) while (reader.BaseStream.Position < headLength)
@@ -83,6 +35,7 @@ namespace AssetStudio
{ {
var data = dataList[i]; var data = dataList[i];
var file = new StreamFile(); var file = new StreamFile();
file.path = data.path;
file.fileName = Path.GetFileName(data.path); file.fileName = Path.GetFileName(data.path);
reader.BaseStream.Position = data.dataOffset; reader.BaseStream.Position = data.dataOffset;
file.stream = new MemoryStream(reader.ReadBytes(data.dataLength)); file.stream = new MemoryStream(reader.ReadBytes(data.dataLength));
@@ -29,26 +29,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@@ -100,14 +100,14 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_AS_DLL;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x86\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x86\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@@ -119,7 +119,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_AS_DLL;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -128,7 +128,7 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -137,14 +137,14 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_AS_DLL;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x64\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x64\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> <IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@@ -156,7 +156,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_AS_DLL;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -165,7 +165,7 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
-12
View File
@@ -4,18 +4,6 @@
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
namespace fbxsdk
{
class FbxManager;
class FbxScene;
class FbxExporter;
template<typename T, const int Alignment = 16>
class FbxArray;
class FbxFileTexture;
class FbxSurfacePhong;
class FbxPose;
}
struct AsFbxContext struct AsFbxContext
{ {
@@ -1,60 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<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> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFrameworks>net472;netstandard2.0;net5.0;net6.0</TargetFrameworks>
<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>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <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-2022; Copyright © hozuki 2020</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
<Reference Include="System.Core" /> <ProjectReference Include="..\AssetStudio\AssetStudio.csproj" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Include="Fbx.PInvoke.cs" /> </Project>
<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>
+2 -2
View File
@@ -28,7 +28,7 @@ namespace AssetStudio
{ {
public static void Export(string path, IImported imported, bool eulerFilter, float filterPrecision, 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 file = new FileInfo(path);
var dir = file.Directory; var dir = file.Directory;
@@ -43,7 +43,7 @@ namespace AssetStudio
var name = Path.GetFileName(path); 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.Initialize();
exporter.ExportAll(blendShape, animation, eulerFilter, filterPrecision); exporter.ExportAll(blendShape, animation, eulerFilter, filterPrecision);
+4 -2
View File
@@ -15,11 +15,12 @@ namespace AssetStudio.FbxInterop
private readonly bool _exportSkins; private readonly bool _exportSkins;
private readonly bool _castToBone; private readonly bool _castToBone;
private readonly float _boneSize; private readonly float _boneSize;
private readonly bool _exportAllUvsAsDiffuseMaps;
private readonly float _scaleFactor; private readonly float _scaleFactor;
private readonly int _versionIndex; private readonly int _versionIndex;
private readonly bool _isAscii; 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(); _context = new FbxExporterContext();
@@ -29,6 +30,7 @@ namespace AssetStudio.FbxInterop
_exportSkins = exportSkins; _exportSkins = exportSkins;
_castToBone = castToBone; _castToBone = castToBone;
_boneSize = boneSize; _boneSize = boneSize;
_exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps;
_scaleFactor = scaleFactor; _scaleFactor = scaleFactor;
_versionIndex = versionIndex; _versionIndex = versionIndex;
_isAscii = isAscii; _isAscii = isAscii;
@@ -171,7 +173,7 @@ namespace AssetStudio.FbxInterop
{ {
foreach (var meshFrame in meshFrames) 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); 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 meshNode = _frameToNode[meshFrame];
var mesh = ImportedHelpers.FindMesh(meshFrame.Path, meshList); 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) private IntPtr ExportTexture(ImportedTexture texture)
@@ -207,7 +207,7 @@ namespace AssetStudio.FbxInterop
return pTex; 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 boneList = importedMesh.BoneList;
var totalBoneCount = 0; var totalBoneCount = 0;
@@ -246,28 +246,25 @@ namespace AssetStudio.FbxInterop
var mesh = AsFbxMeshCreateMesh(_pContext, frameNode); var mesh = AsFbxMeshCreateMesh(_pContext, frameNode);
var totalVertexCount = 0; AsFbxMeshInitControlPoints(mesh, importedMesh.VertexList.Count);
foreach (var m in importedMesh.SubmeshList)
{
totalVertexCount += m.VertexList.Count;
}
AsFbxMeshInitControlPoints(mesh, totalVertexCount);
if (importedMesh.hasNormal) if (importedMesh.hasNormal)
{ {
AsFbxMeshCreateElementNormal(mesh); 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]) if (i == 1 && !exportAllUvsAsDiffuseMaps)
{ {
AsFbxMeshCreateNormalMapUV(mesh, 1); AsFbxMeshCreateNormalMapUV(mesh, 1);
}
else
{
AsFbxMeshCreateDiffuseUV(mesh, i);
}
} }
if (importedMesh.hasTangent) if (importedMesh.hasTangent)
@@ -282,8 +279,6 @@ namespace AssetStudio.FbxInterop
AsFbxMeshCreateElementMaterial(mesh); AsFbxMeshCreateElementMaterial(mesh);
var firstVertex = 0;
foreach (var meshObj in importedMesh.SubmeshList) foreach (var meshObj in importedMesh.SubmeshList)
{ {
var materialIndex = 0; 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) foreach (var face in meshObj.FaceList)
{ {
var index0 = face.VertexIndices[0] + firstVertex; var index0 = face.VertexIndices[0] + meshObj.BaseVertex;
var index1 = face.VertexIndices[1] + firstVertex; var index1 = face.VertexIndices[1] + meshObj.BaseVertex;
var index2 = face.VertexIndices[2] + firstVertex; var index2 = face.VertexIndices[2] + meshObj.BaseVertex;
AsFbxMeshAddPolygon(mesh, materialIndex, index0, index1, index2); 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) if (hasBones)
{ {
IntPtr pSkinContext = IntPtr.Zero; 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")]
+83 -153
View File
@@ -1,154 +1,84 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<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>
<PropertyGroup> <OutputType>WinExe</OutputType>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFrameworks>net472;net5.0-windows;net6.0-windows</TargetFrameworks>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <UseWindowsForms>true</UseWindowsForms>
<ProjectGuid>{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}</ProjectGuid> <ApplicationIcon>Resources\as.ico</ApplicationIcon>
<OutputType>WinExe</OutputType> <Version>0.16.0.0</Version>
<RootNamespace>AssetStudioGUI</RootNamespace> <AssemblyVersion>0.16.0.0</AssemblyVersion>
<AssemblyName>AssetStudioGUI</AssemblyName> <FileVersion>0.16.0.0</FileVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <Copyright>Copyright © Perfare 2018-2022</Copyright>
<FileAlignment>512</FileAlignment> <DebugType>embedded</DebugType>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> </PropertyGroup>
<Deterministic>true</Deterministic>
</PropertyGroup> <ItemGroup>
<PropertyGroup> <ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj" />
<ApplicationIcon>Resources\as.ico</ApplicationIcon> <ProjectReference Include="..\AssetStudio\AssetStudio.csproj" />
</PropertyGroup> </ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols> <ItemGroup>
<OutputPath>bin\Debug\</OutputPath> <None Include="Properties\Settings.settings">
<DefineConstants>DEBUG;TRACE</DefineConstants> <Generator>SettingsSingleFileGenerator</Generator>
<DebugType>full</DebugType> <LastGenOutput>Settings.Designer.cs</LastGenOutput>
<PlatformTarget>AnyCPU</PlatformTarget> </None>
<LangVersion>7.3</LangVersion> <Compile Update="Properties\Settings.Designer.cs">
<ErrorReport>prompt</ErrorReport> <AutoGen>True</AutoGen>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <DependentUpon>Settings.settings</DependentUpon>
<Prefer32Bit>false</Prefer32Bit> <DesignTimeSharedInput>True</DesignTimeSharedInput>
</PropertyGroup> </Compile>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'"> </ItemGroup>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants> <ItemGroup>
<Optimize>true</Optimize> <EmbeddedResource Update="Properties\Resources.resx">
<DebugType>pdbonly</DebugType> <Generator>ResXFileCodeGenerator</Generator>
<PlatformTarget>AnyCPU</PlatformTarget> <LastGenOutput>Resources.Designer.cs</LastGenOutput>
<LangVersion>7.3</LangVersion> </EmbeddedResource>
<ErrorReport>prompt</ErrorReport> <Compile Update="Properties\Resources.Designer.cs">
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <AutoGen>True</AutoGen>
<Prefer32Bit>false</Prefer32Bit> <DependentUpon>Resources.resx</DependentUpon>
</PropertyGroup> <DesignTime>True</DesignTime>
<ItemGroup> </Compile>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> </ItemGroup>
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> <ItemGroup>
<Reference Include="OpenTK, Version=3.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL"> <ContentWithTargetPath Include="Libraries\x86\fmod.dll">
<HintPath>..\packages\OpenTK.3.1.0\lib\net20\OpenTK.dll</HintPath> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Reference> <TargetPath>x86\fmod.dll</TargetPath>
<Reference Include="OpenTK.GLControl, Version=3.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL"> </ContentWithTargetPath>
<HintPath>..\packages\OpenTK.GLControl.3.1.0\lib\net20\OpenTK.GLControl.dll</HintPath> <ContentWithTargetPath Include="Libraries\x64\fmod.dll">
</Reference> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Reference Include="System" /> <TargetPath>x64\fmod.dll</TargetPath>
<Reference Include="System.Core" /> </ContentWithTargetPath>
<Reference Include="System.Xml.Linq" /> </ItemGroup>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <ItemGroup Condition=" '$(TargetFramework)' != 'net472' ">
<Reference Include="System.Data" /> <PackageReference Include="OpenTK" Version="4.6.7" />
<Reference Include="System.Deployment" /> <Reference Include="OpenTK.WinForms">
<Reference Include="System.Drawing" /> <HintPath>Libraries\OpenTK.WinForms.dll</HintPath>
<Reference Include="System.Net.Http" /> </Reference>
<Reference Include="System.Windows.Forms" /> </ItemGroup>
<Reference Include="System.Xml" />
</ItemGroup> <ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<ItemGroup> <PackageReference Include="OpenTK" Version="3.1.0" />
<Compile Include="AssetStudioGUIForm.cs"> <PackageReference Include="OpenTK.GLControl" Version="3.1.0" />
<SubType>Form</SubType> </ItemGroup>
</Compile>
<Compile Include="AssetStudioGUIForm.designer.cs"> <ItemGroup>
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</Compile> </ItemGroup>
<Compile Include="Components\AssetItem.cs" />
<Compile Include="Components\GameObjectTreeNode.cs" /> <Target Name="CopyExtraFiles" AfterTargets="AfterBuild">
<Compile Include="Components\GOHierarchy.cs"> <Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\Win32\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)x86" ContinueOnError="true" />
<SubType>Component</SubType> <Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\x64\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)x64" ContinueOnError="true" />
</Compile> <Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\Win32\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)x86" ContinueOnError="true" />
<Compile Include="Components\OpenFolderDialog.cs" /> <Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\x64\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)x64" ContinueOnError="true" />
<Compile Include="Components\TreeViewExtensions.cs" /> </Target>
<Compile Include="Components\TypeTreeItem.cs" />
<Compile Include="Exporter.cs" /> <Target Name="PublishExtraFiles" AfterTargets="Publish">
<Compile Include="ExportOptions.cs"> <Copy SourceFiles="$(TargetDir)x86\AssetStudioFBXNative.dll" DestinationFolder="$(PublishDir)x86" ContinueOnError="true" />
<SubType>Form</SubType> <Copy SourceFiles="$(TargetDir)x64\AssetStudioFBXNative.dll" DestinationFolder="$(PublishDir)x64" ContinueOnError="true" />
</Compile> <Copy SourceFiles="$(TargetDir)x86\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)x86" ContinueOnError="true" />
<Compile Include="ExportOptions.designer.cs"> <Copy SourceFiles="$(TargetDir)x64\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)x64" ContinueOnError="true" />
<DependentUpon>ExportOptions.cs</DependentUpon> </Target>
</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> </Project>
+42 -11
View File
@@ -41,6 +41,8 @@
this.displayAll = new System.Windows.Forms.ToolStripMenuItem(); this.displayAll = new System.Windows.Forms.ToolStripMenuItem();
this.enablePreview = new System.Windows.Forms.ToolStripMenuItem(); this.enablePreview = new System.Windows.Forms.ToolStripMenuItem();
this.displayInfo = 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.showExpOpt = new System.Windows.Forms.ToolStripMenuItem();
this.modelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.modelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportAllObjectssplitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.exportAllObjectssplitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
@@ -72,6 +74,7 @@
this.filterTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.filterTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.debugMenuItem = 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.exportClassStructuresMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer1 = new System.Windows.Forms.SplitContainer(); this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.tabControl1 = new System.Windows.Forms.TabControl(); this.tabControl1 = new System.Windows.Forms.TabControl();
@@ -210,6 +213,7 @@
this.displayAll, this.displayAll,
this.enablePreview, this.enablePreview,
this.displayInfo, this.displayInfo,
this.toolStripMenuItem14,
this.showExpOpt}); this.showExpOpt});
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(66, 21); this.optionsToolStripMenuItem.Size = new System.Drawing.Size(66, 21);
@@ -249,6 +253,20 @@
"t, audio bitrate, etc."; "t, audio bitrate, etc.";
this.displayInfo.CheckedChanged += new System.EventHandler(this.displayAssetInfo_Check); 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 // showExpOpt
// //
this.showExpOpt.Name = "showExpOpt"; this.showExpOpt.Name = "showExpOpt";
@@ -429,7 +447,7 @@
// toolStripSeparator2 // toolStripSeparator2
// //
this.toolStripSeparator2.Name = "toolStripSeparator2"; this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(396, 6); this.toolStripSeparator2.Size = new System.Drawing.Size(281, 6);
// //
// toolStripMenuItem10 // toolStripMenuItem10
// //
@@ -438,27 +456,27 @@
this.toolStripMenuItem12, this.toolStripMenuItem12,
this.toolStripMenuItem13}); this.toolStripMenuItem13});
this.toolStripMenuItem10.Name = "toolStripMenuItem10"; 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"; this.toolStripMenuItem10.Text = "Asset list to XML";
// //
// toolStripMenuItem11 // toolStripMenuItem11
// //
this.toolStripMenuItem11.Name = "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.Text = "All assets";
this.toolStripMenuItem11.Click += new System.EventHandler(this.toolStripMenuItem11_Click); this.toolStripMenuItem11.Click += new System.EventHandler(this.toolStripMenuItem11_Click);
// //
// toolStripMenuItem12 // toolStripMenuItem12
// //
this.toolStripMenuItem12.Name = "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.Text = "Selected assets";
this.toolStripMenuItem12.Click += new System.EventHandler(this.toolStripMenuItem12_Click); this.toolStripMenuItem12.Click += new System.EventHandler(this.toolStripMenuItem12_Click);
// //
// toolStripMenuItem13 // toolStripMenuItem13
// //
this.toolStripMenuItem13.Name = "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.Text = "Filtered assets";
this.toolStripMenuItem13.Click += new System.EventHandler(this.toolStripMenuItem13_Click); this.toolStripMenuItem13.Click += new System.EventHandler(this.toolStripMenuItem13_Click);
// //
@@ -483,11 +501,22 @@
// debugMenuItem // debugMenuItem
// //
this.debugMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.debugMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem15,
this.exportClassStructuresMenuItem}); this.exportClassStructuresMenuItem});
this.debugMenuItem.Name = "debugMenuItem"; this.debugMenuItem.Name = "debugMenuItem";
this.debugMenuItem.Size = new System.Drawing.Size(59, 21); this.debugMenuItem.Size = new System.Drawing.Size(59, 21);
this.debugMenuItem.Text = "Debug"; 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 // exportClassStructuresMenuItem
// //
this.exportClassStructuresMenuItem.Name = "exportClassStructuresMenuItem"; this.exportClassStructuresMenuItem.Name = "exportClassStructuresMenuItem";
@@ -790,20 +819,21 @@
// //
// FMODtimerLabel // FMODtimerLabel
// //
this.FMODtimerLabel.AutoSize = true;
this.FMODtimerLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight; this.FMODtimerLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.FMODtimerLabel.Location = new System.Drawing.Point(404, 235); this.FMODtimerLabel.Location = new System.Drawing.Point(460, 235);
this.FMODtimerLabel.Name = "FMODtimerLabel"; this.FMODtimerLabel.Name = "FMODtimerLabel";
this.FMODtimerLabel.Size = new System.Drawing.Size(155, 12); this.FMODtimerLabel.Size = new System.Drawing.Size(95, 12);
this.FMODtimerLabel.TabIndex = 7; this.FMODtimerLabel.TabIndex = 7;
this.FMODtimerLabel.Text = "0:00.0 / 0:00.0"; this.FMODtimerLabel.Text = "0:00.0 / 0:00.0";
this.FMODtimerLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
// //
// FMODstatusLabel // FMODstatusLabel
// //
this.FMODstatusLabel.AutoSize = true;
this.FMODstatusLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight; this.FMODstatusLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.FMODstatusLabel.Location = new System.Drawing.Point(213, 235); this.FMODstatusLabel.Location = new System.Drawing.Point(213, 235);
this.FMODstatusLabel.Name = "FMODstatusLabel"; this.FMODstatusLabel.Name = "FMODstatusLabel";
this.FMODstatusLabel.Size = new System.Drawing.Size(50, 12); this.FMODstatusLabel.Size = new System.Drawing.Size(47, 12);
this.FMODstatusLabel.TabIndex = 6; this.FMODstatusLabel.TabIndex = 6;
this.FMODstatusLabel.Text = "Stopped"; this.FMODstatusLabel.Text = "Stopped";
// //
@@ -1036,8 +1066,6 @@
// AssetStudioGUIForm // AssetStudioGUIForm
// //
this.AllowDrop = true; this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1264, 681); this.ClientSize = new System.Drawing.Size(1264, 681);
this.Controls.Add(this.splitContainer1); this.Controls.Add(this.splitContainer1);
this.Controls.Add(this.menuStrip1); this.Controls.Add(this.menuStrip1);
@@ -1178,6 +1206,9 @@
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem11; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem11;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem12; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem12;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem13; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem13;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem14;
private System.Windows.Forms.ToolStripTextBox specifyUnityVersion;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem15;
} }
} }
+96 -63
View File
@@ -6,7 +6,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text; using System.Drawing.Text;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
@@ -19,16 +18,21 @@ using System.Timers;
using System.Windows.Forms; using System.Windows.Forms;
using static AssetStudioGUI.Studio; using static AssetStudioGUI.Studio;
using Font = AssetStudio.Font; using Font = AssetStudio.Font;
using PixelFormat = System.Drawing.Imaging.PixelFormat; #if NET472
using Vector3 = OpenTK.Vector3; using Vector3 = OpenTK.Vector3;
using Vector4 = OpenTK.Vector4; using Vector4 = OpenTK.Vector4;
#else
using Vector3 = OpenTK.Mathematics.Vector3;
using Vector4 = OpenTK.Mathematics.Vector4;
using Matrix4 = OpenTK.Mathematics.Matrix4;
#endif
namespace AssetStudioGUI namespace AssetStudioGUI
{ {
partial class AssetStudioGUIForm : Form partial class AssetStudioGUIForm : Form
{ {
private AssetItem lastSelectedItem; private AssetItem lastSelectedItem;
private Bitmap imageTexture; private DirectBitmap imageTexture;
private string tempClipboard; private string tempClipboard;
private FMOD.System system; private FMOD.System system;
@@ -81,6 +85,11 @@ namespace AssetStudioGUI
private int nextGObject; private int nextGObject;
private List<TreeNode> treeSrcResults = new List<TreeNode>(); private List<TreeNode> treeSrcResults = new List<TreeNode>();
private string openDirectoryBackup = string.Empty;
private string saveDirectoryBackup = string.Empty;
private GUILogger logger;
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts); private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts);
@@ -96,8 +105,9 @@ namespace AssetStudioGUI
enablePreview.Checked = Properties.Settings.Default.enablePreview; enablePreview.Checked = Properties.Settings.Default.enablePreview;
FMODinit(); FMODinit();
Logger.Default = new GUILogger(StatusStripUpdate); logger = new GUILogger(StatusStripUpdate);
Progress.Default = new GUIProgress(SetProgressBarValue); Logger.Default = logger;
Progress.Default = new Progress<int>(SetProgressBarValue);
Studio.StatusStripUpdate = StatusStripUpdate; Studio.StatusStripUpdate = StatusStripUpdate;
} }
@@ -115,7 +125,7 @@ namespace AssetStudioGUI
if (paths.Length > 0) if (paths.Length > 0)
{ {
ResetForm(); ResetForm();
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
if (paths.Length == 1 && Directory.Exists(paths[0])) if (paths.Length == 1 && Directory.Exists(paths[0]))
{ {
await Task.Run(() => assetsManager.LoadFolder(paths[0])); await Task.Run(() => assetsManager.LoadFolder(paths[0]));
@@ -124,16 +134,18 @@ namespace AssetStudioGUI
{ {
await Task.Run(() => assetsManager.LoadFiles(paths)); await Task.Run(() => assetsManager.LoadFiles(paths));
} }
BuildAssetStructures(); BuildAssetStructures();
} }
} }
private async void loadFile_Click(object sender, EventArgs e) private async void loadFile_Click(object sender, EventArgs e)
{ {
if (openFileDialog1.ShowDialog() == DialogResult.OK) openFileDialog1.InitialDirectory = openDirectoryBackup;
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
{ {
ResetForm(); ResetForm();
openDirectoryBackup = Path.GetDirectoryName(openFileDialog1.FileNames[0]);
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
await Task.Run(() => assetsManager.LoadFiles(openFileDialog1.FileNames)); await Task.Run(() => assetsManager.LoadFiles(openFileDialog1.FileNames));
BuildAssetStructures(); BuildAssetStructures();
} }
@@ -142,9 +154,12 @@ namespace AssetStudioGUI
private async void loadFolder_Click(object sender, EventArgs e) private async void loadFolder_Click(object sender, EventArgs e)
{ {
var openFolderDialog = new OpenFolderDialog(); var openFolderDialog = new OpenFolderDialog();
openFolderDialog.InitialFolder = openDirectoryBackup;
if (openFolderDialog.ShowDialog(this) == DialogResult.OK) if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
{ {
ResetForm(); ResetForm();
openDirectoryBackup = openFolderDialog.Folder;
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
await Task.Run(() => assetsManager.LoadFolder(openFolderDialog.Folder)); await Task.Run(() => assetsManager.LoadFolder(openFolderDialog.Folder));
BuildAssetStructures(); BuildAssetStructures();
} }
@@ -152,7 +167,7 @@ namespace AssetStudioGUI
private async void extractFileToolStripMenuItem_Click(object sender, EventArgs e) private async void extractFileToolStripMenuItem_Click(object sender, EventArgs e)
{ {
if (openFileDialog1.ShowDialog() == DialogResult.OK) if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
{ {
var saveFolderDialog = new OpenFolderDialog(); var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.Title = "Select the save folder"; saveFolderDialog.Title = "Select the save folder";
@@ -187,7 +202,7 @@ namespace AssetStudioGUI
{ {
if (assetsManager.assetsFileList.Count == 0) if (assetsManager.assetsFileList.Count == 0)
{ {
StatusStripUpdate("No file was loaded."); StatusStripUpdate("No Unity file can be loaded.");
return; return;
} }
@@ -207,10 +222,6 @@ namespace AssetStudioGUI
sceneTreeView.BeginUpdate(); sceneTreeView.BeginUpdate();
sceneTreeView.Nodes.AddRange(treeNodeCollection.ToArray()); sceneTreeView.Nodes.AddRange(treeNodeCollection.ToArray());
foreach (var node in treeNodeCollection)
{
node.HideCheckBox();
}
sceneTreeView.EndUpdate(); sceneTreeView.EndUpdate();
treeNodeCollection.Clear(); treeNodeCollection.Clear();
@@ -350,7 +361,7 @@ namespace AssetStudioGUI
var versionPath = Path.Combine(savePath, item.Group.Header); var versionPath = Path.Combine(savePath, item.Group.Header);
Directory.CreateDirectory(versionPath); 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()); File.WriteAllText(saveFile, item.ToString());
Progress.Report(++i, count); Progress.Report(++i, count);
@@ -378,7 +389,7 @@ namespace AssetStudioGUI
{ {
if (enablePreview.Checked && imageTexture != null) if (enablePreview.Checked && imageTexture != null)
{ {
previewPanel.BackgroundImage = imageTexture; previewPanel.BackgroundImage = imageTexture.Bitmap;
} }
else else
{ {
@@ -446,7 +457,7 @@ namespace AssetStudioGUI
private void showExpOpt_Click(object sender, EventArgs e) private void showExpOpt_Click(object sender, EventArgs e)
{ {
var exportOpt = new ExportOptions(); var exportOpt = new ExportOptions();
exportOpt.ShowDialog(); exportOpt.ShowDialog(this);
} }
private void assetListView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) private void assetListView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
@@ -741,9 +752,11 @@ namespace AssetStudioGUI
private void PreviewTexture2D(AssetItem assetItem, Texture2D m_Texture2D) private void PreviewTexture2D(AssetItem assetItem, Texture2D m_Texture2D)
{ {
var bitmap = m_Texture2D.ConvertToBitmap(true); var image = m_Texture2D.ConvertToImage(true);
if (bitmap != null) if (image != null)
{ {
var bitmap = new DirectBitmap(image.ConvertToBytes(), m_Texture2D.m_Width, m_Texture2D.m_Height);
image.Dispose();
assetItem.InfoText = $"Width: {m_Texture2D.m_Width}\nHeight: {m_Texture2D.m_Height}\nFormat: {m_Texture2D.m_TextureFormat}"; assetItem.InfoText = $"Width: {m_Texture2D.m_Width}\nHeight: {m_Texture2D.m_Height}\nFormat: {m_Texture2D.m_TextureFormat}";
switch (m_Texture2D.m_TextureSettings.m_FilterMode) switch (m_Texture2D.m_TextureSettings.m_FilterMode)
{ {
@@ -771,13 +784,11 @@ namespace AssetStudioGUI
assetItem.InfoText += "None"; assetItem.InfoText += "None";
if (validChannel != 4) if (validChannel != 4)
{ {
var bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); var bytes = bitmap.Bits;
var bytes = new byte[bitmap.Width * bitmap.Height * 4]; for (int i = 0; i < bitmap.Height; i++)
Marshal.Copy(bmpData.Scan0, bytes, 0, bytes.Length);
for (int i = 0; i < bmpData.Height; i++)
{ {
int offset = Math.Abs(bmpData.Stride) * i; int offset = Math.Abs(bitmap.Stride) * i;
for (int j = 0; j < bmpData.Width; j++) for (int j = 0; j < bitmap.Width; j++)
{ {
bytes[offset] = textureChannels[0] ? bytes[offset] : validChannel == 1 && textureChannels[3] ? byte.MaxValue : byte.MinValue; bytes[offset] = textureChannels[0] ? bytes[offset] : validChannel == 1 && textureChannels[3] ? byte.MaxValue : byte.MinValue;
bytes[offset + 1] = textureChannels[1] ? bytes[offset + 1] : validChannel == 1 && textureChannels[3] ? byte.MaxValue : byte.MinValue; bytes[offset + 1] = textureChannels[1] ? bytes[offset + 1] : validChannel == 1 && textureChannels[3] ? byte.MaxValue : byte.MinValue;
@@ -786,8 +797,6 @@ namespace AssetStudioGUI
offset += 4; offset += 4;
} }
} }
Marshal.Copy(bytes, 0, bmpData.Scan0, bytes.Length);
bitmap.UnlockBits(bmpData);
} }
PreviewTexture(bitmap); PreviewTexture(bitmap);
@@ -807,40 +816,40 @@ namespace AssetStudioGUI
{ {
switch (m_AudioClip.m_Type) switch (m_AudioClip.m_Type)
{ {
case AudioType.ACC: case FMODSoundType.ACC:
assetItem.InfoText += "Acc"; assetItem.InfoText += "Acc";
break; break;
case AudioType.AIFF: case FMODSoundType.AIFF:
assetItem.InfoText += "AIFF"; assetItem.InfoText += "AIFF";
break; break;
case AudioType.IT: case FMODSoundType.IT:
assetItem.InfoText += "Impulse tracker"; assetItem.InfoText += "Impulse tracker";
break; break;
case AudioType.MOD: case FMODSoundType.MOD:
assetItem.InfoText += "Protracker / Fasttracker MOD"; assetItem.InfoText += "Protracker / Fasttracker MOD";
break; break;
case AudioType.MPEG: case FMODSoundType.MPEG:
assetItem.InfoText += "MP2/MP3 MPEG"; assetItem.InfoText += "MP2/MP3 MPEG";
break; break;
case AudioType.OGGVORBIS: case FMODSoundType.OGGVORBIS:
assetItem.InfoText += "Ogg vorbis"; assetItem.InfoText += "Ogg vorbis";
break; break;
case AudioType.S3M: case FMODSoundType.S3M:
assetItem.InfoText += "ScreamTracker 3"; assetItem.InfoText += "ScreamTracker 3";
break; break;
case AudioType.WAV: case FMODSoundType.WAV:
assetItem.InfoText += "Microsoft WAV"; assetItem.InfoText += "Microsoft WAV";
break; break;
case AudioType.XM: case FMODSoundType.XM:
assetItem.InfoText += "FastTracker 2 XM"; assetItem.InfoText += "FastTracker 2 XM";
break; break;
case AudioType.XMA: case FMODSoundType.XMA:
assetItem.InfoText += "Xbox360 XMA"; assetItem.InfoText += "Xbox360 XMA";
break; break;
case AudioType.VAG: case FMODSoundType.VAG:
assetItem.InfoText += "PlayStation Portable ADPCM"; assetItem.InfoText += "PlayStation Portable ADPCM";
break; break;
case AudioType.AUDIOQUEUE: case FMODSoundType.AUDIOQUEUE:
assetItem.InfoText += "iPhone"; assetItem.InfoText += "iPhone";
break; break;
default: default:
@@ -864,7 +873,7 @@ namespace AssetStudioGUI
case AudioCompressionFormat.MP3: case AudioCompressionFormat.MP3:
assetItem.InfoText += "MP3"; assetItem.InfoText += "MP3";
break; break;
case AudioCompressionFormat.VAG: case AudioCompressionFormat.PSMVAG:
assetItem.InfoText += "PlayStation Portable ADPCM"; assetItem.InfoText += "PlayStation Portable ADPCM";
break; break;
case AudioCompressionFormat.HEVAG: case AudioCompressionFormat.HEVAG:
@@ -943,8 +952,8 @@ namespace AssetStudioGUI
var obj = m_MonoBehaviour.ToType(); var obj = m_MonoBehaviour.ToType();
if (obj == null) if (obj == null)
{ {
var nodes = MonoBehaviourToTypeTreeNodes(m_MonoBehaviour); var type = MonoBehaviourToTypeTree(m_MonoBehaviour);
obj = m_MonoBehaviour.ToType(nodes); obj = m_MonoBehaviour.ToType(type);
} }
var str = JsonConvert.SerializeObject(obj, Formatting.Indented); var str = JsonConvert.SerializeObject(obj, Formatting.Indented);
PreviewText(str); PreviewText(str);
@@ -1151,11 +1160,12 @@ namespace AssetStudioGUI
private void PreviewSprite(AssetItem assetItem, Sprite m_Sprite) private void PreviewSprite(AssetItem assetItem, Sprite m_Sprite)
{ {
var bitmap = m_Sprite.GetImage(); var image = m_Sprite.GetImage();
if (bitmap != null) if (image != null)
{ {
var bitmap = new DirectBitmap(image.ConvertToBytes(), image.Width, image.Height);
image.Dispose();
assetItem.InfoText = $"Width: {bitmap.Width}\nHeight: {bitmap.Height}\n"; assetItem.InfoText = $"Width: {bitmap.Width}\nHeight: {bitmap.Height}\n";
PreviewTexture(bitmap); PreviewTexture(bitmap);
} }
else else
@@ -1164,11 +1174,11 @@ namespace AssetStudioGUI
} }
} }
private void PreviewTexture(Bitmap bitmap) private void PreviewTexture(DirectBitmap bitmap)
{ {
imageTexture?.Dispose(); imageTexture?.Dispose();
imageTexture = bitmap; imageTexture = bitmap;
previewPanel.BackgroundImage = imageTexture; previewPanel.BackgroundImage = imageTexture.Bitmap;
if (imageTexture.Width > previewPanel.Width || imageTexture.Height > previewPanel.Height) if (imageTexture.Width > previewPanel.Width || imageTexture.Height > previewPanel.Height)
previewPanel.BackgroundImageLayout = ImageLayout.Zoom; previewPanel.BackgroundImageLayout = ImageLayout.Zoom;
else else
@@ -1219,6 +1229,7 @@ namespace AssetStudioGUI
classesListView.Groups.Clear(); classesListView.Groups.Clear();
previewPanel.BackgroundImage = Properties.Resources.preview; previewPanel.BackgroundImage = Properties.Resources.preview;
imageTexture?.Dispose(); imageTexture?.Dispose();
imageTexture = null;
previewPanel.BackgroundImageLayout = ImageLayout.Center; previewPanel.BackgroundImageLayout = ImageLayout.Center;
assetInfoLabel.Visible = false; assetInfoLabel.Visible = false;
assetInfoLabel.Text = null; assetInfoLabel.Text = null;
@@ -1305,9 +1316,11 @@ namespace AssetStudioGUI
if (animator != null) if (animator != null)
{ {
var saveFolderDialog = new OpenFolderDialog(); var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK) 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); ExportAnimatorWithAnimationClip(animator, animationList, exportPath);
} }
} }
@@ -1328,9 +1341,11 @@ namespace AssetStudioGUI
if (sceneTreeView.Nodes.Count > 0) if (sceneTreeView.Nodes.Count > 0)
{ {
var saveFolderDialog = new OpenFolderDialog(); var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK) 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; List<AssetItem> animationList = null;
if (animation) if (animation)
{ {
@@ -1365,23 +1380,32 @@ namespace AssetStudioGUI
{ {
var gameObjects = new List<GameObject>(); var gameObjects = new List<GameObject>();
GetSelectedParentNode(sceneTreeView.Nodes, gameObjects); GetSelectedParentNode(sceneTreeView.Nodes, gameObjects);
var saveFileDialog = new SaveFileDialog(); if (gameObjects.Count > 0)
saveFileDialog.FileName = gameObjects[0].m_Name + " (merge).fbx";
saveFileDialog.AddExtension = false;
saveFileDialog.Filter = "Fbx file (*.fbx)|*.fbx";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{ {
var exportPath = saveFileDialog.FileName; var saveFileDialog = new SaveFileDialog();
List<AssetItem> animationList = null; saveFileDialog.FileName = gameObjects[0].m_Name + " (merge).fbx";
if (animation) saveFileDialog.AddExtension = false;
saveFileDialog.Filter = "Fbx file (*.fbx)|*.fbx";
saveFileDialog.InitialDirectory = saveDirectoryBackup;
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{ {
animationList = GetSelectedAssets().Where(x => x.Type == ClassIDType.AnimationClip).ToList(); saveDirectoryBackup = Path.GetDirectoryName(saveFileDialog.FileName);
if (animationList.Count == 0) var exportPath = saveFileDialog.FileName;
List<AssetItem> animationList = null;
if (animation)
{ {
animationList = null; animationList = GetSelectedAssets().Where(x => x.Type == ClassIDType.AnimationClip).ToList();
if (animationList.Count == 0)
{
animationList = null;
}
} }
ExportObjectsMergeWithAnimationClip(exportPath, gameObjects, animationList);
} }
ExportObjectsMergeWithAnimationClip(exportPath, gameObjects, animationList); }
else
{
StatusStripUpdate("No Object selected for export.");
} }
} }
} }
@@ -1461,8 +1485,10 @@ namespace AssetStudioGUI
if (sceneTreeView.Nodes.Count > 0) if (sceneTreeView.Nodes.Count > 0)
{ {
var saveFolderDialog = new OpenFolderDialog(); var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK) if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{ {
saveDirectoryBackup = saveFolderDialog.Folder;
var savePath = saveFolderDialog.Folder + Path.DirectorySeparatorChar; var savePath = saveFolderDialog.Folder + Path.DirectorySeparatorChar;
ExportSplitObjects(savePath, sceneTreeView.Nodes); ExportSplitObjects(savePath, sceneTreeView.Nodes);
} }
@@ -1521,10 +1547,11 @@ namespace AssetStudioGUI
if (exportableAssets.Count > 0) if (exportableAssets.Count > 0)
{ {
var saveFolderDialog = new OpenFolderDialog(); var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK) if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{ {
timer.Stop(); timer.Stop();
saveDirectoryBackup = saveFolderDialog.Folder;
List<AssetItem> toExportAssets = null; List<AssetItem> toExportAssets = null;
switch (type) switch (type)
{ {
@@ -1554,10 +1581,11 @@ namespace AssetStudioGUI
if (exportableAssets.Count > 0) if (exportableAssets.Count > 0)
{ {
var saveFolderDialog = new OpenFolderDialog(); var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK) if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{ {
timer.Stop(); timer.Stop();
saveDirectoryBackup = saveFolderDialog.Folder;
List<AssetItem> toExportAssets = null; List<AssetItem> toExportAssets = null;
switch (type) switch (type)
{ {
@@ -2016,6 +2044,11 @@ namespace AssetStudioGUI
} }
} }
private void toolStripMenuItem15_Click(object sender, EventArgs e)
{
logger.ShowErrorMessage = toolStripMenuItem15.Checked;
}
private void glControl1_MouseWheel(object sender, MouseEventArgs e) private void glControl1_MouseWheel(object sender, MouseEventArgs e)
{ {
if (glControl1.Visible) if (glControl1.Visible)
@@ -7,11 +7,6 @@ namespace AssetStudioGUI
{ {
public GameObject gameObject; public GameObject gameObject;
public GameObjectTreeNode(string name)
{
Text = name;
}
public GameObjectTreeNode(GameObject gameObject) public GameObjectTreeNode(GameObject gameObject)
{ {
this.gameObject = gameObject; this.gameObject = gameObject;
+21 -12
View File
@@ -1,5 +1,4 @@
using System; using System;
using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
@@ -15,12 +14,13 @@ namespace AssetStudioGUI
internal DialogResult ShowDialog(IWin32Window owner = null) internal DialogResult ShowDialog(IWin32Window owner = null)
{ {
//#if NETFRAMEWORK
if (Environment.OSVersion.Version.Major >= 6) if (Environment.OSVersion.Version.Major >= 6)
{ {
return ShowVistaDialog(owner); return ShowVistaDialog(owner);
} }
//#endif
return ShowLegacyDialog(owner); return ShowFolderBrowserDialog(owner);
} }
private DialogResult ShowVistaDialog(IWin32Window owner) private DialogResult ShowVistaDialog(IWin32Window owner)
@@ -29,9 +29,11 @@ namespace AssetStudioGUI
frm.GetOptions(out var options); frm.GetOptions(out var options);
options |= NativeMethods.FOS_PICKFOLDERS | NativeMethods.FOS_FORCEFILESYSTEM | NativeMethods.FOS_NOVALIDATE | NativeMethods.FOS_NOTESTFILECREATE | NativeMethods.FOS_DONTADDTORECENT; options |= NativeMethods.FOS_PICKFOLDERS | NativeMethods.FOS_FORCEFILESYSTEM | NativeMethods.FOS_NOVALIDATE | NativeMethods.FOS_NOTESTFILECREATE | NativeMethods.FOS_DONTADDTORECENT;
frm.SetOptions(options); frm.SetOptions(options);
if (Title != null) if (!string.IsNullOrEmpty(Title))
{
frm.SetTitle(Title); frm.SetTitle(Title);
if (InitialFolder != null) }
if (!string.IsNullOrEmpty(InitialFolder))
{ {
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
if (NativeMethods.SHCreateItemFromParsingName(InitialFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK) if (NativeMethods.SHCreateItemFromParsingName(InitialFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK)
@@ -39,7 +41,7 @@ namespace AssetStudioGUI
frm.SetFolder(directoryShellItem); frm.SetFolder(directoryShellItem);
} }
} }
if (DefaultFolder != null) if (!string.IsNullOrEmpty(DefaultFolder))
{ {
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
if (NativeMethods.SHCreateItemFromParsingName(DefaultFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK) if (NativeMethods.SHCreateItemFromParsingName(DefaultFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK)
@@ -72,7 +74,7 @@ namespace AssetStudioGUI
return DialogResult.Cancel; return DialogResult.Cancel;
} }
private DialogResult ShowLegacyDialog(IWin32Window owner) private DialogResult ShowFolderBrowserDialog(IWin32Window owner)
{ {
using (var frm = new FolderBrowserDialog()) using (var frm = new FolderBrowserDialog())
{ {
@@ -80,13 +82,20 @@ namespace AssetStudioGUI
{ {
frm.SelectedPath = InitialFolder; frm.SelectedPath = InitialFolder;
} }
if ((owner == null ? frm.ShowDialog() : frm.ShowDialog(owner)) == DialogResult.OK) #if !NETFRAMEWORK
if (Title != null)
{ {
Folder = Path.GetDirectoryName(frm.SelectedPath); frm.Description = Title;
return DialogResult.OK; frm.UseDescriptionForTitle = true;
} }
#endif
return DialogResult.Cancel; var result = owner == null ? frm.ShowDialog() : frm.ShowDialog(owner);
if (result == DialogResult.OK)
{
Folder = frm.SelectedPath;
return result;
}
return result;
} }
} }
} }
@@ -1,48 +0,0 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace AssetStudioGUI
{
internal static class TreeViewExtensions
{
private const int TVIF_STATE = 0x8;
private const int TVIS_STATEIMAGEMASK = 0xF000;
private const int TV_FIRST = 0x1100;
private const int TVM_SETITEM = TV_FIRST + 63;
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)]
private struct TVITEM
{
public int mask;
public IntPtr hItem;
public int state;
public int stateMask;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpszText;
public int cchTextMax;
public int iImage;
public int iSelectedImage;
public int cChildren;
public IntPtr lParam;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref TVITEM lParam);
/// <summary>
/// Hides the checkbox for the specified node on a TreeView control.
/// </summary>
public static void HideCheckBox(this TreeNode node)
{
var tvi = new TVITEM
{
hItem = node.Handle,
mask = TVIF_STATE,
stateMask = TVIS_STATEIMAGEMASK,
state = 0
};
SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi);
}
}
}
+5 -5
View File
@@ -7,19 +7,19 @@ namespace AssetStudioGUI
{ {
internal class TypeTreeItem : ListViewItem internal class TypeTreeItem : ListViewItem
{ {
private List<TypeTreeNode> m_Nodes; private TypeTree m_Type;
public TypeTreeItem(int typeID, List<TypeTreeNode> m_Nodes) public TypeTreeItem(int typeID, TypeTree m_Type)
{ {
this.m_Nodes = m_Nodes; this.m_Type = m_Type;
Text = m_Nodes[0].m_Type + " " + m_Nodes[0].m_Name; Text = m_Type.m_Nodes[0].m_Type + " " + m_Type.m_Nodes[0].m_Name;
SubItems.Add(typeID.ToString()); SubItems.Add(typeID.ToString());
} }
public override string ToString() public override string ToString()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
foreach (var i in m_Nodes) foreach (var i in m_Type.m_Nodes)
{ {
sb.AppendFormat("{0}{1} {2} {3} {4}\r\n", new string('\t', i.m_Level), i.m_Type, i.m_Name, i.m_ByteSize, (i.m_MetaFlag & 0x4000) != 0); sb.AppendFormat("{0}{1} {2} {3} {4}\r\n", new string('\t', i.m_Level), i.m_Type, i.m_Name, i.m_ByteSize, (i.m_MetaFlag & 0x4000) != 0);
} }
+43
View File
@@ -0,0 +1,43 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace AssetStudioGUI
{
public sealed class DirectBitmap : IDisposable
{
public DirectBitmap(byte[] buff, int width, int height)
{
Width = width;
Height = height;
Bits = buff;
m_handle = GCHandle.Alloc(Bits, GCHandleType.Pinned);
m_bitmap = new Bitmap(Width, Height, Stride, PixelFormat.Format32bppArgb, m_handle.AddrOfPinnedObject());
}
private void Dispose(bool disposing)
{
if (disposing)
{
m_bitmap.Dispose();
m_handle.Free();
}
m_bitmap = null;
}
public void Dispose()
{
Dispose(true);
}
public int Height { get; }
public int Width { get; }
public int Stride => Width * 4;
public byte[] Bits { get; }
public Bitmap Bitmap => m_bitmap;
private Bitmap m_bitmap;
private readonly GCHandle m_handle;
}
}
+36 -17
View File
@@ -28,6 +28,7 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
this.components = new System.ComponentModel.Container();
this.OKbutton = new System.Windows.Forms.Button(); this.OKbutton = new System.Windows.Forms.Button();
this.Cancel = new System.Windows.Forms.Button(); this.Cancel = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox(); this.groupBox1 = new System.Windows.Forms.GroupBox();
@@ -43,6 +44,7 @@
this.tobmp = new System.Windows.Forms.RadioButton(); this.tobmp = new System.Windows.Forms.RadioButton();
this.converttexture = new System.Windows.Forms.CheckBox(); this.converttexture = new System.Windows.Forms.CheckBox();
this.groupBox2 = new System.Windows.Forms.GroupBox(); this.groupBox2 = new System.Windows.Forms.GroupBox();
this.exportAllUvsAsDiffuseMaps = new System.Windows.Forms.CheckBox();
this.exportBlendShape = new System.Windows.Forms.CheckBox(); this.exportBlendShape = new System.Windows.Forms.CheckBox();
this.exportAnimations = new System.Windows.Forms.CheckBox(); this.exportAnimations = new System.Windows.Forms.CheckBox();
this.scaleFactor = new System.Windows.Forms.NumericUpDown(); this.scaleFactor = new System.Windows.Forms.NumericUpDown();
@@ -59,6 +61,7 @@
this.castToBone = new System.Windows.Forms.CheckBox(); this.castToBone = new System.Windows.Forms.CheckBox();
this.exportAllNodes = new System.Windows.Forms.CheckBox(); this.exportAllNodes = new System.Windows.Forms.CheckBox();
this.eulerFilter = 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.groupBox1.SuspendLayout();
this.panel1.SuspendLayout(); this.panel1.SuspendLayout();
this.groupBox2.SuspendLayout(); this.groupBox2.SuspendLayout();
@@ -69,7 +72,7 @@
// //
// OKbutton // 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.Name = "OKbutton";
this.OKbutton.Size = new System.Drawing.Size(75, 21); this.OKbutton.Size = new System.Drawing.Size(75, 21);
this.OKbutton.TabIndex = 6; this.OKbutton.TabIndex = 6;
@@ -80,7 +83,7 @@
// Cancel // Cancel
// //
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.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.Name = "Cancel";
this.Cancel.Size = new System.Drawing.Size(75, 21); this.Cancel.Size = new System.Drawing.Size(75, 21);
this.Cancel.TabIndex = 7; this.Cancel.TabIndex = 7;
@@ -100,7 +103,7 @@
this.groupBox1.Controls.Add(this.converttexture); this.groupBox1.Controls.Add(this.converttexture);
this.groupBox1.Location = new System.Drawing.Point(12, 12); this.groupBox1.Location = new System.Drawing.Point(12, 12);
this.groupBox1.Name = "groupBox1"; 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.TabIndex = 9;
this.groupBox1.TabStop = false; this.groupBox1.TabStop = false;
this.groupBox1.Text = "Export"; this.groupBox1.Text = "Export";
@@ -182,7 +185,7 @@
this.totga.Name = "totga"; this.totga.Name = "totga";
this.totga.Size = new System.Drawing.Size(41, 16); this.totga.Size = new System.Drawing.Size(41, 16);
this.totga.TabIndex = 2; this.totga.TabIndex = 2;
this.totga.Text = "TGA"; this.totga.Text = "Tga";
this.totga.UseVisualStyleBackColor = true; this.totga.UseVisualStyleBackColor = true;
// //
// tojpg // tojpg
@@ -192,7 +195,7 @@
this.tojpg.Name = "tojpg"; this.tojpg.Name = "tojpg";
this.tojpg.Size = new System.Drawing.Size(47, 16); this.tojpg.Size = new System.Drawing.Size(47, 16);
this.tojpg.TabIndex = 4; this.tojpg.TabIndex = 4;
this.tojpg.Text = "JPEG"; this.tojpg.Text = "Jpeg";
this.tojpg.UseVisualStyleBackColor = true; this.tojpg.UseVisualStyleBackColor = true;
// //
// topng // topng
@@ -204,7 +207,7 @@
this.topng.Size = new System.Drawing.Size(41, 16); this.topng.Size = new System.Drawing.Size(41, 16);
this.topng.TabIndex = 3; this.topng.TabIndex = 3;
this.topng.TabStop = true; this.topng.TabStop = true;
this.topng.Text = "PNG"; this.topng.Text = "Png";
this.topng.UseVisualStyleBackColor = true; this.topng.UseVisualStyleBackColor = true;
// //
// tobmp // tobmp
@@ -214,7 +217,7 @@
this.tobmp.Name = "tobmp"; this.tobmp.Name = "tobmp";
this.tobmp.Size = new System.Drawing.Size(41, 16); this.tobmp.Size = new System.Drawing.Size(41, 16);
this.tobmp.TabIndex = 2; this.tobmp.TabIndex = 2;
this.tobmp.Text = "BMP"; this.tobmp.Text = "Bmp";
this.tobmp.UseVisualStyleBackColor = true; this.tobmp.UseVisualStyleBackColor = true;
// //
// converttexture // converttexture
@@ -232,6 +235,7 @@
// groupBox2 // groupBox2
// //
this.groupBox2.AutoSize = true; this.groupBox2.AutoSize = true;
this.groupBox2.Controls.Add(this.exportAllUvsAsDiffuseMaps);
this.groupBox2.Controls.Add(this.exportBlendShape); this.groupBox2.Controls.Add(this.exportBlendShape);
this.groupBox2.Controls.Add(this.exportAnimations); this.groupBox2.Controls.Add(this.exportAnimations);
this.groupBox2.Controls.Add(this.scaleFactor); this.groupBox2.Controls.Add(this.scaleFactor);
@@ -250,11 +254,24 @@
this.groupBox2.Controls.Add(this.eulerFilter); this.groupBox2.Controls.Add(this.eulerFilter);
this.groupBox2.Location = new System.Drawing.Point(250, 12); this.groupBox2.Location = new System.Drawing.Point(250, 12);
this.groupBox2.Name = "groupBox2"; 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.TabIndex = 11;
this.groupBox2.TabStop = false; this.groupBox2.TabStop = false;
this.groupBox2.Text = "Fbx"; 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 // exportBlendShape
// //
this.exportBlendShape.AutoSize = true; this.exportBlendShape.AutoSize = true;
@@ -287,7 +304,7 @@
0, 0,
0, 0,
131072}); 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.Name = "scaleFactor";
this.scaleFactor.Size = new System.Drawing.Size(60, 21); this.scaleFactor.Size = new System.Drawing.Size(60, 21);
this.scaleFactor.TabIndex = 20; this.scaleFactor.TabIndex = 20;
@@ -301,7 +318,7 @@
// label5 // label5
// //
this.label5.AutoSize = true; 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.Name = "label5";
this.label5.Size = new System.Drawing.Size(71, 12); this.label5.Size = new System.Drawing.Size(71, 12);
this.label5.TabIndex = 19; this.label5.TabIndex = 19;
@@ -314,7 +331,7 @@
this.fbxFormat.Items.AddRange(new object[] { this.fbxFormat.Items.AddRange(new object[] {
"Binary", "Binary",
"Ascii"}); "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.Name = "fbxFormat";
this.fbxFormat.Size = new System.Drawing.Size(61, 20); this.fbxFormat.Size = new System.Drawing.Size(61, 20);
this.fbxFormat.TabIndex = 18; this.fbxFormat.TabIndex = 18;
@@ -322,7 +339,7 @@
// label4 // label4
// //
this.label4.AutoSize = true; 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.Name = "label4";
this.label4.Size = new System.Drawing.Size(59, 12); this.label4.Size = new System.Drawing.Size(59, 12);
this.label4.TabIndex = 17; this.label4.TabIndex = 17;
@@ -339,7 +356,7 @@
"7.3", "7.3",
"7.4", "7.4",
"7.5"}); "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.Name = "fbxVersion";
this.fbxVersion.Size = new System.Drawing.Size(47, 20); this.fbxVersion.Size = new System.Drawing.Size(47, 20);
this.fbxVersion.TabIndex = 16; this.fbxVersion.TabIndex = 16;
@@ -347,7 +364,7 @@
// label3 // label3
// //
this.label3.AutoSize = true; 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.Name = "label3";
this.label3.Size = new System.Drawing.Size(65, 12); this.label3.Size = new System.Drawing.Size(65, 12);
this.label3.TabIndex = 15; this.label3.TabIndex = 15;
@@ -355,7 +372,7 @@
// //
// boneSize // 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.Name = "boneSize";
this.boneSize.Size = new System.Drawing.Size(46, 21); this.boneSize.Size = new System.Drawing.Size(46, 21);
this.boneSize.TabIndex = 11; this.boneSize.TabIndex = 11;
@@ -368,7 +385,7 @@
// label2 // label2
// //
this.label2.AutoSize = true; 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.Name = "label2";
this.label2.Size = new System.Drawing.Size(53, 12); this.label2.Size = new System.Drawing.Size(53, 12);
this.label2.TabIndex = 10; this.label2.TabIndex = 10;
@@ -453,7 +470,7 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.Cancel; 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.groupBox2);
this.Controls.Add(this.groupBox1); this.Controls.Add(this.groupBox1);
this.Controls.Add(this.Cancel); this.Controls.Add(this.Cancel);
@@ -512,5 +529,7 @@
private System.Windows.Forms.Label label6; private System.Windows.Forms.Label label6;
private System.Windows.Forms.CheckBox restoreExtensionName; private System.Windows.Forms.CheckBox restoreExtensionName;
private System.Windows.Forms.CheckBox openAfterExport; 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 AssetStudio;
using System.Collections.Generic; using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
namespace AssetStudioGUI namespace AssetStudioGUI
@@ -19,7 +13,7 @@ namespace AssetStudioGUI
restoreExtensionName.Checked = Properties.Settings.Default.restoreExtensionName; restoreExtensionName.Checked = Properties.Settings.Default.restoreExtensionName;
converttexture.Checked = Properties.Settings.Default.convertTexture; converttexture.Checked = Properties.Settings.Default.convertTexture;
convertAudio.Checked = Properties.Settings.Default.convertAudio; 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) foreach (Control c in panel1.Controls)
{ {
if (c.Text == str) if (c.Text == str)
@@ -36,10 +30,12 @@ namespace AssetStudioGUI
exportAnimations.Checked = Properties.Settings.Default.exportAnimations; exportAnimations.Checked = Properties.Settings.Default.exportAnimations;
exportBlendShape.Checked = Properties.Settings.Default.exportBlendShape; exportBlendShape.Checked = Properties.Settings.Default.exportBlendShape;
castToBone.Checked = Properties.Settings.Default.castToBone; castToBone.Checked = Properties.Settings.Default.castToBone;
exportAllUvsAsDiffuseMaps.Checked = Properties.Settings.Default.exportAllUvsAsDiffuseMaps;
boneSize.Value = Properties.Settings.Default.boneSize; boneSize.Value = Properties.Settings.Default.boneSize;
scaleFactor.Value = Properties.Settings.Default.scaleFactor; scaleFactor.Value = Properties.Settings.Default.scaleFactor;
fbxVersion.SelectedIndex = Properties.Settings.Default.fbxVersion; fbxVersion.SelectedIndex = Properties.Settings.Default.fbxVersion;
fbxFormat.SelectedIndex = Properties.Settings.Default.fbxFormat; fbxFormat.SelectedIndex = Properties.Settings.Default.fbxFormat;
} }
private void OKbutton_Click(object sender, EventArgs e) private void OKbutton_Click(object sender, EventArgs e)
@@ -52,7 +48,7 @@ namespace AssetStudioGUI
{ {
if (((RadioButton)c).Checked) if (((RadioButton)c).Checked)
{ {
Properties.Settings.Default.convertType = c.Text; Properties.Settings.Default.convertType = (ImageFormat)Enum.Parse(typeof(ImageFormat), c.Text);
break; break;
} }
} }
@@ -64,6 +60,7 @@ namespace AssetStudioGUI
Properties.Settings.Default.exportAnimations = exportAnimations.Checked; Properties.Settings.Default.exportAnimations = exportAnimations.Checked;
Properties.Settings.Default.exportBlendShape = exportBlendShape.Checked; Properties.Settings.Default.exportBlendShape = exportBlendShape.Checked;
Properties.Settings.Default.castToBone = castToBone.Checked; Properties.Settings.Default.castToBone = castToBone.Checked;
Properties.Settings.Default.exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps.Checked;
Properties.Settings.Default.boneSize = boneSize.Value; Properties.Settings.Default.boneSize = boneSize.Value;
Properties.Settings.Default.scaleFactor = scaleFactor.Value; Properties.Settings.Default.scaleFactor = scaleFactor.Value;
Properties.Settings.Default.fbxVersion = fbxVersion.SelectedIndex; Properties.Settings.Default.fbxVersion = fbxVersion.SelectedIndex;
@@ -78,5 +75,6 @@ namespace AssetStudioGUI
DialogResult = DialogResult.Cancel; DialogResult = DialogResult.Cancel;
Close(); Close();
} }
} }
} }
+3
View File
@@ -117,4 +117,7 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </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> </root>
+31 -72
View File
@@ -1,11 +1,9 @@
using System.Collections.Generic; using AssetStudio;
using System.Drawing.Imaging; using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using AssetStudio;
using Newtonsoft.Json;
using TGASharpLib;
namespace AssetStudioGUI namespace AssetStudioGUI
{ {
@@ -16,40 +14,20 @@ namespace AssetStudioGUI
var m_Texture2D = (Texture2D)item.Asset; var m_Texture2D = (Texture2D)item.Asset;
if (Properties.Settings.Default.convertTexture) if (Properties.Settings.Default.convertTexture)
{ {
var bitmap = m_Texture2D.ConvertToBitmap(true); var type = Properties.Settings.Default.convertType;
if (bitmap == null) if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
return false; return false;
ImageFormat format = null; var image = m_Texture2D.ConvertToImage(true);
var ext = Properties.Settings.Default.convertType; if (image == null)
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))
return false; return false;
if (tga) using (image)
{ {
var file = new TGA(bitmap); using (var file = File.OpenWrite(exportFullPath))
file.Save(exportFullPath); {
image.WriteToStream(file, type);
}
return true;
} }
else
{
bitmap.Save(exportFullPath, format);
}
bitmap.Dispose();
return true;
} }
else else
{ {
@@ -120,8 +98,8 @@ namespace AssetStudioGUI
var type = m_MonoBehaviour.ToType(); var type = m_MonoBehaviour.ToType();
if (type == null) if (type == null)
{ {
var nodes = Studio.MonoBehaviourToTypeTreeNodes(m_MonoBehaviour); var m_Type = Studio.MonoBehaviourToTypeTree(m_MonoBehaviour);
type = m_MonoBehaviour.ToType(nodes); type = m_MonoBehaviour.ToType(m_Type);
} }
var str = JsonConvert.SerializeObject(type, Formatting.Indented); var str = JsonConvert.SerializeObject(type, Formatting.Indented);
File.WriteAllText(exportFullPath, str); File.WriteAllText(exportFullPath, str);
@@ -174,6 +152,7 @@ namespace AssetStudioGUI
#region UV #region UV
if (m_Mesh.m_UV0?.Length > 0) if (m_Mesh.m_UV0?.Length > 0)
{ {
c = 4;
if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 2) if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 2)
{ {
c = 2; c = 2;
@@ -230,12 +209,11 @@ namespace AssetStudioGUI
public static bool ExportVideoClip(AssetItem item, string exportPath) public static bool ExportVideoClip(AssetItem item, string exportPath)
{ {
var m_VideoClip = (VideoClip)item.Asset; var m_VideoClip = (VideoClip)item.Asset;
var m_VideoData = m_VideoClip.m_VideoData.GetData(); if (m_VideoClip.m_ExternalResources.m_Size > 0)
if (m_VideoData != null && m_VideoData.Length != 0)
{ {
if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath)) if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath))
return false; return false;
File.WriteAllBytes(exportFullPath, m_VideoData); m_VideoClip.m_VideoData.WriteData(exportFullPath);
return true; return true;
} }
return false; return false;
@@ -252,40 +230,20 @@ namespace AssetStudioGUI
public static bool ExportSprite(AssetItem item, string exportPath) public static bool ExportSprite(AssetItem item, string exportPath)
{ {
ImageFormat format = null;
var type = Properties.Settings.Default.convertType; var type = Properties.Settings.Default.convertType;
bool tga = false; if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
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))
return false; return false;
var bitmap = ((Sprite)item.Asset).GetImage(); var image = ((Sprite)item.Asset).GetImage();
if (bitmap != null) if (image != null)
{ {
if (tga) using (image)
{ {
var file = new TGA(bitmap); using (var file = File.OpenWrite(exportFullPath))
file.Save(exportFullPath); {
image.WriteToStream(file, type);
}
return true;
} }
else
{
bitmap.Save(exportFullPath, format);
}
bitmap.Dispose();
return true;
} }
return false; return false;
} }
@@ -359,11 +317,12 @@ namespace AssetStudioGUI
var exportBlendShape = Properties.Settings.Default.exportBlendShape; var exportBlendShape = Properties.Settings.Default.exportBlendShape;
var castToBone = Properties.Settings.Default.castToBone; var castToBone = Properties.Settings.Default.castToBone;
var boneSize = (int)Properties.Settings.Default.boneSize; var boneSize = (int)Properties.Settings.Default.boneSize;
var exportAllUvsAsDiffuseMaps = Properties.Settings.Default.exportAllUvsAsDiffuseMaps;
var scaleFactor = (float)Properties.Settings.Default.scaleFactor; var scaleFactor = (float)Properties.Settings.Default.scaleFactor;
var fbxVersion = Properties.Settings.Default.fbxVersion; var fbxVersion = Properties.Settings.Default.fbxVersion;
var fbxFormat = Properties.Settings.Default.fbxFormat; var fbxFormat = Properties.Settings.Default.fbxFormat;
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision, 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) public static bool ExportDumpFile(AssetItem item, string exportPath)
@@ -373,8 +332,8 @@ namespace AssetStudioGUI
var str = item.Asset.Dump(); var str = item.Asset.Dump();
if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour) if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour)
{ {
var nodes = Studio.MonoBehaviourToTypeTreeNodes(m_MonoBehaviour); var m_Type = Studio.MonoBehaviourToTypeTree(m_MonoBehaviour);
str = m_MonoBehaviour.Dump(nodes); str = m_MonoBehaviour.Dump(m_Type);
} }
if (str != null) if (str != null)
{ {
+17 -6
View File
@@ -1,13 +1,12 @@
using System; using AssetStudio;
using System.Collections.Generic; using System;
using System.Linq; using System.Windows.Forms;
using System.Text;
using AssetStudio;
namespace AssetStudioGUI namespace AssetStudioGUI
{ {
class GUILogger : ILogger class GUILogger : ILogger
{ {
public bool ShowErrorMessage = true;
private Action<string> action; private Action<string> action;
public GUILogger(Action<string> action) public GUILogger(Action<string> action)
@@ -17,7 +16,19 @@ namespace AssetStudioGUI
public void Log(LoggerEvent loggerEvent, string message) public void Log(LoggerEvent loggerEvent, string message)
{ {
action(message); switch (loggerEvent)
{
case LoggerEvent.Error:
if (ShowErrorMessage)
{
MessageBox.Show(message);
}
break;
default:
action(message);
break;
}
} }
} }
} }
-23
View File
@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AssetStudio;
namespace AssetStudioGUI
{
class GUIProgress : IProgress
{
private Action<int> action;
public GUIProgress(Action<int> action)
{
this.action = action;
}
public void Report(int value)
{
action(value);
}
}
}
Binary file not shown.
-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.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -9,11 +9,14 @@ namespace AssetStudioGUI
static class Program static class Program
{ {
/// <summary> /// <summary>
/// 应用程序的主入口点。 /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
static void Main() static void Main()
{ {
#if !NETFRAMEWORK
Application.SetHighDpiMode(HighDpiMode.SystemAware);
#endif
Application.EnableVisualStyles(); Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new AssetStudioGUIForm()); 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> /// <summary>
/// 重写当前线程的 CurrentUICulture 属性 /// 重写当前线程的 CurrentUICulture 属性,对
/// 重写当前线程的 CurrentUICulture 属性 /// 使用此强类型资源类的所有资源查找执行重写
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture { 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.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 { internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 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.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("PNG")] [global::System.Configuration.DefaultSettingValueAttribute("Png")]
public string convertType { public global::AssetStudio.ImageFormat convertType {
get { get {
return ((string)(this["convertType"])); return ((global::AssetStudio.ImageFormat)(this["convertType"]));
} }
set { set {
this["convertType"] = value; this["convertType"] = value;
@@ -262,5 +262,17 @@ namespace AssetStudioGUI.Properties {
this["restoreExtensionName"] = value; 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"> <Setting Name="convertAudio" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value> <Value Profile="(Default)">True</Value>
</Setting> </Setting>
<Setting Name="convertType" Type="System.String" Scope="User"> <Setting Name="convertType" Type="AssetStudio.ImageFormat" Scope="User">
<Value Profile="(Default)">PNG</Value> <Value Profile="(Default)">Png</Value>
</Setting> </Setting>
<Setting Name="eulerFilter" Type="System.Boolean" Scope="User"> <Setting Name="eulerFilter" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value> <Value Profile="(Default)">True</Value>
@@ -62,5 +62,8 @@
<Setting Name="restoreExtensionName" Type="System.Boolean" Scope="User"> <Setting Name="restoreExtensionName" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value> <Value Profile="(Default)">True</Value>
</Setting> </Setting>
<Setting Name="exportAllUvsAsDiffuseMaps" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings> </Settings>
</SettingsFile> </SettingsFile>
+58 -42
View File
@@ -72,37 +72,37 @@ namespace AssetStudioGUI
public static int ExtractFile(string fileName, string savePath) public static int ExtractFile(string fileName, string savePath)
{ {
int extractedCount = 0; int extractedCount = 0;
var type = ImportHelper.CheckFileType(fileName, out var reader); var reader = new FileReader(fileName);
if (type == FileType.BundleFile) if (reader.FileType == FileType.BundleFile)
extractedCount += ExtractBundleFile(fileName, reader, savePath); extractedCount += ExtractBundleFile(reader, savePath);
else if (type == FileType.WebFile) else if (reader.FileType == FileType.WebFile)
extractedCount += ExtractWebDataFile(fileName, reader, savePath); extractedCount += ExtractWebDataFile(reader, savePath);
else else
reader.Dispose(); reader.Dispose();
return extractedCount; 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)} ..."); StatusStripUpdate($"Decompressing {reader.FileName} ...");
var bundleFile = new BundleFile(reader, bundleFilePath); var bundleFile = new BundleFile(reader);
reader.Dispose(); reader.Dispose();
if (bundleFile.fileList.Length > 0) 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 ExtractStreamFile(extractPath, bundleFile.fileList);
} }
return 0; 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); var webFile = new WebFile(reader);
reader.Dispose(); reader.Dispose();
if (webFile.fileList.Length > 0) 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 ExtractStreamFile(extractPath, webFile.fileList);
} }
return 0; return 0;
@@ -113,10 +113,11 @@ namespace AssetStudioGUI
int extractedCount = 0; int extractedCount = 0;
foreach (var file in fileList) foreach (var file in fileList)
{ {
var filePath = Path.Combine(extractPath, file.fileName); var filePath = Path.Combine(extractPath, file.path);
if (!Directory.Exists(extractPath)) var fileDirectory = Path.GetDirectoryName(filePath);
if (!Directory.Exists(fileDirectory))
{ {
Directory.CreateDirectory(extractPath); Directory.CreateDirectory(fileDirectory);
} }
if (!File.Exists(filePath)) if (!File.Exists(filePath))
{ {
@@ -264,7 +265,7 @@ namespace AssetStudioGUI
Progress.Reset(); Progress.Reset();
foreach (var assetsFile in assetsManager.assetsFileList) foreach (var assetsFile in assetsManager.assetsFileList)
{ {
var fileNode = new GameObjectTreeNode(assetsFile.fileName); //RootNode var fileNode = new TreeNode(assetsFile.fileName); //RootNode
foreach (var obj in assetsFile.Objects) foreach (var obj in assetsFile.Objects)
{ {
@@ -306,11 +307,12 @@ namespace AssetStudioGUI
{ {
if (m_Father.m_GameObject.TryGet(out var parentGameObject)) if (m_Father.m_GameObject.TryGet(out var parentGameObject))
{ {
if (!treeNodeDictionary.TryGetValue(parentGameObject, out parentNode)) if (!treeNodeDictionary.TryGetValue(parentGameObject, out var parentGameObjectNode))
{ {
parentNode = new GameObjectTreeNode(parentGameObject); parentGameObjectNode = new GameObjectTreeNode(parentGameObject);
treeNodeDictionary.Add(parentGameObject, parentNode); treeNodeDictionary.Add(parentGameObject, parentGameObjectNode);
} }
parentNode = parentGameObjectNode;
} }
} }
} }
@@ -340,27 +342,27 @@ namespace AssetStudioGUI
{ {
if (typeMap.TryGetValue(assetsFile.unityVersion, out var curVer)) if (typeMap.TryGetValue(assetsFile.unityVersion, out var curVer))
{ {
foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null)) foreach (var type in assetsFile.m_Types.Where(x => x.m_Type != null))
{ {
var key = type.classID; var key = type.classID;
if (type.m_ScriptTypeIndex >= 0) if (type.m_ScriptTypeIndex >= 0)
{ {
key = -1 - type.m_ScriptTypeIndex; key = -1 - type.m_ScriptTypeIndex;
} }
curVer[key] = new TypeTreeItem(key, type.m_Nodes); curVer[key] = new TypeTreeItem(key, type.m_Type);
} }
} }
else else
{ {
var items = new SortedDictionary<int, TypeTreeItem>(); var items = new SortedDictionary<int, TypeTreeItem>();
foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null)) foreach (var type in assetsFile.m_Types.Where(x => x.m_Type != null))
{ {
var key = type.classID; var key = type.classID;
if (type.m_ScriptTypeIndex >= 0) if (type.m_ScriptTypeIndex >= 0)
{ {
key = -1 - type.m_ScriptTypeIndex; key = -1 - type.m_ScriptTypeIndex;
} }
items[key] = new TypeTreeItem(key, type.m_Nodes); items[key] = new TypeTreeItem(key, type.m_Type);
} }
typeMap.Add(assetsFile.unityVersion, items); typeMap.Add(assetsFile.unityVersion, items);
} }
@@ -398,14 +400,21 @@ namespace AssetStudioGUI
} }
break; break;
case 2: //source file case 2: //source file
exportPath = Path.Combine(savePath, asset.SourceFile.fullName + "_export"); if (string.IsNullOrEmpty(asset.SourceFile.originalPath))
{
exportPath = Path.Combine(savePath, asset.SourceFile.fileName + "_export");
}
else
{
exportPath = Path.Combine(savePath, Path.GetFileName(asset.SourceFile.originalPath) + "_export", asset.SourceFile.fileName);
}
break; break;
default: default:
exportPath = savePath; exportPath = savePath;
break; break;
} }
exportPath += Path.DirectorySeparatorChar; exportPath += Path.DirectorySeparatorChar;
StatusStripUpdate($"Exporting {asset.TypeString}: {asset.Text}"); StatusStripUpdate($"[{exportedCount}/{toExportCount}] Exporting {asset.TypeString}: {asset.Text}");
try try
{ {
switch (exportType) switch (exportType)
@@ -449,7 +458,7 @@ namespace AssetStudioGUI
if (Properties.Settings.Default.openAfterExport && exportedCount > 0) if (Properties.Settings.Default.openAfterExport && exportedCount > 0)
{ {
Process.Start(savePath); OpenFolderInExplorer(savePath);
} }
}); });
} }
@@ -494,7 +503,7 @@ namespace AssetStudioGUI
if (Properties.Settings.Default.openAfterExport && toExportAssets.Count() > 0) if (Properties.Settings.Default.openAfterExport && toExportAssets.Count() > 0)
{ {
Process.Start(savePath); OpenFolderInExplorer(savePath);
} }
}); });
} }
@@ -506,7 +515,7 @@ namespace AssetStudioGUI
var count = nodes.Cast<TreeNode>().Sum(x => x.Nodes.Count); var count = nodes.Cast<TreeNode>().Sum(x => x.Nodes.Count);
int k = 0; int k = 0;
Progress.Reset(); Progress.Reset();
foreach (GameObjectTreeNode node in nodes) foreach (TreeNode node in nodes)
{ {
//遍历一级子节点 //遍历一级子节点
foreach (GameObjectTreeNode j in node.Nodes) foreach (GameObjectTreeNode j in node.Nodes)
@@ -523,13 +532,13 @@ namespace AssetStudioGUI
//处理非法文件名 //处理非法文件名
var filename = FixFileName(j.Text); var filename = FixFileName(j.Text);
//每个文件存放在单独的文件夹 //每个文件存放在单独的文件夹
var targetPath = $"{savePath}{filename}\\"; var targetPath = $"{savePath}{filename}{Path.DirectorySeparatorChar}";
//重名文件处理 //重名文件处理
for (int i = 1; ; i++) for (int i = 1; ; i++)
{ {
if (Directory.Exists(targetPath)) if (Directory.Exists(targetPath))
{ {
targetPath = $"{savePath}{filename} ({i})\\"; targetPath = $"{savePath}{filename} ({i}){Path.DirectorySeparatorChar}";
} }
else else
{ {
@@ -554,7 +563,7 @@ namespace AssetStudioGUI
} }
if (Properties.Settings.Default.openAfterExport) if (Properties.Settings.Default.openAfterExport)
{ {
Process.Start(savePath); OpenFolderInExplorer(savePath);
} }
StatusStripUpdate("Finished"); StatusStripUpdate("Finished");
}); });
@@ -580,7 +589,7 @@ namespace AssetStudioGUI
ExportAnimator(animator, exportPath, animationList); ExportAnimator(animator, exportPath, animationList);
if (Properties.Settings.Default.openAfterExport) if (Properties.Settings.Default.openAfterExport)
{ {
Process.Start(exportPath); OpenFolderInExplorer(exportPath);
} }
Progress.Report(1, 1); Progress.Report(1, 1);
StatusStripUpdate($"Finished exporting {animator.Text}"); StatusStripUpdate($"Finished exporting {animator.Text}");
@@ -622,12 +631,12 @@ namespace AssetStudioGUI
} }
if (Properties.Settings.Default.openAfterExport) if (Properties.Settings.Default.openAfterExport)
{ {
Process.Start(exportPath); OpenFolderInExplorer(exportPath);
} }
} }
else else
{ {
StatusStripUpdate("No Object can be exported."); StatusStripUpdate("No Object selected for export.");
} }
}); });
} }
@@ -652,18 +661,18 @@ namespace AssetStudioGUI
} }
if (Properties.Settings.Default.openAfterExport) if (Properties.Settings.Default.openAfterExport)
{ {
Process.Start(Path.GetDirectoryName(exportPath)); OpenFolderInExplorer(Path.GetDirectoryName(exportPath));
} }
}); });
} }
public static void GetSelectedParentNode(TreeNodeCollection nodes, List<GameObject> gameObjects) public static void GetSelectedParentNode(TreeNodeCollection nodes, List<GameObject> gameObjects)
{ {
foreach (GameObjectTreeNode i in nodes) foreach (TreeNode i in nodes)
{ {
if (i.Checked) if (i is GameObjectTreeNode gameObjectTreeNode && i.Checked)
{ {
gameObjects.Add(i.gameObject); gameObjects.Add(gameObjectTreeNode.gameObject);
} }
else else
{ {
@@ -672,7 +681,7 @@ namespace AssetStudioGUI
} }
} }
public static List<TypeTreeNode> MonoBehaviourToTypeTreeNodes(MonoBehaviour m_MonoBehaviour) public static TypeTree MonoBehaviourToTypeTree(MonoBehaviour m_MonoBehaviour)
{ {
if (!assemblyLoader.Loaded) if (!assemblyLoader.Loaded)
{ {
@@ -687,7 +696,7 @@ namespace AssetStudioGUI
assemblyLoader.Loaded = true; assemblyLoader.Loaded = true;
} }
} }
return m_MonoBehaviour.ConvertToTypeTreeNodes(assemblyLoader); return m_MonoBehaviour.ConvertToTypeTree(assemblyLoader);
} }
public static string DumpAsset(Object obj) public static string DumpAsset(Object obj)
@@ -695,10 +704,17 @@ namespace AssetStudioGUI
var str = obj.Dump(); var str = obj.Dump();
if (str == null && obj is MonoBehaviour m_MonoBehaviour) if (str == null && obj is MonoBehaviour m_MonoBehaviour)
{ {
var nodes = MonoBehaviourToTypeTreeNodes(m_MonoBehaviour); var type = MonoBehaviourToTypeTree(m_MonoBehaviour);
str = m_MonoBehaviour.Dump(nodes); str = m_MonoBehaviour.Dump(type);
} }
return str; return str;
} }
public static void OpenFolderInExplorer(string path)
{
var info = new ProcessStartInfo(path);
info.UseShellExecute = true;
Process.Start(info);
}
} }
} }
-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 resolver = new MyAssemblyResolver();
var readerParameters = new ReaderParameters(); var readerParameters = new ReaderParameters();
readerParameters.AssemblyResolver = resolver; readerParameters.AssemblyResolver = resolver;
try foreach (var file in files)
{ {
foreach (var file in files) try
{ {
var assembly = AssemblyDefinition.ReadAssembly(file, readerParameters); var assembly = AssemblyDefinition.ReadAssembly(file, readerParameters);
resolver.Register(assembly); resolver.Register(assembly);
moduleDic.Add(assembly.MainModule.Name, assembly.MainModule); moduleDic.Add(assembly.MainModule.Name, assembly.MainModule);
} }
} catch
catch {
{ // ignored
// ignored }
} }
Loaded = true; Loaded = true;
} }
+18 -102
View File
@@ -1,108 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<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> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFrameworks>net472;netstandard2.0;net5.0;net6.0</TargetFrameworks>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Version>0.16.0.0</Version>
<ProjectGuid>{80AEC261-21EE-4E4F-A93B-7A744DC84888}</ProjectGuid> <AssemblyVersion>0.16.0.0</AssemblyVersion>
<OutputType>Library</OutputType> <FileVersion>0.16.0.0</FileVersion>
<AppDesignerFolder>Properties</AppDesignerFolder> <Copyright>Copyright © Perfare 2018-2022</Copyright>
<RootNamespace>AssetStudioUtility</RootNamespace> <DebugType>embedded</DebugType>
<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>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <PackageReference Include="Mono.Cecil" Version="0.11.3" />
<Reference Include="System.Core" /> <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta13" />
<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>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AssemblyLoader.cs" /> <ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
<Compile Include="AudioClipConverter.cs" /> <ProjectReference Include="..\AssetStudioFBXWrapper\AssetStudioFBXWrapper.csproj" />
<Compile Include="CSspv\Disassembler.cs" /> <ProjectReference Include="..\AssetStudio\AssetStudio.csproj" />
<Compile Include="CSspv\EnumValuesExtensions.cs" /> <ProjectReference Include="..\Texture2DDecoderWrapper\Texture2DDecoderWrapper.csproj" />
<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" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj"> </Project>
<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>
+20 -20
View File
@@ -94,29 +94,29 @@ namespace AssetStudio
{ {
switch (m_AudioClip.m_Type) switch (m_AudioClip.m_Type)
{ {
case AudioType.ACC: case FMODSoundType.ACC:
return ".m4a"; return ".m4a";
case AudioType.AIFF: case FMODSoundType.AIFF:
return ".aif"; return ".aif";
case AudioType.IT: case FMODSoundType.IT:
return ".it"; return ".it";
case AudioType.MOD: case FMODSoundType.MOD:
return ".mod"; return ".mod";
case AudioType.MPEG: case FMODSoundType.MPEG:
return ".mp3"; return ".mp3";
case AudioType.OGGVORBIS: case FMODSoundType.OGGVORBIS:
return ".ogg"; return ".ogg";
case AudioType.S3M: case FMODSoundType.S3M:
return ".s3m"; return ".s3m";
case AudioType.WAV: case FMODSoundType.WAV:
return ".wav"; return ".wav";
case AudioType.XM: case FMODSoundType.XM:
return ".xm"; return ".xm";
case AudioType.XMA: case FMODSoundType.XMA:
return ".wav"; return ".wav";
case AudioType.VAG: case FMODSoundType.VAG:
return ".vag"; return ".vag";
case AudioType.AUDIOQUEUE: case FMODSoundType.AUDIOQUEUE:
return ".fsb"; return ".fsb";
} }
@@ -133,7 +133,7 @@ namespace AssetStudio
return ".fsb"; return ".fsb";
case AudioCompressionFormat.MP3: case AudioCompressionFormat.MP3:
return ".fsb"; return ".fsb";
case AudioCompressionFormat.VAG: case AudioCompressionFormat.PSMVAG:
return ".fsb"; return ".fsb";
case AudioCompressionFormat.HEVAG: case AudioCompressionFormat.HEVAG:
return ".fsb"; return ".fsb";
@@ -159,13 +159,13 @@ namespace AssetStudio
{ {
switch (m_AudioClip.m_Type) switch (m_AudioClip.m_Type)
{ {
case AudioType.AIFF: case FMODSoundType.AIFF:
case AudioType.IT: case FMODSoundType.IT:
case AudioType.MOD: case FMODSoundType.MOD:
case AudioType.S3M: case FMODSoundType.S3M:
case AudioType.XM: case FMODSoundType.XM:
case AudioType.XMA: case FMODSoundType.XMA:
case AudioType.AUDIOQUEUE: case FMODSoundType.AUDIOQUEUE:
return true; return true;
default: default:
return false; return false;
+55
View File
@@ -0,0 +1,55 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.Formats.Tga;
using SixLabors.ImageSharp.PixelFormats;
using System.IO;
using System.Runtime.InteropServices;
namespace AssetStudio
{
public static class ImageExtensions
{
public static void WriteToStream(this Image image, Stream stream, ImageFormat imageFormat)
{
switch (imageFormat)
{
case ImageFormat.Jpeg:
image.SaveAsJpeg(stream);
break;
case ImageFormat.Png:
image.SaveAsPng(stream);
break;
case ImageFormat.Bmp:
image.Save(stream, new BmpEncoder
{
BitsPerPixel = BmpBitsPerPixel.Pixel32,
SupportTransparency = true
});
break;
case ImageFormat.Tga:
image.Save(stream, new TgaEncoder
{
BitsPerPixel = TgaBitsPerPixel.Pixel32,
Compression = TgaCompression.None
});
break;
}
}
public static MemoryStream ConvertToStream(this Image image, ImageFormat imageFormat)
{
var stream = new MemoryStream();
image.WriteToStream(stream, imageFormat);
return stream;
}
public static byte[] ConvertToBytes<TPixel>(this Image<TPixel> image) where TPixel : unmanaged, IPixel<TPixel>
{
if (image.TryGetSinglePixelSpan(out var pixelSpan))
{
return MemoryMarshal.AsBytes(pixelSpan).ToArray();
}
return null;
}
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace AssetStudio
{
public enum ImageFormat
{
Jpeg,
Png,
Bmp,
Tga
}
}
Binary file not shown.
Binary file not shown.
+111 -131
View File
@@ -1,10 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using TGASharpLib;
namespace AssetStudio namespace AssetStudio
{ {
@@ -17,15 +14,16 @@ namespace AssetStudio
public List<ImportedKeyframedAnimation> AnimationList { get; protected set; } = new List<ImportedKeyframedAnimation>(); public List<ImportedKeyframedAnimation> AnimationList { get; protected set; } = new List<ImportedKeyframedAnimation>();
public List<ImportedMorph> MorphList { get; protected set; } = new List<ImportedMorph>(); public List<ImportedMorph> MorphList { get; protected set; } = new List<ImportedMorph>();
private string imageFormat; private ImageFormat imageFormat;
private Avatar avatar; private Avatar avatar;
private HashSet<AnimationClip> animationClipHashSet = new HashSet<AnimationClip>(); 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<uint, string> bonePathHash = new Dictionary<uint, string>();
private Dictionary<Texture2D, string> textureNameDictionary = new Dictionary<Texture2D, string>(); private Dictionary<Texture2D, string> textureNameDictionary = new Dictionary<Texture2D, string>();
private Dictionary<Transform, ImportedFrame> transformDictionary = new Dictionary<Transform, ImportedFrame>(); private Dictionary<Transform, ImportedFrame> transformDictionary = new Dictionary<Transform, ImportedFrame>();
Dictionary<uint, string> morphChannelNames = new Dictionary<uint, string>(); 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; this.imageFormat = imageFormat;
if (m_GameObject.m_Animator != null) if (m_GameObject.m_Animator != null)
@@ -50,7 +48,7 @@ namespace AssetStudio
ConvertAnimations(); 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; this.imageFormat = imageFormat;
RootFrame = CreateFrame(rootName, Vector3.Zero, new Quaternion(0, 0, 0, 0), Vector3.One); RootFrame = CreateFrame(rootName, Vector3.Zero, new Quaternion(0, 0, 0, 0), Vector3.One);
@@ -80,7 +78,7 @@ namespace AssetStudio
ConvertAnimations(); ConvertAnimations();
} }
public ModelConverter(Animator m_Animator, string imageFormat, AnimationClip[] animationList = null) public ModelConverter(Animator m_Animator, ImageFormat imageFormat, AnimationClip[] animationList = null)
{ {
this.imageFormat = imageFormat; this.imageFormat = imageFormat;
InitWithAnimator(m_Animator); InitWithAnimator(m_Animator);
@@ -166,6 +164,10 @@ namespace AssetStudio
{ {
if (animation.TryGet(out var animationClip)) if (animation.TryGet(out var animationClip))
{ {
if (!boundAnimationPathDic.ContainsKey(animationClip))
{
boundAnimationPathDic.Add(animationClip, GetTransformPath(m_Transform));
}
animationClipHashSet.Add(animationClip); animationClipHashSet.Add(animationClip);
} }
} }
@@ -319,79 +321,8 @@ namespace AssetStudio
} }
ImportedMaterial iMat = ConvertMaterial(mat); ImportedMaterial iMat = ConvertMaterial(mat);
iSubmesh.Material = iMat.Name; iSubmesh.Material = iMat.Name;
iSubmesh.VertexList = new List<ImportedVertex>((int)submesh.vertexCount); iSubmesh.BaseVertex = (int)mesh.m_SubMeshes[i].firstVertex;
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);
}
//Face //Face
iSubmesh.FaceList = new List<ImportedFace>(numFaces); iSubmesh.FaceList = new List<ImportedFace>(numFaces);
var end = firstFace + numFaces; var end = firstFace + numFaces;
@@ -405,9 +336,85 @@ namespace AssetStudio
iSubmesh.FaceList.Add(face); iSubmesh.FaceList.Add(face);
} }
firstFace = end; firstFace = end;
iMesh.SubmeshList.Add(iSubmesh); 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) if (meshR is SkinnedMeshRenderer sMesh)
{ {
//Bone //Bone
@@ -524,7 +531,7 @@ namespace AssetStudio
keyframe.VertexList.Add(destVertex); keyframe.VertexList.Add(destVertex);
var morphVertex = mesh.m_Shapes.vertices[j]; var morphVertex = mesh.m_Shapes.vertices[j];
destVertex.Index = morphVertex.index; destVertex.Index = morphVertex.index;
var sourceVertex = GetSourceVertex(iMesh.SubmeshList, (int)morphVertex.index); var sourceVertex = iMesh.VertexList[(int)morphVertex.index];
destVertex.Vertex = new ImportedVertex(); destVertex.Vertex = new ImportedVertex();
var morphPos = morphVertex.vertex; var morphPos = morphVertex.vertex;
destVertex.Vertex.Vertex = sourceVertex.Vertex + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z); destVertex.Vertex.Vertex = sourceVertex.Vertex + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z);
@@ -598,6 +605,15 @@ namespace AssetStudio
return null; 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) private string FixBonePath(string path)
{ {
var frame = RootFrame.FindFrameByPath(path); var frame = RootFrame.FindFrameByPath(path);
@@ -694,7 +710,7 @@ namespace AssetStudio
texture.Dest = dest; texture.Dest = dest;
var ext = $".{imageFormat.ToLower()}"; var ext = $".{imageFormat.ToString().ToLower()}";
if (textureNameDictionary.TryGetValue(m_Texture2D, out var textureName)) if (textureNameDictionary.TryGetValue(m_Texture2D, out var textureName))
{ {
texture.Name = textureName; texture.Name = textureName;
@@ -740,30 +756,13 @@ namespace AssetStudio
return; return;
} }
var bitmap = m_Texture2D.ConvertToBitmap(true); var stream = m_Texture2D.ConvertToStream(imageFormat, true);
if (bitmap != null) 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); iTex = new ImportedTexture(stream, name);
TextureList.Add(iTex); TextureList.Add(iTex);
bitmap.Dispose();
} }
} }
} }
@@ -794,7 +793,7 @@ namespace AssetStudio
{ {
foreach (var m_CompressedRotationCurve in animationClip.m_CompressedRotationCurves) 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 numKeys = m_CompressedRotationCurve.m_Times.m_NumItems;
var data = m_CompressedRotationCurve.m_Times.UnpackInts(); var data = m_CompressedRotationCurve.m_Times.UnpackInts();
@@ -816,7 +815,7 @@ namespace AssetStudio
} }
foreach (var m_RotationCurve in animationClip.m_RotationCurves) 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) 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)); 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) 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) 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))); 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) 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) 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))); 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) 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) 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))); 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); channelName = channelName.Substring(dotPos + 1);
} }
var path = FixBonePath(m_FloatCurve.path); var path = FixBonePath(animationClip, m_FloatCurve.path);
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
{ {
path = GetPathByChannelName(channelName); path = GetPathByChannelName(channelName);
@@ -880,7 +879,7 @@ namespace AssetStudio
{ {
var m_Clip = animationClip.m_MuscleClip.m_Clip; var m_Clip = animationClip.m_MuscleClip.m_Clip;
var streamedFrames = m_Clip.m_StreamedClip.ReadData(); 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++) for (int frameIndex = 1; frameIndex < streamedFrames.Count - 1; frameIndex++)
{ {
var frame = streamedFrames[frameIndex]; var frame = streamedFrames[frameIndex];
@@ -1014,20 +1013,6 @@ namespace AssetStudio
return boneName; 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) private void CreateBonePathHash(Transform m_Transform)
{ {
var name = GetTransformPathByFather(m_Transform); var name = GetTransformPathByFather(m_Transform);
@@ -1078,26 +1063,21 @@ namespace AssetStudio
else else
{ {
transformName = strs.Last(); transformName = strs.Last();
var parentFrameName = strs[strs.Length - 2]; var parentFramePath = path.Substring(0, path.LastIndexOf('/'));
parentFrame = RootFrame.FindChild(parentFrameName); parentFrame = RootFrame.FindRelativeFrameWithPath(parentFramePath);
//var parentFramePath = path.Substring(0, path.LastIndexOf('/'));
//parentFrame = RootFrame.FindFrameByPath(parentFramePath);
} }
var skeletonPose = avatar.m_Avatar.m_DefaultPose; var skeletonPose = avatar.m_Avatar.m_DefaultPose;
var xform = skeletonPose.m_X[i]; var xform = skeletonPose.m_X[i];
var frame = RootFrame.FindChild(transformName); var frame = RootFrame.FindChild(transformName);
if (frame != null) if (frame != null)
{ {
SetFrame(frame, xform.t, xform.q, xform.s); SetFrame(frame, xform.t, xform.q, xform.s);
parentFrame.AddChild(frame);
} }
else else
{ {
frame = CreateFrame(transformName, xform.t, xform.q, xform.s); frame = CreateFrame(transformName, xform.t, xform.q, xform.s);
parentFrame.AddChild(frame);
} }
parentFrame.AddChild(frame);
} }
} }
+2 -2
View File
@@ -3,9 +3,9 @@
public static class ModelExporter public static class ModelExporter
{ {
public static void ExportFbx(string path, IImported imported, bool eulerFilter, float filterPrecision, 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);
} }
} }
} }
+6 -5
View File
@@ -4,21 +4,22 @@ namespace AssetStudio
{ {
public static class MonoBehaviourConverter public static class MonoBehaviourConverter
{ {
public static List<TypeTreeNode> ConvertToTypeTreeNodes(this MonoBehaviour m_MonoBehaviour, AssemblyLoader assemblyLoader) public static TypeTree ConvertToTypeTree(this MonoBehaviour m_MonoBehaviour, AssemblyLoader assemblyLoader)
{ {
var nodes = new List<TypeTreeNode>(); var m_Type = new TypeTree();
m_Type.m_Nodes = new List<TypeTreeNode>();
var helper = new SerializedTypeHelper(m_MonoBehaviour.version); var helper = new SerializedTypeHelper(m_MonoBehaviour.version);
helper.AddMonoBehaviour(nodes, 0); helper.AddMonoBehaviour(m_Type.m_Nodes, 0);
if (m_MonoBehaviour.m_Script.TryGet(out var m_Script)) if (m_MonoBehaviour.m_Script.TryGet(out var m_Script))
{ {
var typeDef = assemblyLoader.GetTypeDefinition(m_Script.m_AssemblyName, string.IsNullOrEmpty(m_Script.m_Namespace) ? m_Script.m_ClassName : $"{m_Script.m_Namespace}.{m_Script.m_ClassName}"); var typeDef = assemblyLoader.GetTypeDefinition(m_Script.m_AssemblyName, string.IsNullOrEmpty(m_Script.m_Namespace) ? m_Script.m_ClassName : $"{m_Script.m_Namespace}.{m_Script.m_ClassName}");
if (typeDef != null) if (typeDef != null)
{ {
var typeDefinitionConverter = new TypeDefinitionConverter(typeDef, helper, 1); var typeDefinitionConverter = new TypeDefinitionConverter(typeDef, helper, 1);
nodes.AddRange(typeDefinitionConverter.ConvertToTypeTreeNodes()); m_Type.m_Nodes.AddRange(typeDefinitionConverter.ConvertToTypeTreeNodes());
} }
} }
return nodes; return m_Type;
} }
} }
} }
@@ -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")]
+510 -209
View File
@@ -1,9 +1,10 @@
using System; using K4os.Compression.LZ4;
using System;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Lz4;
namespace AssetStudio namespace AssetStudio
{ {
@@ -14,13 +15,11 @@ namespace AssetStudio
if (shader.m_SubProgramBlob != null) //5.3 - 5.4 if (shader.m_SubProgramBlob != null) //5.3 - 5.4
{ {
var decompressedBytes = new byte[shader.decompressedSize]; var decompressedBytes = new byte[shader.decompressedSize];
using (var decoder = new Lz4DecoderStream(new MemoryStream(shader.m_SubProgramBlob))) LZ4Codec.Decode(shader.m_SubProgramBlob, decompressedBytes);
{
decoder.Read(decompressedBytes, 0, (int)shader.decompressedSize);
}
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes))) using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
{ {
var program = new ShaderProgram(blobReader, shader.version); var program = new ShaderProgram(blobReader, shader.version);
program.Read(blobReader, 0);
return header + program.Export(Encoding.UTF8.GetString(shader.m_Script)); return header + program.Export(Encoding.UTF8.GetString(shader.m_Script));
} }
} }
@@ -35,19 +34,25 @@ namespace AssetStudio
private static string ConvertSerializedShader(Shader shader) private static string ConvertSerializedShader(Shader shader)
{ {
var shaderPrograms = new ShaderProgram[shader.platforms.Length]; var length = shader.platforms.Length;
for (var i = 0; i < shader.platforms.Length; i++) var shaderPrograms = new ShaderProgram[length];
for (var i = 0; i < length; i++)
{ {
var compressedBytes = new byte[shader.compressedLengths[i]]; for (var j = 0; j < shader.offsets[i].Length; j++)
Buffer.BlockCopy(shader.compressedBlob, (int)shader.offsets[i], compressedBytes, 0, (int)shader.compressedLengths[i]);
var decompressedBytes = new byte[shader.decompressedLengths[i]];
using (var decoder = new Lz4DecoderStream(new MemoryStream(compressedBytes)))
{ {
decoder.Read(decompressedBytes, 0, (int)shader.decompressedLengths[i]); var offset = shader.offsets[i][j];
} var compressedLength = shader.compressedLengths[i][j];
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes))) var decompressedLength = shader.decompressedLengths[i][j];
{ var decompressedBytes = new byte[decompressedLength];
shaderPrograms[i] = new ShaderProgram(blobReader, shader.version); LZ4Codec.Decode(shader.compressedBlob, (int)offset, (int)compressedLength, decompressedBytes, 0, (int)decompressedLength);
using (var blobReader = new BinaryReader(new MemoryStream(decompressedBytes)))
{
if (j == 0)
{
shaderPrograms[i] = new ShaderProgram(blobReader, shader.version);
}
shaderPrograms[i].Read(blobReader, j);
}
} }
} }
@@ -104,17 +109,17 @@ namespace AssetStudio
var sb = new StringBuilder(); var sb = new StringBuilder();
switch (m_Passe.m_Type) switch (m_Passe.m_Type)
{ {
case PassType.kPassTypeNormal: case PassType.Normal:
sb.Append(" Pass "); sb.Append(" Pass ");
break; break;
case PassType.kPassTypeUse: case PassType.Use:
sb.Append(" UsePass "); sb.Append(" UsePass ");
break; break;
case PassType.kPassTypeGrab: case PassType.Grab:
sb.Append(" GrabPass "); sb.Append(" GrabPass ");
break; break;
} }
if (m_Passe.m_Type == PassType.kPassTypeUse) if (m_Passe.m_Type == PassType.Use)
{ {
sb.Append($"\"{m_Passe.m_UseName}\"\n"); sb.Append($"\"{m_Passe.m_UseName}\"\n");
} }
@@ -122,7 +127,7 @@ namespace AssetStudio
{ {
sb.Append("{\n"); sb.Append("{\n");
if (m_Passe.m_Type == PassType.kPassTypeGrab) if (m_Passe.m_Type == PassType.Grab)
{ {
if (!string.IsNullOrEmpty(m_Passe.m_TextureName)) if (!string.IsNullOrEmpty(m_Passe.m_TextureName))
{ {
@@ -167,6 +172,13 @@ namespace AssetStudio
sb.Append(ConvertSerializedSubPrograms(m_Passe.progDomain.m_SubPrograms, platforms, shaderPrograms)); sb.Append(ConvertSerializedSubPrograms(m_Passe.progDomain.m_SubPrograms, platforms, shaderPrograms));
sb.Append("}\n"); sb.Append("}\n");
} }
if (m_Passe.progRayTracing?.m_SubPrograms.Length > 0)
{
sb.Append("Program \"rtp\" {\n");
sb.Append(ConvertSerializedSubPrograms(m_Passe.progRayTracing.m_SubPrograms, platforms, shaderPrograms));
sb.Append("}\n");
}
} }
sb.Append("}\n"); sb.Append("}\n");
} }
@@ -222,7 +234,7 @@ namespace AssetStudio
sb.Append(ConvertSerializedTagMap(m_State.m_Tags, 2)); 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) if (m_State.alphaToMask.val > 0f)
{ {
@@ -293,9 +305,111 @@ namespace AssetStudio
sb.Append($" Offset {m_State.offsetFactor.val}, {m_State.offsetUnits.val}\n"); 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.Unknown ||
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.Unknown)
{
sb.Append(" Mode ");
switch (m_State.fogMode)
{
case FogMode.Disabled:
sb.Append("Off");
break;
case FogMode.Linear:
sb.Append("Linear");
break;
case FogMode.Exp:
sb.Append("Exp");
break;
case FogMode.Exp2:
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) if (m_State.lighting)
{ {
@@ -307,27 +421,220 @@ namespace AssetStudio
return sb.ToString(); return sb.ToString();
} }
private static string ConvertSerializedShaderRTBlendState(SerializedShaderRTBlendState[] rtBlend) private static string ConvertSerializedStencilOp(SerializedStencilOp stencilOp, string suffix)
{ {
//TODO Blend
var sb = new StringBuilder(); 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]; var blend = rtBlend[i];
if (!blend.srcBlend.val.Equals(1f) || if (blend.srcBlend.val != 1f ||
!blend.destBlend.val.Equals(0f) || blend.destBlend.val != 0f ||
!blend.srcBlendAlpha.val.Equals(1f) || blend.srcBlendAlpha.val != 1f ||
!blend.destBlendAlpha.val.Equals(0f)) blend.destBlendAlpha.val != 0f)
{ {
sb.Append(" Blend "); sb.Append(" Blend ");
sb.Append($"{i} "); if (i != 0 || rtSeparateBlend)
sb.Append('\n'); {
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(); 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) private static string ConvertSerializedTagMap(SerializedTagMap m_Tags, int intent)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@@ -367,37 +674,37 @@ namespace AssetStudio
sb.Append($"{m_Prop.m_Name} (\"{m_Prop.m_Description}\", "); sb.Append($"{m_Prop.m_Name} (\"{m_Prop.m_Description}\", ");
switch (m_Prop.m_Type) switch (m_Prop.m_Type)
{ {
case SerializedPropertyType.kColor: case SerializedPropertyType.Color:
sb.Append("Color"); sb.Append("Color");
break; break;
case SerializedPropertyType.kVector: case SerializedPropertyType.Vector:
sb.Append("Vector"); sb.Append("Vector");
break; break;
case SerializedPropertyType.kFloat: case SerializedPropertyType.Float:
sb.Append("Float"); sb.Append("Float");
break; break;
case SerializedPropertyType.kRange: case SerializedPropertyType.Range:
sb.Append($"Range({m_Prop.m_DefValue[1]}, {m_Prop.m_DefValue[2]})"); sb.Append($"Range({m_Prop.m_DefValue[1]}, {m_Prop.m_DefValue[2]})");
break; break;
case SerializedPropertyType.kTexture: case SerializedPropertyType.Texture:
switch (m_Prop.m_DefTexture.m_TexDim) switch (m_Prop.m_DefTexture.m_TexDim)
{ {
case TextureDimension.kTexDimAny: case TextureDimension.Any:
sb.Append("any"); sb.Append("any");
break; break;
case TextureDimension.kTexDim2D: case TextureDimension.Tex2D:
sb.Append("2D"); sb.Append("2D");
break; break;
case TextureDimension.kTexDim3D: case TextureDimension.Tex3D:
sb.Append("3D"); sb.Append("3D");
break; break;
case TextureDimension.kTexDimCUBE: case TextureDimension.Cube:
sb.Append("Cube"); sb.Append("Cube");
break; break;
case TextureDimension.kTexDim2DArray: case TextureDimension.Tex2DArray:
sb.Append("2DArray"); sb.Append("2DArray");
break; break;
case TextureDimension.kTexDimCubeArray: case TextureDimension.CubeArray:
sb.Append("CubeArray"); sb.Append("CubeArray");
break; break;
} }
@@ -406,15 +713,15 @@ namespace AssetStudio
sb.Append(") = "); sb.Append(") = ");
switch (m_Prop.m_Type) switch (m_Prop.m_Type)
{ {
case SerializedPropertyType.kColor: case SerializedPropertyType.Color:
case SerializedPropertyType.kVector: case SerializedPropertyType.Vector:
sb.Append($"({m_Prop.m_DefValue[0]},{m_Prop.m_DefValue[1]},{m_Prop.m_DefValue[2]},{m_Prop.m_DefValue[3]})"); sb.Append($"({m_Prop.m_DefValue[0]},{m_Prop.m_DefValue[1]},{m_Prop.m_DefValue[2]},{m_Prop.m_DefValue[3]})");
break; break;
case SerializedPropertyType.kFloat: case SerializedPropertyType.Float:
case SerializedPropertyType.kRange: case SerializedPropertyType.Range:
sb.Append(m_Prop.m_DefValue[0]); sb.Append(m_Prop.m_DefValue[0]);
break; break;
case SerializedPropertyType.kTexture: case SerializedPropertyType.Texture:
sb.Append($"\"{m_Prop.m_DefTexture.m_DefaultName}\" {{ }}"); sb.Append($"\"{m_Prop.m_DefTexture.m_DefaultName}\" {{ }}");
break; break;
default: default:
@@ -428,100 +735,65 @@ namespace AssetStudio
{ {
switch (platform) switch (platform)
{ {
case ShaderCompilerPlatform.kShaderCompPlatformGL: case ShaderCompilerPlatform.GL:
return programType == ShaderGpuProgramType.kShaderGpuProgramGLLegacy; return programType == ShaderGpuProgramType.GLLegacy;
case ShaderCompilerPlatform.kShaderCompPlatformD3D9: case ShaderCompilerPlatform.D3D9:
return programType == ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM20 return programType == ShaderGpuProgramType.DX9VertexSM20
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM30 || programType == ShaderGpuProgramType.DX9VertexSM30
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM20 || programType == ShaderGpuProgramType.DX9PixelSM20
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM30; || programType == ShaderGpuProgramType.DX9PixelSM30;
case ShaderCompilerPlatform.kShaderCompPlatformXbox360: case ShaderCompilerPlatform.Xbox360:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS case ShaderCompilerPlatform.PS3:
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS case ShaderCompilerPlatform.PSP2:
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS case ShaderCompilerPlatform.PS4:
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS case ShaderCompilerPlatform.XboxOne:
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS; case ShaderCompilerPlatform.N3DS:
case ShaderCompilerPlatform.kShaderCompPlatformPS3: case ShaderCompilerPlatform.WiiU:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS case ShaderCompilerPlatform.Switch:
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleFS case ShaderCompilerPlatform.XboxOneD3D12:
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleHS case ShaderCompilerPlatform.GameCoreXboxOne:
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleDS case ShaderCompilerPlatform.GameCoreScarlett:
|| programType == ShaderGpuProgramType.kShaderGpuProgramConsoleGS; case ShaderCompilerPlatform.PS5:
case ShaderCompilerPlatform.kShaderCompPlatformD3D11: return programType == ShaderGpuProgramType.ConsoleVS
return programType == ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM40 || programType == ShaderGpuProgramType.ConsoleFS
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM50 || programType == ShaderGpuProgramType.ConsoleHS
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM40 || programType == ShaderGpuProgramType.ConsoleDS
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM50 || programType == ShaderGpuProgramType.ConsoleGS;
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM40 case ShaderCompilerPlatform.PS5NGGC:
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM50 return programType == ShaderGpuProgramType.PS5NGGC;
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11HullSM50 case ShaderCompilerPlatform.D3D11:
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX11DomainSM50; return programType == ShaderGpuProgramType.DX11VertexSM40
case ShaderCompilerPlatform.kShaderCompPlatformGLES20: || programType == ShaderGpuProgramType.DX11VertexSM50
return programType == ShaderGpuProgramType.kShaderGpuProgramGLES; || programType == ShaderGpuProgramType.DX11PixelSM40
case ShaderCompilerPlatform.kShaderCompPlatformNaCl: //Obsolete || programType == ShaderGpuProgramType.DX11PixelSM50
|| programType == ShaderGpuProgramType.DX11GeometrySM40
|| programType == ShaderGpuProgramType.DX11GeometrySM50
|| programType == ShaderGpuProgramType.DX11HullSM50
|| programType == ShaderGpuProgramType.DX11DomainSM50;
case ShaderCompilerPlatform.GLES20:
return programType == ShaderGpuProgramType.GLES;
case ShaderCompilerPlatform.NaCl: //Obsolete
throw new NotSupportedException(); throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformFlash: //Obsolete case ShaderCompilerPlatform.Flash: //Obsolete
throw new NotSupportedException(); throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformD3D11_9x: case ShaderCompilerPlatform.D3D11_9x:
return programType == ShaderGpuProgramType.kShaderGpuProgramDX10Level9Vertex return programType == ShaderGpuProgramType.DX10Level9Vertex
|| programType == ShaderGpuProgramType.kShaderGpuProgramDX10Level9Pixel; || programType == ShaderGpuProgramType.DX10Level9Pixel;
case ShaderCompilerPlatform.kShaderCompPlatformGLES3Plus: case ShaderCompilerPlatform.GLES3Plus:
return programType == ShaderGpuProgramType.kShaderGpuProgramGLES31AEP return programType == ShaderGpuProgramType.GLES31AEP
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLES31 || programType == ShaderGpuProgramType.GLES31
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLES3; || programType == ShaderGpuProgramType.GLES3;
case ShaderCompilerPlatform.kShaderCompPlatformPSP2: case ShaderCompilerPlatform.PSM: //Unknown
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(); throw new NotSupportedException();
case ShaderCompilerPlatform.kShaderCompPlatformMetal: case ShaderCompilerPlatform.Metal:
return programType == ShaderGpuProgramType.kShaderGpuProgramMetalVS return programType == ShaderGpuProgramType.MetalVS
|| programType == ShaderGpuProgramType.kShaderGpuProgramMetalFS; || programType == ShaderGpuProgramType.MetalFS;
case ShaderCompilerPlatform.kShaderCompPlatformOpenGLCore: case ShaderCompilerPlatform.OpenGLCore:
return programType == ShaderGpuProgramType.kShaderGpuProgramGLCore32 return programType == ShaderGpuProgramType.GLCore32
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLCore41 || programType == ShaderGpuProgramType.GLCore41
|| programType == ShaderGpuProgramType.kShaderGpuProgramGLCore43; || programType == ShaderGpuProgramType.GLCore43;
case ShaderCompilerPlatform.kShaderCompPlatformN3DS: case ShaderCompilerPlatform.Vulkan:
return programType == ShaderGpuProgramType.kShaderGpuProgramConsoleVS return programType == ShaderGpuProgramType.SPIRV;
|| 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: default:
throw new NotSupportedException(); throw new NotSupportedException();
} }
@@ -531,48 +803,56 @@ namespace AssetStudio
{ {
switch (platform) switch (platform)
{ {
case ShaderCompilerPlatform.kShaderCompPlatformGL: case ShaderCompilerPlatform.GL:
return "openGL"; return "openGL";
case ShaderCompilerPlatform.kShaderCompPlatformD3D9: case ShaderCompilerPlatform.D3D9:
return "d3d9"; return "d3d9";
case ShaderCompilerPlatform.kShaderCompPlatformXbox360: case ShaderCompilerPlatform.Xbox360:
return "xbox360"; return "xbox360";
case ShaderCompilerPlatform.kShaderCompPlatformPS3: case ShaderCompilerPlatform.PS3:
return "ps3"; return "ps3";
case ShaderCompilerPlatform.kShaderCompPlatformD3D11: case ShaderCompilerPlatform.D3D11:
return "d3d11"; return "d3d11";
case ShaderCompilerPlatform.kShaderCompPlatformGLES20: case ShaderCompilerPlatform.GLES20:
return "gles"; return "gles";
case ShaderCompilerPlatform.kShaderCompPlatformNaCl: case ShaderCompilerPlatform.NaCl:
return "glesdesktop"; return "glesdesktop";
case ShaderCompilerPlatform.kShaderCompPlatformFlash: case ShaderCompilerPlatform.Flash:
return "flash"; return "flash";
case ShaderCompilerPlatform.kShaderCompPlatformD3D11_9x: case ShaderCompilerPlatform.D3D11_9x:
return "d3d11_9x"; return "d3d11_9x";
case ShaderCompilerPlatform.kShaderCompPlatformGLES3Plus: case ShaderCompilerPlatform.GLES3Plus:
return "gles3"; return "gles3";
case ShaderCompilerPlatform.kShaderCompPlatformPSP2: case ShaderCompilerPlatform.PSP2:
return "psp2"; return "psp2";
case ShaderCompilerPlatform.kShaderCompPlatformPS4: case ShaderCompilerPlatform.PS4:
return "ps4"; return "ps4";
case ShaderCompilerPlatform.kShaderCompPlatformXboxOne: case ShaderCompilerPlatform.XboxOne:
return "xboxone"; return "xboxone";
case ShaderCompilerPlatform.kShaderCompPlatformPSM: case ShaderCompilerPlatform.PSM:
return "psm"; return "psm";
case ShaderCompilerPlatform.kShaderCompPlatformMetal: case ShaderCompilerPlatform.Metal:
return "metal"; return "metal";
case ShaderCompilerPlatform.kShaderCompPlatformOpenGLCore: case ShaderCompilerPlatform.OpenGLCore:
return "glcore"; return "glcore";
case ShaderCompilerPlatform.kShaderCompPlatformN3DS: case ShaderCompilerPlatform.N3DS:
return "n3ds"; return "n3ds";
case ShaderCompilerPlatform.kShaderCompPlatformWiiU: case ShaderCompilerPlatform.WiiU:
return "wiiu"; return "wiiu";
case ShaderCompilerPlatform.kShaderCompPlatformVulkan: case ShaderCompilerPlatform.Vulkan:
return "vulkan"; return "vulkan";
case ShaderCompilerPlatform.kShaderCompPlatformSwitch: case ShaderCompilerPlatform.Switch:
return "switch"; return "switch";
case ShaderCompilerPlatform.kShaderCompPlatformXboxOneD3D12: case ShaderCompilerPlatform.XboxOneD3D12:
return "xboxone_d3d12"; return "xboxone_d3d12";
case ShaderCompilerPlatform.GameCoreXboxOne:
return "xboxone";
case ShaderCompilerPlatform.GameCoreScarlett:
return "xbox_scarlett";
case ShaderCompilerPlatform.PS5:
return "ps5";
case ShaderCompilerPlatform.PS5NGGC:
return "ps5_nggc";
default: default:
return "unknown"; return "unknown";
} }
@@ -585,29 +865,49 @@ namespace AssetStudio
"///////////////////////////////////////////\n"; "///////////////////////////////////////////\n";
} }
public class ShaderSubProgramEntry
{
public int Offset;
public int Length;
public int Segment;
public ShaderSubProgramEntry(BinaryReader reader, int[] version)
{
Offset = reader.ReadInt32();
Length = reader.ReadInt32();
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
Segment = reader.ReadInt32();
}
}
}
public class ShaderProgram public class ShaderProgram
{ {
public ShaderSubProgramEntry[] entries;
public ShaderSubProgram[] m_SubPrograms; public ShaderSubProgram[] m_SubPrograms;
public ShaderProgram(BinaryReader reader, int[] version) public ShaderProgram(BinaryReader reader, int[] version)
{ {
var subProgramsCapacity = reader.ReadInt32(); var subProgramsCapacity = reader.ReadInt32();
m_SubPrograms = new ShaderSubProgram[subProgramsCapacity]; entries = new ShaderSubProgramEntry[subProgramsCapacity];
int entrySize;
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
entrySize = 12;
}
else
{
entrySize = 8;
}
for (int i = 0; i < subProgramsCapacity; i++) for (int i = 0; i < subProgramsCapacity; i++)
{ {
reader.BaseStream.Position = 4 + i * entrySize; entries[i] = new ShaderSubProgramEntry(reader, version);
var offset = reader.ReadInt32(); }
reader.BaseStream.Position = offset; m_SubPrograms = new ShaderSubProgram[subProgramsCapacity];
m_SubPrograms[i] = new ShaderSubProgram(reader); }
public void Read(BinaryReader reader, int segment)
{
for (int i = 0; i < entries.Length; i++)
{
var entry = entries[i];
if (entry.Segment == segment)
{
reader.BaseStream.Position = entry.Offset;
m_SubPrograms[i] = new ShaderSubProgram(reader);
}
} }
} }
@@ -640,7 +940,8 @@ namespace AssetStudio
//201609010 - Unity 5.6, 2017.1 & 2017.2 //201609010 - Unity 5.6, 2017.1 & 2017.2
//201708220 - Unity 2017.3, Unity 2017.4 & Unity 2018.1 //201708220 - Unity 2017.3, Unity 2017.4 & Unity 2018.1
//201802150 - Unity 2018.2 & Unity 2018.3 //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_Version = reader.ReadInt32();
m_ProgramType = (ShaderGpuProgramType)reader.ReadInt32(); m_ProgramType = (ShaderGpuProgramType)reader.ReadInt32();
reader.BaseStream.Position += 12; reader.BaseStream.Position += 12;
@@ -654,7 +955,7 @@ namespace AssetStudio
{ {
m_Keywords[i] = reader.ReadAlignedString(); m_Keywords[i] = reader.ReadAlignedString();
} }
if (m_Version >= 201806140) if (m_Version >= 201806140 && m_Version < 202012090)
{ {
var m_LocalKeywordsSize = reader.ReadInt32(); var m_LocalKeywordsSize = reader.ReadInt32();
m_LocalKeywords = new string[m_LocalKeywordsSize]; m_LocalKeywords = new string[m_LocalKeywordsSize];
@@ -696,36 +997,36 @@ namespace AssetStudio
{ {
switch (m_ProgramType) switch (m_ProgramType)
{ {
case ShaderGpuProgramType.kShaderGpuProgramGLLegacy: case ShaderGpuProgramType.GLLegacy:
case ShaderGpuProgramType.kShaderGpuProgramGLES31AEP: case ShaderGpuProgramType.GLES31AEP:
case ShaderGpuProgramType.kShaderGpuProgramGLES31: case ShaderGpuProgramType.GLES31:
case ShaderGpuProgramType.kShaderGpuProgramGLES3: case ShaderGpuProgramType.GLES3:
case ShaderGpuProgramType.kShaderGpuProgramGLES: case ShaderGpuProgramType.GLES:
case ShaderGpuProgramType.kShaderGpuProgramGLCore32: case ShaderGpuProgramType.GLCore32:
case ShaderGpuProgramType.kShaderGpuProgramGLCore41: case ShaderGpuProgramType.GLCore41:
case ShaderGpuProgramType.kShaderGpuProgramGLCore43: case ShaderGpuProgramType.GLCore43:
sb.Append(Encoding.UTF8.GetString(m_ProgramCode)); sb.Append(Encoding.UTF8.GetString(m_ProgramCode));
break; break;
case ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM20: case ShaderGpuProgramType.DX9VertexSM20:
case ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM30: case ShaderGpuProgramType.DX9VertexSM30:
case ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM20: case ShaderGpuProgramType.DX9PixelSM20:
case ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM30: case ShaderGpuProgramType.DX9PixelSM30:
{ {
/*var shaderBytecode = new ShaderBytecode(m_ProgramCode); /*var shaderBytecode = new ShaderBytecode(m_ProgramCode);
sb.Append(shaderBytecode.Disassemble());*/ sb.Append(shaderBytecode.Disassemble());*/
sb.Append("// shader disassembly not supported on DXBC"); sb.Append("// shader disassembly not supported on DXBC");
break; break;
} }
case ShaderGpuProgramType.kShaderGpuProgramDX10Level9Vertex: case ShaderGpuProgramType.DX10Level9Vertex:
case ShaderGpuProgramType.kShaderGpuProgramDX10Level9Pixel: case ShaderGpuProgramType.DX10Level9Pixel:
case ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM40: case ShaderGpuProgramType.DX11VertexSM40:
case ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM50: case ShaderGpuProgramType.DX11VertexSM50:
case ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM40: case ShaderGpuProgramType.DX11PixelSM40:
case ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM50: case ShaderGpuProgramType.DX11PixelSM50:
case ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM40: case ShaderGpuProgramType.DX11GeometrySM40:
case ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM50: case ShaderGpuProgramType.DX11GeometrySM50:
case ShaderGpuProgramType.kShaderGpuProgramDX11HullSM50: case ShaderGpuProgramType.DX11HullSM50:
case ShaderGpuProgramType.kShaderGpuProgramDX11DomainSM50: case ShaderGpuProgramType.DX11DomainSM50:
{ {
/*int start = 6; /*int start = 6;
if (m_Version == 201509030) // 5.3 if (m_Version == 201509030) // 5.3
@@ -739,8 +1040,8 @@ namespace AssetStudio
sb.Append("// shader disassembly not supported on DXBC"); sb.Append("// shader disassembly not supported on DXBC");
break; break;
} }
case ShaderGpuProgramType.kShaderGpuProgramMetalVS: case ShaderGpuProgramType.MetalVS:
case ShaderGpuProgramType.kShaderGpuProgramMetalFS: case ShaderGpuProgramType.MetalFS:
using (var reader = new BinaryReader(new MemoryStream(m_ProgramCode))) using (var reader = new BinaryReader(new MemoryStream(m_ProgramCode)))
{ {
var fourCC = reader.ReadUInt32(); var fourCC = reader.ReadUInt32();
@@ -754,7 +1055,7 @@ namespace AssetStudio
sb.Append(Encoding.UTF8.GetString(buff)); sb.Append(Encoding.UTF8.GetString(buff));
} }
break; break;
case ShaderGpuProgramType.kShaderGpuProgramSPIRV: case ShaderGpuProgramType.SPIRV:
try try
{ {
sb.Append(SpirVShaderConverter.Convert(m_ProgramCode)); sb.Append(SpirVShaderConverter.Convert(m_ProgramCode));
@@ -764,11 +1065,11 @@ namespace AssetStudio
sb.Append($"// disassembly error {e.Message}\n"); sb.Append($"// disassembly error {e.Message}\n");
} }
break; break;
case ShaderGpuProgramType.kShaderGpuProgramConsoleVS: case ShaderGpuProgramType.ConsoleVS:
case ShaderGpuProgramType.kShaderGpuProgramConsoleFS: case ShaderGpuProgramType.ConsoleFS:
case ShaderGpuProgramType.kShaderGpuProgramConsoleHS: case ShaderGpuProgramType.ConsoleHS:
case ShaderGpuProgramType.kShaderGpuProgramConsoleDS: case ShaderGpuProgramType.ConsoleDS:
case ShaderGpuProgramType.kShaderGpuProgramConsoleGS: case ShaderGpuProgramType.ConsoleGS:
sb.Append(Encoding.UTF8.GetString(m_ProgramCode)); sb.Append(Encoding.UTF8.GetString(m_ProgramCode));
break; break;
default: default:
+55 -67
View File
@@ -1,117 +1,105 @@
using System.Collections.Generic; using SixLabors.ImageSharp;
using System.Drawing; using SixLabors.ImageSharp.Drawing;
using System.Drawing.Drawing2D; using SixLabors.ImageSharp.Drawing.Processing;
using System.Drawing.Imaging; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Numerics;
namespace AssetStudio namespace AssetStudio
{ {
public static class SpriteHelper public static class SpriteHelper
{ {
public static Bitmap GetImage(this Sprite m_Sprite) public static Image<Bgra32> GetImage(this Sprite m_Sprite)
{ {
if (m_Sprite.m_SpriteAtlas != null && m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlas)) if (m_Sprite.m_SpriteAtlas != null && m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlas))
{ {
if (m_SpriteAtlas.m_RenderDataMap.TryGetValue(m_Sprite.m_RenderDataKey, out var spriteAtlasData) && spriteAtlasData.texture.TryGet(out var m_Texture2D)) if (m_SpriteAtlas.m_RenderDataMap.TryGetValue(m_Sprite.m_RenderDataKey, out var spriteAtlasData) && spriteAtlasData.texture.TryGet(out var m_Texture2D))
{ {
return CutImage(m_Texture2D, m_Sprite, spriteAtlasData.textureRect, spriteAtlasData.textureRectOffset, spriteAtlasData.settingsRaw); return CutImage(m_Sprite, m_Texture2D, spriteAtlasData.textureRect, spriteAtlasData.textureRectOffset, spriteAtlasData.downscaleMultiplier, spriteAtlasData.settingsRaw);
} }
} }
else else
{ {
if (m_Sprite.m_RD.texture.TryGet(out var m_Texture2D)) if (m_Sprite.m_RD.texture.TryGet(out var m_Texture2D))
{ {
return CutImage(m_Texture2D, m_Sprite, m_Sprite.m_RD.textureRect, m_Sprite.m_RD.textureRectOffset, m_Sprite.m_RD.settingsRaw); return CutImage(m_Sprite, m_Texture2D, m_Sprite.m_RD.textureRect, m_Sprite.m_RD.textureRectOffset, m_Sprite.m_RD.downscaleMultiplier, m_Sprite.m_RD.settingsRaw);
} }
} }
return null; return null;
} }
private static Bitmap CutImage(Texture2D m_Texture2D, Sprite m_Sprite, Rectf textureRect, Vector2 textureRectOffset, SpriteSettings settingsRaw) private static Image<Bgra32> CutImage(Sprite m_Sprite, Texture2D m_Texture2D, Rectf textureRect, Vector2 textureRectOffset, float downscaleMultiplier, SpriteSettings settingsRaw)
{ {
var originalImage = m_Texture2D.ConvertToBitmap(false); var originalImage = m_Texture2D.ConvertToImage(false);
if (originalImage != null) if (originalImage != null)
{ {
using (originalImage) using (originalImage)
{ {
//var spriteImage = originalImage.Clone(textureRect, PixelFormat.Format32bppArgb); if (downscaleMultiplier > 0f && downscaleMultiplier != 1f)
var rectf = new RectangleF(textureRect.x, textureRect.y, textureRect.width, textureRect.height);
var rect = Rectangle.Round(rectf);
if (rect.Width == 0)
{ {
rect.Width = 1; var width = (int)(m_Texture2D.m_Width / downscaleMultiplier);
} var height = (int)(m_Texture2D.m_Height / downscaleMultiplier);
if (rect.Height == 0) originalImage.Mutate(x => x.Resize(width, height));
{
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, originalImage.Width);
rectBottom = Math.Min(rectBottom, originalImage.Height);
var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY);
var spriteImage = originalImage.Clone(x => x.Crop(rect));
if (settingsRaw.packed == 1) if (settingsRaw.packed == 1)
{ {
//RotateAndFlip //RotateAndFlip
switch (settingsRaw.packingRotation) switch (settingsRaw.packingRotation)
{ {
case SpritePackingRotation.kSPRFlipHorizontal: case SpritePackingRotation.FlipHorizontal:
spriteImage.RotateFlip(RotateFlipType.RotateNoneFlipX); spriteImage.Mutate(x => x.Flip(FlipMode.Horizontal));
break; break;
case SpritePackingRotation.kSPRFlipVertical: case SpritePackingRotation.FlipVertical:
spriteImage.RotateFlip(RotateFlipType.RotateNoneFlipY); spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
break; break;
case SpritePackingRotation.kSPRRotate180: case SpritePackingRotation.Rotate180:
spriteImage.RotateFlip(RotateFlipType.Rotate180FlipNone); spriteImage.Mutate(x => x.Rotate(180));
break; break;
case SpritePackingRotation.kSPRRotate90: case SpritePackingRotation.Rotate90:
spriteImage.RotateFlip(RotateFlipType.Rotate270FlipNone); spriteImage.Mutate(x => x.Rotate(270));
break; break;
} }
} }
//Tight //Tight
if (settingsRaw.packingMode == SpritePackingMode.kSPMTight) if (settingsRaw.packingMode == SpritePackingMode.Tight)
{ {
try try
{ {
var triangles = GetTriangles(m_Sprite.m_RD); var triangles = GetTriangles(m_Sprite.m_RD);
var points = triangles.Select(x => x.Select(y => new PointF(y.X, y.Y)).ToArray()); var polygons = triangles.Select(x => new Polygon(new LinearLineSegment(x.Select(y => new PointF(y.X, y.Y)).ToArray()))).ToArray();
using (var path = new GraphicsPath()) IPathCollection path = new PathCollection(polygons);
var matrix = Matrix3x2.CreateScale(m_Sprite.m_PixelsToUnits);
matrix *= Matrix3x2.CreateTranslation(m_Sprite.m_Rect.width * m_Sprite.m_Pivot.X - textureRectOffset.X, m_Sprite.m_Rect.height * m_Sprite.m_Pivot.Y - textureRectOffset.Y);
path = path.Transform(matrix);
var graphicsOptions = new GraphicsOptions
{ {
foreach (var p in points) Antialias = false,
{ AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
path.AddPolygon(p); };
} var options = new DrawingOptions
using (var matr = new Matrix()) {
{ GraphicsOptions = graphicsOptions
var version = m_Sprite.version; };
if (version[0] < 5 using (var mask = new Image<Bgra32>(rect.Width, rect.Height, SixLabors.ImageSharp.Color.Black))
|| (version[0] == 5 && version[1] < 4) {
|| (version[0] == 5 && version[1] == 4 && version[2] <= 1)) //5.4.1p3 down mask.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, path));
{ var bursh = new ImageBrush(mask);
matr.Translate(m_Sprite.m_Rect.width * 0.5f - textureRectOffset.X, m_Sprite.m_Rect.height * 0.5f - textureRectOffset.Y); spriteImage.Mutate(x => x.Fill(graphicsOptions, bursh));
} spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
else return spriteImage;
{
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;
}
}
}
} }
} }
catch catch
@@ -121,7 +109,7 @@ namespace AssetStudio
} }
//Rectangle //Rectangle
spriteImage.RotateFlip(RotateFlipType.RotateNoneFlipY); spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
return spriteImage; return spriteImage;
} }
} }
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+36 -3
View File
@@ -1,13 +1,46 @@
using System.Drawing; using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System.IO;
namespace AssetStudio namespace AssetStudio
{ {
public static class Texture2DExtensions public static class Texture2DExtensions
{ {
public static Bitmap ConvertToBitmap(this Texture2D m_Texture2D, bool flip) public static Image<Bgra32> ConvertToImage(this Texture2D m_Texture2D, bool flip)
{ {
var converter = new Texture2DConverter(m_Texture2D); var converter = new Texture2DConverter(m_Texture2D);
return converter.ConvertToBitmap(flip); var buff = BigArrayPool<byte>.Shared.Rent(m_Texture2D.m_Width * m_Texture2D.m_Height * 4);
try
{
if (converter.DecodeTexture2D(buff))
{
var image = Image.LoadPixelData<Bgra32>(buff, m_Texture2D.m_Width, m_Texture2D.m_Height);
if (flip)
{
image.Mutate(x => x.Flip(FlipMode.Vertical));
}
return image;
}
return null;
}
finally
{
BigArrayPool<byte>.Shared.Return(buff);
}
}
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;
} }
} }
} }
+42 -61
View File
@@ -26,22 +26,22 @@ namespace AssetStudio
{ {
var nodes = new List<TypeTreeNode>(); var nodes = new List<TypeTreeNode>();
Stack<TypeReference> baseTypes = new Stack<TypeReference>(); var baseTypes = new Stack<TypeReference>();
TypeReference baseType = TypeDef.BaseType; var lastBaseType = TypeDef.BaseType;
while (!UnitySerializationLogic.IsNonSerialized(baseType)) while (!UnitySerializationLogic.IsNonSerialized(lastBaseType))
{ {
GenericInstanceType genericInstanceType = baseType as GenericInstanceType; var genericInstanceType = lastBaseType as GenericInstanceType;
if (genericInstanceType != null) if (genericInstanceType != null)
{ {
TypeResolver.Add(genericInstanceType); TypeResolver.Add(genericInstanceType);
} }
baseTypes.Push(baseType); baseTypes.Push(lastBaseType);
baseType = baseType.Resolve().BaseType; lastBaseType = lastBaseType.Resolve().BaseType;
} }
while (baseTypes.Count > 0) while (baseTypes.Count > 0)
{ {
TypeReference typeReference = baseTypes.Pop(); var typeReference = baseTypes.Pop();
TypeDefinition typeDefinition = typeReference.Resolve(); var typeDefinition = typeReference.Resolve();
foreach (var fieldDefinition in typeDefinition.Fields.Where(WillUnitySerialize)) foreach (var fieldDefinition in typeDefinition.Fields.Where(WillUnitySerialize))
{ {
if (!IsHiddenByParentClass(baseTypes, fieldDefinition, TypeDef)) if (!IsHiddenByParentClass(baseTypes, fieldDefinition, TypeDef))
@@ -50,15 +50,15 @@ namespace AssetStudio
} }
} }
var genericInstanceType2 = typeReference as GenericInstanceType; var genericInstanceType = typeReference as GenericInstanceType;
if (genericInstanceType2 != null) 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; return nodes;
@@ -66,75 +66,60 @@ namespace AssetStudio
private bool WillUnitySerialize(FieldDefinition fieldDefinition) private bool WillUnitySerialize(FieldDefinition fieldDefinition)
{ {
bool result;
try try
{ {
TypeReference typeReference = TypeResolver.Resolve(fieldDefinition.FieldType); var resolvedFieldType = TypeResolver.Resolve(fieldDefinition.FieldType);
if (UnitySerializationLogic.ShouldNotTryToResolve(typeReference)) 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) catch (Exception ex)
{ {
throw new Exception(string.Format("Exception while processing {0} {1}, error {2}", fieldDefinition.FieldType.FullName, fieldDefinition.FullName, ex.Message)); 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) 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() private IEnumerable<FieldDefinition> FilteredFields()
{ {
foreach (var f in TypeDef.Fields.Where(WillUnitySerialize)) return TypeDef.Fields.Where(WillUnitySerialize).Where(f =>
{ UnitySerializationLogic.IsSupportedCollection(f.FieldType) ||
if (UnitySerializationLogic.IsSupportedCollection(f.FieldType) || !f.FieldType.IsGenericInstance || UnitySerializationLogic.ShouldImplementIDeserializable(f.FieldType.Resolve())) !f.FieldType.IsGenericInstance ||
{ UnitySerializationLogic.ShouldImplementIDeserializable(f.FieldType.Resolve()));
yield return f;
}
}
yield break;
} }
private FieldReference ResolveGenericFieldReference(FieldReference fieldRef) 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); return TypeDef.Module.ImportReference(field);
} }
private TypeReference ResolveDeclaringType(TypeReference declaringType) private TypeReference ResolveDeclaringType(TypeReference declaringType)
{ {
TypeDefinition typeDefinition = declaringType.Resolve(); var typeDefinition = declaringType.Resolve();
TypeReference result;
if (typeDefinition == null || !typeDefinition.HasGenericParameters) 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); genericInstanceType.GenericArguments.Add(genericParameter);
foreach (GenericParameter item in typeDefinition.GenericParameters)
{
genericInstanceType.GenericArguments.Add(item);
}
result = TypeResolver.Resolve(genericInstanceType);
} }
return result; return TypeResolver.Resolve(genericInstanceType);
} }
private List<TypeTreeNode> ProcessingFieldRef(FieldReference fieldDef) private List<TypeTreeNode> ProcessingFieldRef(FieldReference fieldDef)
@@ -155,7 +140,6 @@ namespace AssetStudio
private static bool RequiresAlignment(TypeReference typeRef) private static bool RequiresAlignment(TypeReference typeRef)
{ {
bool result;
switch (typeRef.MetadataType) switch (typeRef.MetadataType)
{ {
case MetadataType.Boolean: case MetadataType.Boolean:
@@ -164,13 +148,10 @@ namespace AssetStudio
case MetadataType.Byte: case MetadataType.Byte:
case MetadataType.Int16: case MetadataType.Int16:
case MetadataType.UInt16: case MetadataType.UInt16:
result = true; return true;
break;
default: default:
result = (UnitySerializationLogic.IsSupportedCollection(typeRef) && RequiresAlignment(CecilUtils.ElementTypeOfCollection(typeRef))); return UnitySerializationLogic.IsSupportedCollection(typeRef) && RequiresAlignment(CecilUtils.ElementTypeOfCollection(typeRef));
break;
} }
return result;
} }
private static bool IsSystemString(TypeReference typeRef) private static bool IsSystemString(TypeReference typeRef)
@@ -272,28 +253,28 @@ namespace AssetStudio
switch (typeRef.FullName) switch (typeRef.FullName)
{ {
case "UnityEngine.AnimationCurve": case "UnityEngine.AnimationCurve":
Helper.AddAnimationCurve(nodes, name, indent + 1); Helper.AddAnimationCurve(nodes, name, indent);
break; break;
case "UnityEngine.Gradient": case "UnityEngine.Gradient":
Helper.AddGradient(nodes, name, indent + 1); Helper.AddGradient(nodes, name, indent);
break; break;
case "UnityEngine.GUIStyle": case "UnityEngine.GUIStyle":
Helper.AddGUIStyle(nodes, name, indent + 1); Helper.AddGUIStyle(nodes, name, indent);
break; break;
case "UnityEngine.RectOffset": case "UnityEngine.RectOffset":
Helper.AddRectOffset(nodes, name, indent + 1); Helper.AddRectOffset(nodes, name, indent);
break; break;
case "UnityEngine.Color32": case "UnityEngine.Color32":
Helper.AddColor32(nodes, name, indent + 1); Helper.AddColor32(nodes, name, indent);
break; break;
case "UnityEngine.Matrix4x4": case "UnityEngine.Matrix4x4":
Helper.AddMatrix4x4(nodes, name, indent + 1); Helper.AddMatrix4x4(nodes, name, indent);
break; break;
case "UnityEngine.Rendering.SphericalHarmonicsL2": case "UnityEngine.Rendering.SphericalHarmonicsL2":
Helper.AddSphericalHarmonicsL2(nodes, name, indent + 1); Helper.AddSphericalHarmonicsL2(nodes, name, indent);
break; break;
case "UnityEngine.PropertyName": case "UnityEngine.PropertyName":
Helper.AddPropertyName(nodes, name, indent + 1); Helper.AddPropertyName(nodes, name, indent);
break; break;
} }
} }
@@ -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;
}
}
}

Some files were not shown because too many files have changed in this diff Show More