parent
b93866d196
commit
8ea998b81f
|
@ -3,11 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.27130.2024
|
VisualStudioVersion = 15.0.27130.2024
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBX", "AssetStudioFBX\AssetStudioFBX.vcxproj", "{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBX", "AssetStudioFBX\AssetStudioFBX.vcxproj", "{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioTools", "AssetStudioTools\AssetStudioTools.csproj", "{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{AF56B63C-1764-41B7-9E60-8D485422AC3B}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -33,14 +35,22 @@ Global
|
||||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x64.Build.0 = Release|x64
|
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x64.Build.0 = Release|x64
|
||||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x86.ActiveCfg = Release|Win32
|
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x86.Build.0 = Release|Win32
|
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x86.Build.0 = Release|Win32
|
||||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.ActiveCfg = Debug|Any CPU
|
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.Build.0 = Debug|Any CPU
|
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.Build.0 = Debug|x64
|
||||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.ActiveCfg = Debug|Any CPU
|
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.Build.0 = Debug|Any CPU
|
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.Build.0 = Debug|x86
|
||||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.ActiveCfg = Release|Any CPU
|
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.ActiveCfg = Release|x64
|
||||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.Build.0 = Release|Any CPU
|
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.Build.0 = Release|x64
|
||||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.ActiveCfg = Release|Any CPU
|
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.ActiveCfg = Release|x86
|
||||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.Build.0 = Release|Any CPU
|
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.Build.0 = Release|x86
|
||||||
|
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace SevenZip
|
namespace SevenZip
|
||||||
{
|
{
|
||||||
class CRC
|
public class CRC
|
||||||
{
|
{
|
||||||
public static readonly uint[] Table;
|
public static readonly uint[] Table;
|
||||||
|
|
||||||
|
|
|
@ -1,163 +1,72 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<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>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProductVersion>8.0.30703</ProductVersion>
|
<ProjectGuid>{AF56B63C-1764-41B7-9E60-8D485422AC3B}</ProjectGuid>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<OutputType>Library</OutputType>
|
||||||
<ProjectGuid>{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}</ProjectGuid>
|
|
||||||
<OutputType>WinExe</OutputType>
|
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>AssetStudio</RootNamespace>
|
<RootNamespace>AssetStudio</RootNamespace>
|
||||||
<AssemblyName>AssetStudio</AssemblyName>
|
<AssemblyName>AssetStudio</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
<TargetFrameworkProfile>
|
|
||||||
</TargetFrameworkProfile>
|
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
<Deterministic>true</Deterministic>
|
||||||
<PublishUrl>publish\</PublishUrl>
|
|
||||||
<Install>true</Install>
|
|
||||||
<InstallFrom>Disk</InstallFrom>
|
|
||||||
<UpdateEnabled>false</UpdateEnabled>
|
|
||||||
<UpdateMode>Foreground</UpdateMode>
|
|
||||||
<UpdateInterval>7</UpdateInterval>
|
|
||||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
|
||||||
<UpdatePeriodically>false</UpdatePeriodically>
|
|
||||||
<UpdateRequired>false</UpdateRequired>
|
|
||||||
<MapFileExtensions>true</MapFileExtensions>
|
|
||||||
<ApplicationRevision>0</ApplicationRevision>
|
|
||||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
|
||||||
<UseApplicationTrust>false</UseApplicationTrust>
|
|
||||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<Optimize>false</Optimize>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
|
||||||
<OutputPath>bin\x64\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<OutputPath>bin\x86\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="dnlib">
|
|
||||||
<HintPath>Libraries\dnlib.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="OpenTK">
|
|
||||||
<HintPath>Libraries\OpenTK.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="OpenTK.GLControl">
|
|
||||||
<HintPath>Libraries\OpenTK.GLControl.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="SharpDX">
|
|
||||||
<HintPath>Libraries\SharpDX.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="SharpDX.D3DCompiler">
|
|
||||||
<HintPath>Libraries\SharpDX.D3DCompiler.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="SharpDX.Mathematics">
|
<Reference Include="SharpDX.Mathematics">
|
||||||
<HintPath>Libraries\SharpDX.Mathematics.dll</HintPath>
|
<HintPath>Libraries\SharpDX.Mathematics.dll</HintPath>
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Half">
|
<Reference Include="System.Half">
|
||||||
<HintPath>Libraries\System.Half.dll</HintPath>
|
<HintPath>Libraries\System.Half.dll</HintPath>
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Web.Extensions" />
|
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Drawing" />
|
|
||||||
<Reference Include="System.Windows.Forms" />
|
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="7zip\Common\CommandLineParser.cs">
|
<Compile Include="7zip\Common\CommandLineParser.cs" />
|
||||||
<SubType>Code</SubType>
|
<Compile Include="7zip\Common\CRC.cs" />
|
||||||
</Compile>
|
<Compile Include="7zip\Common\InBuffer.cs" />
|
||||||
<Compile Include="7zip\Common\CRC.cs">
|
<Compile Include="7zip\Common\OutBuffer.cs" />
|
||||||
<SubType>Code</SubType>
|
<Compile Include="7zip\Compress\LZMA\LzmaBase.cs" />
|
||||||
</Compile>
|
<Compile Include="7zip\Compress\LZMA\LzmaDecoder.cs" />
|
||||||
<Compile Include="7zip\Common\InBuffer.cs">
|
<Compile Include="7zip\Compress\LZMA\LzmaEncoder.cs" />
|
||||||
<SubType>Code</SubType>
|
<Compile Include="7zip\Compress\LZ\IMatchFinder.cs" />
|
||||||
</Compile>
|
<Compile Include="7zip\Compress\LZ\LzBinTree.cs" />
|
||||||
<Compile Include="7zip\Common\OutBuffer.cs">
|
<Compile Include="7zip\Compress\LZ\LzInWindow.cs" />
|
||||||
<SubType>Code</SubType>
|
<Compile Include="7zip\Compress\LZ\LzOutWindow.cs" />
|
||||||
</Compile>
|
<Compile Include="7zip\Compress\RangeCoder\RangeCoder.cs" />
|
||||||
<Compile Include="7zip\Compress\LZMA\LzmaBase.cs">
|
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBit.cs" />
|
||||||
<SubType>Code</SubType>
|
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBitTree.cs" />
|
||||||
</Compile>
|
<Compile Include="7zip\ICoder.cs" />
|
||||||
<Compile Include="7zip\Compress\LZMA\LzmaDecoder.cs">
|
<Compile Include="Utility\IImported.cs" />
|
||||||
<SubType>Code</SubType>
|
<Compile Include="SerializedFile.cs" />
|
||||||
</Compile>
|
<Compile Include="AssetsManager.cs" />
|
||||||
<Compile Include="7zip\Compress\LZMA\LzmaEncoder.cs">
|
<Compile Include="Extensions\BinaryReaderExtensions.cs" />
|
||||||
<SubType>Code</SubType>
|
<Compile Include="Extensions\BinaryWriterExtensions.cs" />
|
||||||
</Compile>
|
|
||||||
<Compile Include="7zip\Compress\LZ\IMatchFinder.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="7zip\Compress\LZ\LzBinTree.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="7zip\Compress\LZ\LzInWindow.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="7zip\Compress\LZ\LzOutWindow.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoder.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBit.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBitTree.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="7zip\ICoder.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Brotli\BitReader.cs" />
|
<Compile Include="Brotli\BitReader.cs" />
|
||||||
<Compile Include="Brotli\BrotliInputStream.cs" />
|
<Compile Include="Brotli\BrotliInputStream.cs" />
|
||||||
<Compile Include="Brotli\BrotliRuntimeException.cs" />
|
<Compile Include="Brotli\BrotliRuntimeException.cs" />
|
||||||
|
@ -173,170 +82,67 @@
|
||||||
<Compile Include="Brotli\Transform.cs" />
|
<Compile Include="Brotli\Transform.cs" />
|
||||||
<Compile Include="Brotli\Utils.cs" />
|
<Compile Include="Brotli\Utils.cs" />
|
||||||
<Compile Include="Brotli\WordTransformType.cs" />
|
<Compile Include="Brotli\WordTransformType.cs" />
|
||||||
<Compile Include="Classes\Behaviour.cs" />
|
<Compile Include="BuildTarget.cs" />
|
||||||
<Compile Include="Classes\Component.cs" />
|
<Compile Include="BuildType.cs" />
|
||||||
<Compile Include="Classes\EditorExtension.cs" />
|
<Compile Include="BundleFile.cs" />
|
||||||
<Compile Include="Classes\MonoScript.cs" />
|
|
||||||
<Compile Include="Classes\NamedObject.cs" />
|
|
||||||
<Compile Include="Classes\Object.cs" />
|
|
||||||
<Compile Include="StudioClasses\ObjectReader.cs" />
|
|
||||||
<Compile Include="StudioClasses\PPtr.cs" />
|
|
||||||
<Compile Include="Classes\Renderer.cs" />
|
|
||||||
<Compile Include="Classes\Texture.cs" />
|
|
||||||
<Compile Include="StudioClasses\AudioClipConverter.cs" />
|
|
||||||
<Compile Include="StudioClasses\CommonString.cs" />
|
|
||||||
<Compile Include="StudioClasses\FileIdentifier.cs" />
|
|
||||||
<Compile Include="StudioClasses\GameObjectTreeNode.cs" />
|
|
||||||
<Compile Include="StudioClasses\LocalSerializedObjectIdentifier.cs" />
|
|
||||||
<Compile Include="StudioClasses\ObjectInfo.cs" />
|
|
||||||
<Compile Include="StudioClasses\ScriptHelper.cs" />
|
|
||||||
<Compile Include="StudioClasses\SerializedFileHeader.cs" />
|
|
||||||
<Compile Include="StudioClasses\SerializedType.cs" />
|
|
||||||
<Compile Include="StudioClasses\SevenZipHelper.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Classes\Animation.cs" />
|
<Compile Include="Classes\Animation.cs" />
|
||||||
<Compile Include="Classes\AnimationClip.cs" />
|
<Compile Include="Classes\AnimationClip.cs" />
|
||||||
<Compile Include="Classes\Animator.cs" />
|
<Compile Include="Classes\Animator.cs" />
|
||||||
<Compile Include="Classes\AnimatorController.cs" />
|
<Compile Include="Classes\AnimatorController.cs" />
|
||||||
<Compile Include="Classes\AnimatorOverrideController.cs" />
|
<Compile Include="Classes\AnimatorOverrideController.cs" />
|
||||||
<Compile Include="Classes\Avatar.cs" />
|
|
||||||
<Compile Include="OpenFolderDialog.cs" />
|
|
||||||
<Compile Include="StudioClasses\BinaryReaderExtensions.cs" />
|
|
||||||
<Compile Include="StudioClasses\BinaryWriterExtensions.cs" />
|
|
||||||
<Compile Include="StudioClasses\BuildTarget.cs" />
|
|
||||||
<Compile Include="StudioClasses\ClassIDType.cs" />
|
|
||||||
<Compile Include="StudioClasses\ShaderConverter.cs" />
|
|
||||||
<Compile Include="StudioClasses\TypeTreeNode.cs" />
|
|
||||||
<Compile Include="StudioClasses\TypeTreeHelper.cs" />
|
|
||||||
<Compile Include="StudioClasses\ResourcesHelper.cs" />
|
|
||||||
<Compile Include="Classes\AssetBundle.cs" />
|
<Compile Include="Classes\AssetBundle.cs" />
|
||||||
<Compile Include="Classes\MovieTexture.cs" />
|
|
||||||
<Compile Include="Classes\Sprite.cs" />
|
|
||||||
<Compile Include="Classes\SpriteAtlas.cs" />
|
|
||||||
<Compile Include="Classes\VideoClip.cs" />
|
|
||||||
<Compile Include="StudioClasses\AssetItem.cs" />
|
|
||||||
<Compile Include="Classes\AudioClip.cs" />
|
<Compile Include="Classes\AudioClip.cs" />
|
||||||
|
<Compile Include="Classes\Avatar.cs" />
|
||||||
|
<Compile Include="Classes\Behaviour.cs" />
|
||||||
<Compile Include="Classes\BuildSettings.cs" />
|
<Compile Include="Classes\BuildSettings.cs" />
|
||||||
<Compile Include="StudioClasses\BundleFile.cs" />
|
<Compile Include="Classes\Component.cs" />
|
||||||
<Compile Include="StudioClasses\TypeTreeItem.cs" />
|
<Compile Include="Classes\EditorExtension.cs" />
|
||||||
<Compile Include="StudioClasses\SpriteHelper.cs" />
|
|
||||||
<Compile Include="StudioClasses\Exporter.cs" />
|
|
||||||
<Compile Include="StudioClasses\Importer.cs" />
|
|
||||||
<Compile Include="StudioClasses\StreamExtensions.cs" />
|
|
||||||
<Compile Include="StudioClasses\Studio.cs" />
|
|
||||||
<Compile Include="StudioClasses\EndianBinaryReader.cs" />
|
|
||||||
<Compile Include="ExportOptions.cs">
|
|
||||||
<SubType>Form</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="ExportOptions.Designer.cs">
|
|
||||||
<DependentUpon>ExportOptions.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<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="Classes\Font.cs" />
|
<Compile Include="Classes\Font.cs" />
|
||||||
<Compile Include="GOHierarchy.cs">
|
<Compile Include="Classes\GameObject.cs" />
|
||||||
<SubType>Component</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Lz4DecoderStream.cs" />
|
|
||||||
<Compile Include="Classes\Material.cs" />
|
<Compile Include="Classes\Material.cs" />
|
||||||
<Compile Include="Classes\Mesh.cs" />
|
<Compile Include="Classes\Mesh.cs" />
|
||||||
<Compile Include="Classes\GameObject.cs" />
|
<Compile Include="Classes\MeshFilter.cs" />
|
||||||
|
<Compile Include="Classes\MeshRenderer.cs" />
|
||||||
<Compile Include="Classes\MonoBehaviour.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\PlayerSettings.cs" />
|
||||||
<Compile Include="Classes\RectTransform.cs" />
|
<Compile Include="Classes\RectTransform.cs" />
|
||||||
<Compile Include="Classes\MeshRenderer.cs" />
|
<Compile Include="Classes\Renderer.cs" />
|
||||||
<Compile Include="Classes\Shader.cs" />
|
<Compile Include="Classes\Shader.cs" />
|
||||||
<Compile Include="Classes\SkinnedMeshRenderer.cs" />
|
<Compile Include="Classes\SkinnedMeshRenderer.cs" />
|
||||||
<Compile Include="Classes\MeshFilter.cs" />
|
<Compile Include="Classes\Sprite.cs" />
|
||||||
|
<Compile Include="Classes\SpriteAtlas.cs" />
|
||||||
<Compile Include="Classes\TextAsset.cs" />
|
<Compile Include="Classes\TextAsset.cs" />
|
||||||
|
<Compile Include="Classes\Texture.cs" />
|
||||||
<Compile Include="Classes\Texture2D.cs" />
|
<Compile Include="Classes\Texture2D.cs" />
|
||||||
<Compile Include="Classes\Transform.cs" />
|
<Compile Include="Classes\Transform.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Classes\VideoClip.cs" />
|
||||||
|
<Compile Include="ClassIDType.cs" />
|
||||||
|
<Compile Include="CommonString.cs" />
|
||||||
|
<Compile Include="EndianBinaryReader.cs" />
|
||||||
|
<Compile Include="FileIdentifier.cs" />
|
||||||
|
<Compile Include="Utility\ILogger.cs" />
|
||||||
|
<Compile Include="ImportHelper.cs" />
|
||||||
|
<Compile Include="Utility\IProgress.cs" />
|
||||||
|
<Compile Include="LocalSerializedObjectIdentifier.cs" />
|
||||||
|
<Compile Include="Utility\Logger.cs" />
|
||||||
|
<Compile Include="Lz4DecoderStream.cs" />
|
||||||
|
<Compile Include="ObjectInfo.cs" />
|
||||||
|
<Compile Include="ObjectReader.cs" />
|
||||||
|
<Compile Include="Classes\PPtr.cs" />
|
||||||
|
<Compile Include="Utility\Progress.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="StudioClasses\AssetsFile.cs" />
|
<Compile Include="ResourcesHelper.cs" />
|
||||||
<Compile Include="StudioClasses\ModelConverter.cs" />
|
<Compile Include="SerializedFileHeader.cs" />
|
||||||
<Compile Include="StudioClasses\Texture2DConverter.cs" />
|
<Compile Include="SerializedType.cs" />
|
||||||
<Compile Include="StudioClasses\WebFile.cs" />
|
<Compile Include="SevenZipHelper.cs" />
|
||||||
<Compile Include="AssetStudioForm.cs">
|
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||||
<SubType>Form</SubType>
|
<Compile Include="TypeTreeHelper.cs" />
|
||||||
</Compile>
|
<Compile Include="TypeTreeNode.cs" />
|
||||||
<Compile Include="AssetStudioForm.Designer.cs">
|
<Compile Include="WebFile.cs" />
|
||||||
<DependentUpon>AssetStudioForm.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="TreeViewExtensions.cs" />
|
|
||||||
<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>
|
|
||||||
<EmbeddedResource Include="AssetStudioForm.resx">
|
|
||||||
<DependentUpon>AssetStudioForm.cs</DependentUpon>
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<None Include="app.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>
|
|
||||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
|
|
||||||
<Visible>False</Visible>
|
|
||||||
<ProductName>Microsoft .NET Framework 4 Client Profile %28x86 and x64%29</ProductName>
|
|
||||||
<Install>true</Install>
|
|
||||||
</BootstrapperPackage>
|
|
||||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
|
||||||
<Visible>False</Visible>
|
|
||||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
|
||||||
<Install>false</Install>
|
|
||||||
</BootstrapperPackage>
|
|
||||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
|
|
||||||
<Visible>False</Visible>
|
|
||||||
<ProductName>Windows Installer 4.5</ProductName>
|
|
||||||
<Install>true</Install>
|
|
||||||
</BootstrapperPackage>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="Resources\preview.png" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\AssetStudioFBX\AssetStudioFBX.vcxproj">
|
|
||||||
<Project>{4f8ef5ef-732b-49cf-9eb3-b23e19ae6267}</Project>
|
|
||||||
<Name>AssetStudioFBX</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj">
|
|
||||||
<Project>{9131c403-7fe8-444d-9af5-5fe5df76ff24}</Project>
|
|
||||||
<Name>AssetStudioUtility</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="Resources\as.ico" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
|
||||||
<PostBuildEvent>xcopy /y "$(ProjectDir)Libraries" "$(TargetDir)"
|
|
||||||
xcopy /y "$(ProjectDir)Libraries\$(PlatformName)" "$(TargetDir)"</PostBuildEvent>
|
|
||||||
</PropertyGroup>
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
|
||||||
<Target Name="BeforeBuild">
|
|
||||||
</Target>
|
|
||||||
<Target Name="AfterBuild">
|
|
||||||
</Target>
|
|
||||||
-->
|
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,192 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using static AssetStudio.ImportHelper;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public class AssetsManager
|
||||||
|
{
|
||||||
|
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
|
||||||
|
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>();
|
||||||
|
internal Dictionary<string, EndianBinaryReader> resourceFileReaders = new Dictionary<string, EndianBinaryReader>();
|
||||||
|
|
||||||
|
private List<string> importFiles = new List<string>();
|
||||||
|
private HashSet<string> importFilesHash = new HashSet<string>();
|
||||||
|
private HashSet<string> assetsfileListHash = new HashSet<string>();
|
||||||
|
|
||||||
|
public void LoadFiles(string[] files)
|
||||||
|
{
|
||||||
|
var path = Path.GetDirectoryName(files[0]);
|
||||||
|
MergeSplitAssets(path);
|
||||||
|
var toReadFile = ProcessingSplitFiles(files.ToList());
|
||||||
|
Load(toReadFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadFolder(string path)
|
||||||
|
{
|
||||||
|
MergeSplitAssets(path, true);
|
||||||
|
var files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).ToList();
|
||||||
|
var toReadFile = ProcessingSplitFiles(files);
|
||||||
|
Load(toReadFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Load(string[] files)
|
||||||
|
{
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
importFiles.Add(file);
|
||||||
|
importFilesHash.Add(Path.GetFileName(file).ToUpper());
|
||||||
|
}
|
||||||
|
Progress.Reset();
|
||||||
|
//use a for loop because list size can change
|
||||||
|
for (var i = 0; i < importFiles.Count; i++)
|
||||||
|
{
|
||||||
|
LoadFile(importFiles[i]);
|
||||||
|
Progress.Report(i + 1, importFiles.Count);
|
||||||
|
}
|
||||||
|
importFiles.Clear();
|
||||||
|
importFilesHash.Clear();
|
||||||
|
assetsfileListHash.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadFile(string fullName)
|
||||||
|
{
|
||||||
|
switch (CheckFileType(fullName, out var reader))
|
||||||
|
{
|
||||||
|
case FileType.AssetsFile:
|
||||||
|
LoadAssetsFile(fullName, reader);
|
||||||
|
break;
|
||||||
|
case FileType.BundleFile:
|
||||||
|
LoadBundleFile(fullName, reader);
|
||||||
|
break;
|
||||||
|
case FileType.WebFile:
|
||||||
|
LoadWebFile(fullName, reader);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadAssetsFile(string fullName, EndianBinaryReader reader)
|
||||||
|
{
|
||||||
|
var fileName = Path.GetFileName(fullName);
|
||||||
|
if (!assetsfileListHash.Contains(fileName.ToUpper()))
|
||||||
|
{
|
||||||
|
Logger.Info($"Loading {fileName}");
|
||||||
|
var assetsFile = new SerializedFile(this, fullName, reader);
|
||||||
|
if (assetsFile.valid)
|
||||||
|
{
|
||||||
|
assetsFileList.Add(assetsFile);
|
||||||
|
assetsfileListHash.Add(assetsFile.upperFileName);
|
||||||
|
|
||||||
|
foreach (var sharedFile in assetsFile.m_Externals)
|
||||||
|
{
|
||||||
|
var sharedFilePath = Path.GetDirectoryName(fullName) + "\\" + sharedFile.fileName;
|
||||||
|
var sharedFileName = sharedFile.fileName;
|
||||||
|
|
||||||
|
if (!importFilesHash.Contains(sharedFileName.ToUpper()))
|
||||||
|
{
|
||||||
|
if (!File.Exists(sharedFilePath))
|
||||||
|
{
|
||||||
|
var findFiles = Directory.GetFiles(Path.GetDirectoryName(fullName), sharedFileName, SearchOption.AllDirectories);
|
||||||
|
if (findFiles.Length > 0)
|
||||||
|
{
|
||||||
|
sharedFilePath = findFiles[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(sharedFilePath))
|
||||||
|
{
|
||||||
|
importFiles.Add(sharedFilePath);
|
||||||
|
importFilesHash.Add(sharedFileName.ToUpper());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reader.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reader.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadAssetsFromMemory(string fullName, EndianBinaryReader reader, string originalPath, string unityVersion = null)
|
||||||
|
{
|
||||||
|
var fileName = Path.GetFileName(fullName);
|
||||||
|
if (!assetsfileListHash.Contains(fileName.ToUpper()))
|
||||||
|
{
|
||||||
|
Logger.Info($"Loading {fileName}");
|
||||||
|
var assetsFile = new SerializedFile(this, fullName, reader);
|
||||||
|
if (assetsFile.valid)
|
||||||
|
{
|
||||||
|
assetsFile.originalPath = originalPath;
|
||||||
|
if (assetsFile.header.m_Version < 7)
|
||||||
|
{
|
||||||
|
assetsFile.SetVersion(unityVersion);
|
||||||
|
}
|
||||||
|
assetsFileList.Add(assetsFile);
|
||||||
|
assetsfileListHash.Add(assetsFile.upperFileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resourceFileReaders.Add(assetsFile.upperFileName, assetsFile.reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadBundleFile(string fullName, EndianBinaryReader reader, string parentPath = null)
|
||||||
|
{
|
||||||
|
var fileName = Path.GetFileName(fullName);
|
||||||
|
Logger.Info("Decompressing " + fileName);
|
||||||
|
var bundleFile = new BundleFile(reader, fullName);
|
||||||
|
reader.Dispose();
|
||||||
|
foreach (var file in bundleFile.fileList)
|
||||||
|
{
|
||||||
|
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
|
||||||
|
LoadAssetsFromMemory(dummyPath, new EndianBinaryReader(file.stream), parentPath ?? fullName, bundleFile.versionEngine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadWebFile(string fullName, EndianBinaryReader reader)
|
||||||
|
{
|
||||||
|
var fileName = Path.GetFileName(fullName);
|
||||||
|
Logger.Info("Loading " + fileName);
|
||||||
|
var webFile = new WebFile(reader);
|
||||||
|
reader.Dispose();
|
||||||
|
foreach (var file in webFile.fileList)
|
||||||
|
{
|
||||||
|
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
|
||||||
|
switch (CheckFileType(file.stream, out reader))
|
||||||
|
{
|
||||||
|
case FileType.AssetsFile:
|
||||||
|
LoadAssetsFromMemory(dummyPath, reader, fullName);
|
||||||
|
break;
|
||||||
|
case FileType.BundleFile:
|
||||||
|
LoadBundleFile(dummyPath, reader, fullName);
|
||||||
|
break;
|
||||||
|
case FileType.WebFile:
|
||||||
|
LoadWebFile(dummyPath, reader);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
foreach (var assetsFile in assetsFileList)
|
||||||
|
{
|
||||||
|
assetsFile.reader.Close();
|
||||||
|
}
|
||||||
|
assetsFileList.Clear();
|
||||||
|
foreach (var resourceFileReader in resourceFileReaders)
|
||||||
|
{
|
||||||
|
resourceFileReader.Value.Close();
|
||||||
|
}
|
||||||
|
resourceFileReaders.Clear();
|
||||||
|
assetsFileIndexCache.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public class BuildType
|
||||||
|
{
|
||||||
|
private string buildType;
|
||||||
|
|
||||||
|
public BuildType(string type)
|
||||||
|
{
|
||||||
|
buildType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAlpha => buildType == "a";
|
||||||
|
public bool IsPatch => buildType == "p";
|
||||||
|
}
|
||||||
|
}
|
|
@ -102,7 +102,7 @@ namespace AssetStudio
|
||||||
for (int i = 0; i < fileCount; i++)
|
for (int i = 0; i < fileCount; i++)
|
||||||
{
|
{
|
||||||
var file = new StreamFile();
|
var file = new StreamFile();
|
||||||
file.fileName = reader.ReadStringToNull();
|
file.fileName = Path.GetFileName(reader.ReadStringToNull());
|
||||||
int fileOffset = reader.ReadInt32();
|
int fileOffset = reader.ReadInt32();
|
||||||
fileOffset += offset;
|
fileOffset += offset;
|
||||||
int fileSize = reader.ReadInt32();
|
int fileSize = reader.ReadInt32();
|
|
@ -1,9 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using SharpDX;
|
using SharpDX;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Text;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
class AnimatorOverrideController : NamedObject
|
public class AnimatorOverrideController : NamedObject
|
||||||
{
|
{
|
||||||
public PPtr m_Controller;
|
public PPtr m_Controller;
|
||||||
public PPtr[][] m_Clips;
|
public PPtr[][] m_Clips;
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace AssetStudio
|
||||||
if (reader.byteSize + reader.byteStart - reader.Position != tsize)
|
if (reader.byteSize + reader.byteStart - reader.Position != tsize)
|
||||||
{
|
{
|
||||||
m_Offset = reader.ReadInt32();
|
m_Offset = reader.ReadInt32();
|
||||||
m_Source = sourceFile.filePath + ".resS";
|
m_Source = sourceFile.fullName + ".resS";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -83,7 +83,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(m_Source))
|
if (!string.IsNullOrEmpty(m_Source))
|
||||||
{
|
{
|
||||||
m_AudioData = ResourcesHelper.GetData(m_Source, sourceFile.filePath, m_Offset, (int)m_Size);
|
m_AudioData = ResourcesHelper.GetData(m_Source, sourceFile, m_Offset, (int)m_Size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
m_Shader = reader.ReadPPtr();
|
m_Shader = reader.ReadPPtr();
|
||||||
|
|
||||||
if (version[0] == 4 && (version[1] >= 2 || (version[1] == 1 && buildType[0] != "a")))
|
if (version[0] == 4 && (version[1] >= 2 || (version[1] == 1 && !buildType.IsAlpha)))
|
||||||
{
|
{
|
||||||
m_ShaderKeywords = new string[reader.ReadInt32()];
|
m_ShaderKeywords = new string[reader.ReadInt32()];
|
||||||
for (int i = 0; i < m_ShaderKeywords.Length; i++)
|
for (int i = 0; i < m_ShaderKeywords.Length; i++)
|
||||||
|
|
|
@ -20,10 +20,10 @@ namespace AssetStudio
|
||||||
public float[] m_Vertices;
|
public float[] m_Vertices;
|
||||||
public float[] m_Normals;
|
public float[] m_Normals;
|
||||||
public float[] m_Colors;
|
public float[] m_Colors;
|
||||||
|
public float[] m_UV0;
|
||||||
public float[] m_UV1;
|
public float[] m_UV1;
|
||||||
public float[] m_UV2;
|
public float[] m_UV2;
|
||||||
public float[] m_UV3;
|
public float[] m_UV3;
|
||||||
public float[] m_UV4;
|
|
||||||
public float[] m_Tangents;
|
public float[] m_Tangents;
|
||||||
public uint[] m_BoneNameHashes;
|
public uint[] m_BoneNameHashes;
|
||||||
public BlendShapeData m_Shapes;
|
public BlendShapeData m_Shapes;
|
||||||
|
@ -295,7 +295,7 @@ namespace AssetStudio
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region BlendShapeData for 4.1.0 to 4.2.x, excluding 4.1.0 alpha
|
#region BlendShapeData for 4.1.0 to 4.2.x, excluding 4.1.0 alpha
|
||||||
if (version[0] == 4 && ((version[1] == 1 && buildType[0] != "a") || (version[1] > 1 && version[1] <= 2)))
|
if (version[0] == 4 && ((version[1] == 1 && !buildType.IsAlpha) || (version[1] > 1 && version[1] <= 2)))
|
||||||
{
|
{
|
||||||
int m_Shapes_size = reader.ReadInt32();
|
int m_Shapes_size = reader.ReadInt32();
|
||||||
if (m_Shapes_size > 0)
|
if (m_Shapes_size > 0)
|
||||||
|
@ -359,7 +359,7 @@ namespace AssetStudio
|
||||||
reader.AlignStream(4);
|
reader.AlignStream(4);
|
||||||
//This is a bug fixed in 2017.3.1p1 and later versions
|
//This is a bug fixed in 2017.3.1p1 and later versions
|
||||||
if ((version[0] > 2017 || (version[0] == 2017 && version[1] >= 4)) || //2017.4
|
if ((version[0] > 2017 || (version[0] == 2017 && version[1] >= 4)) || //2017.4
|
||||||
((version[0] == 2017 && version[1] == 3 && version[2] == 1) && buildType[0] == "p") || //fixed after 2017.3.1px
|
((version[0] == 2017 && version[1] == 3 && version[2] == 1) && buildType.IsPatch) || //fixed after 2017.3.1px
|
||||||
((version[0] == 2017 && version[1] == 3) && m_MeshCompression == 0))//2017.3.xfx with no compression
|
((version[0] == 2017 && version[1] == 3) && m_MeshCompression == 0))//2017.3.xfx with no compression
|
||||||
{
|
{
|
||||||
var m_IndexFormat = reader.ReadInt32();
|
var m_IndexFormat = reader.ReadInt32();
|
||||||
|
@ -407,12 +407,12 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_UV1_size = reader.ReadInt32();
|
int m_UV1_size = reader.ReadInt32();
|
||||||
m_UV1 = new float[m_UV1_size * 2];
|
m_UV0 = new float[m_UV1_size * 2];
|
||||||
for (int v = 0; v < m_UV1_size * 2; v++) { m_UV1[v] = reader.ReadSingle(); }
|
for (int v = 0; v < m_UV1_size * 2; v++) { m_UV0[v] = reader.ReadSingle(); }
|
||||||
|
|
||||||
int m_UV2_size = reader.ReadInt32();
|
int m_UV2_size = reader.ReadInt32();
|
||||||
m_UV2 = new float[m_UV2_size * 2];
|
m_UV1 = new float[m_UV2_size * 2];
|
||||||
for (int v = 0; v < m_UV2_size * 2; v++) { m_UV2[v] = reader.ReadSingle(); }
|
for (int v = 0; v < m_UV2_size * 2; v++) { m_UV1[v] = reader.ReadSingle(); }
|
||||||
|
|
||||||
if (version[0] == 2 && version[1] <= 5)
|
if (version[0] == 2 && version[1] <= 5)
|
||||||
{
|
{
|
||||||
|
@ -631,16 +631,16 @@ namespace AssetStudio
|
||||||
m_Colors = componentsFloatArray;
|
m_Colors = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
case 4: //kShaderChannelTexCoord0
|
case 4: //kShaderChannelTexCoord0
|
||||||
m_UV1 = componentsFloatArray;
|
m_UV0 = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
case 5: //kShaderChannelTexCoord1
|
case 5: //kShaderChannelTexCoord1
|
||||||
m_UV2 = componentsFloatArray;
|
m_UV1 = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
case 6: //kShaderChannelTexCoord2
|
case 6: //kShaderChannelTexCoord2
|
||||||
m_UV3 = componentsFloatArray;
|
m_UV2 = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
case 7: //kShaderChannelTexCoord3
|
case 7: //kShaderChannelTexCoord3
|
||||||
m_UV4 = componentsFloatArray;
|
m_UV3 = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
//kShaderChannelTexCoord4 8
|
//kShaderChannelTexCoord4 8
|
||||||
//kShaderChannelTexCoord5 9
|
//kShaderChannelTexCoord5 9
|
||||||
|
@ -744,15 +744,15 @@ namespace AssetStudio
|
||||||
m_Colors = componentsFloatArray;
|
m_Colors = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
case 3: //kShaderChannelTexCoord0
|
case 3: //kShaderChannelTexCoord0
|
||||||
m_UV1 = componentsFloatArray;
|
m_UV0 = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
case 4: //kShaderChannelTexCoord1
|
case 4: //kShaderChannelTexCoord1
|
||||||
m_UV2 = componentsFloatArray;
|
m_UV1 = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
case 5: //kShaderChannelTangent & kShaderChannelTexCoord2
|
case 5: //kShaderChannelTangent & kShaderChannelTexCoord2
|
||||||
if (version[0] >= 5)
|
if (version[0] >= 5)
|
||||||
{
|
{
|
||||||
m_UV3 = componentsFloatArray;
|
m_UV2 = componentsFloatArray;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -760,7 +760,7 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6: //kShaderChannelTexCoord3
|
case 6: //kShaderChannelTexCoord3
|
||||||
m_UV4 = componentsFloatArray;
|
m_UV3 = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
case 7: //kShaderChannelTangent
|
case 7: //kShaderChannelTangent
|
||||||
m_Tangents = componentsFloatArray;
|
m_Tangents = componentsFloatArray;
|
||||||
|
@ -831,8 +831,8 @@ namespace AssetStudio
|
||||||
case 0: m_Vertices = componentsArray; break;
|
case 0: m_Vertices = componentsArray; break;
|
||||||
case 1: m_Normals = componentsArray; break;
|
case 1: m_Normals = componentsArray; break;
|
||||||
case 2: m_Colors = componentsArray; break;
|
case 2: m_Colors = componentsArray; break;
|
||||||
case 3: m_UV1 = componentsArray; break;
|
case 3: m_UV0 = componentsArray; break;
|
||||||
case 4: m_UV2 = componentsArray; break;
|
case 4: m_UV1 = componentsArray; break;
|
||||||
case 5: m_Tangents = componentsArray; break;
|
case 5: m_Tangents = componentsArray; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -864,18 +864,18 @@ namespace AssetStudio
|
||||||
var m_UV_Packed = new PackedFloatVector(reader);
|
var m_UV_Packed = new PackedFloatVector(reader);
|
||||||
if (m_UV_Packed.m_NumItems > 0)
|
if (m_UV_Packed.m_NumItems > 0)
|
||||||
{
|
{
|
||||||
m_UV1 = m_UV_Packed.UnpackFloats(2, 4, 0, m_VertexCount);
|
m_UV0 = m_UV_Packed.UnpackFloats(2, 4, 0, m_VertexCount);
|
||||||
if (m_UV_Packed.m_NumItems >= m_VertexCount * 4)
|
if (m_UV_Packed.m_NumItems >= m_VertexCount * 4)
|
||||||
{
|
{
|
||||||
m_UV2 = m_UV_Packed.UnpackFloats(2, 4, m_VertexCount * 2, m_VertexCount);
|
m_UV1 = m_UV_Packed.UnpackFloats(2, 4, m_VertexCount * 2, m_VertexCount);
|
||||||
}
|
}
|
||||||
if (m_UV_Packed.m_NumItems >= m_VertexCount * 6)
|
if (m_UV_Packed.m_NumItems >= m_VertexCount * 6)
|
||||||
{
|
{
|
||||||
m_UV3 = m_UV_Packed.UnpackFloats(2, 4, m_VertexCount * 4, m_VertexCount);
|
m_UV2 = m_UV_Packed.UnpackFloats(2, 4, m_VertexCount * 4, m_VertexCount);
|
||||||
}
|
}
|
||||||
if (m_UV_Packed.m_NumItems >= m_VertexCount * 8)
|
if (m_UV_Packed.m_NumItems >= m_VertexCount * 8)
|
||||||
{
|
{
|
||||||
m_UV4 = m_UV_Packed.UnpackFloats(2, 4, m_VertexCount * 6, m_VertexCount);
|
m_UV3 = m_UV_Packed.UnpackFloats(2, 4, m_VertexCount * 6, m_VertexCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -7,10 +7,10 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
public abstract class Object
|
public abstract class Object
|
||||||
{
|
{
|
||||||
protected AssetsFile sourceFile;
|
protected SerializedFile sourceFile;
|
||||||
public ObjectReader reader;
|
public ObjectReader reader;
|
||||||
public int[] version;
|
public int[] version;
|
||||||
protected string[] buildType;
|
protected BuildType buildType;
|
||||||
public BuildTarget platform;
|
public BuildTarget platform;
|
||||||
|
|
||||||
protected Object(ObjectReader reader)
|
protected Object(ObjectReader reader)
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
using static AssetStudio.Studio;
|
namespace AssetStudio
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public class PPtr
|
public class PPtr
|
||||||
{
|
{
|
||||||
public int m_FileID;
|
public int m_FileID;
|
||||||
public long m_PathID;
|
public long m_PathID;
|
||||||
|
|
||||||
//custom
|
public SerializedFile assetsFile;
|
||||||
public AssetsFile assetsFile;
|
|
||||||
public int index = -2; //-2 - Prepare, -1 - Missing
|
public int index = -2; //-2 - Prepare, -1 - Missing
|
||||||
|
|
||||||
private bool TryGetAssetsFile(out AssetsFile result)
|
private bool TryGetAssetsFile(out SerializedFile result)
|
||||||
{
|
{
|
||||||
result = null;
|
result = null;
|
||||||
if (m_FileID == 0)
|
if (m_FileID == 0)
|
||||||
|
@ -22,6 +19,10 @@ namespace AssetStudio
|
||||||
|
|
||||||
if (m_FileID > 0 && m_FileID - 1 < assetsFile.m_Externals.Count)
|
if (m_FileID > 0 && m_FileID - 1 < assetsFile.m_Externals.Count)
|
||||||
{
|
{
|
||||||
|
var assetsManager = assetsFile.assetsManager;
|
||||||
|
var assetsfileList = assetsManager.assetsFileList;
|
||||||
|
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
||||||
|
|
||||||
if (index == -2)
|
if (index == -2)
|
||||||
{
|
{
|
||||||
var m_External = assetsFile.m_Externals[m_FileID - 1];
|
var m_External = assetsFile.m_Externals[m_FileID - 1];
|
|
@ -105,7 +105,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(path))
|
if (!string.IsNullOrEmpty(path))
|
||||||
{
|
{
|
||||||
image_data = ResourcesHelper.GetData(path, sourceFile.filePath, offset, image_data_size);
|
image_data = ResourcesHelper.GetData(path, sourceFile, offset, image_data_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(m_Source))
|
if (!string.IsNullOrEmpty(m_Source))
|
||||||
{
|
{
|
||||||
m_VideoData = ResourcesHelper.GetData(m_Source, sourceFile.filePath, (long)m_Offset, (int)m_Size);
|
m_VideoData = ResourcesHelper.GetData(m_Source, sourceFile, (long)m_Offset, (int)m_Size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
|
@ -14,13 +14,11 @@ namespace AssetStudio
|
||||||
public class EndianBinaryReader : BinaryReader
|
public class EndianBinaryReader : BinaryReader
|
||||||
{
|
{
|
||||||
public EndianType endian;
|
public EndianType endian;
|
||||||
private byte[] a16 = new byte[2];
|
|
||||||
private byte[] a32 = new byte[4];
|
|
||||||
private byte[] a64 = new byte[8];
|
|
||||||
|
|
||||||
public EndianBinaryReader(Stream stream, EndianType endian = EndianType.BigEndian)
|
public EndianBinaryReader(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream)
|
||||||
: base(stream)
|
{
|
||||||
{ this.endian = endian; }
|
this.endian = endian;
|
||||||
|
}
|
||||||
|
|
||||||
public long Position
|
public long Position
|
||||||
{
|
{
|
||||||
|
@ -32,9 +30,9 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (endian == EndianType.BigEndian)
|
if (endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
a16 = ReadBytes(2);
|
var buff = ReadBytes(2);
|
||||||
Array.Reverse(a16);
|
Array.Reverse(buff);
|
||||||
return BitConverter.ToInt16(a16, 0);
|
return BitConverter.ToInt16(buff, 0);
|
||||||
}
|
}
|
||||||
return base.ReadInt16();
|
return base.ReadInt16();
|
||||||
}
|
}
|
||||||
|
@ -43,9 +41,9 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (endian == EndianType.BigEndian)
|
if (endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
a32 = ReadBytes(4);
|
var buff = ReadBytes(4);
|
||||||
Array.Reverse(a32);
|
Array.Reverse(buff);
|
||||||
return BitConverter.ToInt32(a32, 0);
|
return BitConverter.ToInt32(buff, 0);
|
||||||
}
|
}
|
||||||
return base.ReadInt32();
|
return base.ReadInt32();
|
||||||
}
|
}
|
||||||
|
@ -54,9 +52,9 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (endian == EndianType.BigEndian)
|
if (endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
a64 = ReadBytes(8);
|
var buff = ReadBytes(8);
|
||||||
Array.Reverse(a64);
|
Array.Reverse(buff);
|
||||||
return BitConverter.ToInt64(a64, 0);
|
return BitConverter.ToInt64(buff, 0);
|
||||||
}
|
}
|
||||||
return base.ReadInt64();
|
return base.ReadInt64();
|
||||||
}
|
}
|
||||||
|
@ -65,9 +63,9 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (endian == EndianType.BigEndian)
|
if (endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
a16 = ReadBytes(2);
|
var buff = ReadBytes(2);
|
||||||
Array.Reverse(a16);
|
Array.Reverse(buff);
|
||||||
return BitConverter.ToUInt16(a16, 0);
|
return BitConverter.ToUInt16(buff, 0);
|
||||||
}
|
}
|
||||||
return base.ReadUInt16();
|
return base.ReadUInt16();
|
||||||
}
|
}
|
||||||
|
@ -76,9 +74,9 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (endian == EndianType.BigEndian)
|
if (endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
a32 = ReadBytes(4);
|
var buff = ReadBytes(4);
|
||||||
Array.Reverse(a32);
|
Array.Reverse(buff);
|
||||||
return BitConverter.ToUInt32(a32, 0);
|
return BitConverter.ToUInt32(buff, 0);
|
||||||
}
|
}
|
||||||
return base.ReadUInt32();
|
return base.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
@ -87,9 +85,9 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (endian == EndianType.BigEndian)
|
if (endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
a64 = ReadBytes(8);
|
var buff = ReadBytes(8);
|
||||||
Array.Reverse(a64);
|
Array.Reverse(buff);
|
||||||
return BitConverter.ToUInt64(a64, 0);
|
return BitConverter.ToUInt64(buff, 0);
|
||||||
}
|
}
|
||||||
return base.ReadUInt64();
|
return base.ReadUInt64();
|
||||||
}
|
}
|
||||||
|
@ -98,9 +96,9 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (endian == EndianType.BigEndian)
|
if (endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
a32 = ReadBytes(4);
|
var buff = ReadBytes(4);
|
||||||
Array.Reverse(a32);
|
Array.Reverse(buff);
|
||||||
return BitConverter.ToSingle(a32, 0);
|
return BitConverter.ToSingle(buff, 0);
|
||||||
}
|
}
|
||||||
return base.ReadSingle();
|
return base.ReadSingle();
|
||||||
}
|
}
|
||||||
|
@ -109,9 +107,9 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (endian == EndianType.BigEndian)
|
if (endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
a64 = ReadBytes(8);
|
var buff = ReadBytes(8);
|
||||||
Array.Reverse(a64);
|
Array.Reverse(buff);
|
||||||
return BitConverter.ToUInt64(a64, 0);
|
return BitConverter.ToUInt64(buff, 0);
|
||||||
}
|
}
|
||||||
return base.ReadDouble();
|
return base.ReadDouble();
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using SharpDX;
|
using SharpDX;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
|
@ -1,8 +1,4 @@
|
||||||
using System;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
|
@ -0,0 +1,104 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public enum FileType
|
||||||
|
{
|
||||||
|
AssetsFile,
|
||||||
|
BundleFile,
|
||||||
|
WebFile
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ImportHelper
|
||||||
|
{
|
||||||
|
public static void MergeSplitAssets(string path, bool allDirectories = false)
|
||||||
|
{
|
||||||
|
var splitFiles = Directory.GetFiles(path, "*.split0", allDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (var splitFile in splitFiles)
|
||||||
|
{
|
||||||
|
var destFile = Path.GetFileNameWithoutExtension(splitFile);
|
||||||
|
var destPath = Path.GetDirectoryName(splitFile) + "\\";
|
||||||
|
var destFull = destPath + destFile;
|
||||||
|
if (!File.Exists(destFull))
|
||||||
|
{
|
||||||
|
var splitParts = Directory.GetFiles(destPath, destFile + ".split*");
|
||||||
|
using (var destStream = File.Create(destFull))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < splitParts.Length; i++)
|
||||||
|
{
|
||||||
|
var splitPart = destFull + ".split" + i;
|
||||||
|
using (var sourceStream = File.OpenRead(splitPart))
|
||||||
|
{
|
||||||
|
sourceStream.CopyTo(destStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] ProcessingSplitFiles(List<string> selectFile)
|
||||||
|
{
|
||||||
|
var splitFiles = selectFile.Where(x => x.Contains(".split"))
|
||||||
|
.Select(x => Path.GetDirectoryName(x) + "\\" + Path.GetFileNameWithoutExtension(x))
|
||||||
|
.Distinct()
|
||||||
|
.ToList();
|
||||||
|
selectFile.RemoveAll(x => x.Contains(".split"));
|
||||||
|
foreach (var file in splitFiles)
|
||||||
|
{
|
||||||
|
if (File.Exists(file))
|
||||||
|
{
|
||||||
|
selectFile.Add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selectFile.Distinct().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FileType CheckFileType(Stream stream, out EndianBinaryReader reader)
|
||||||
|
{
|
||||||
|
reader = new EndianBinaryReader(stream);
|
||||||
|
return CheckFileType(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FileType CheckFileType(string fileName, out EndianBinaryReader reader)
|
||||||
|
{
|
||||||
|
reader = new EndianBinaryReader(File.OpenRead(fileName));
|
||||||
|
return CheckFileType(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileType CheckFileType(EndianBinaryReader reader)
|
||||||
|
{
|
||||||
|
var signature = reader.ReadStringToNull();
|
||||||
|
reader.Position = 0;
|
||||||
|
switch (signature)
|
||||||
|
{
|
||||||
|
case "UnityWeb":
|
||||||
|
case "UnityRaw":
|
||||||
|
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":
|
||||||
|
case "UnityFS":
|
||||||
|
return FileType.BundleFile;
|
||||||
|
case "UnityWebData1.0":
|
||||||
|
return FileType.WebFile;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
var magic = reader.ReadBytes(2);
|
||||||
|
reader.Position = 0;
|
||||||
|
if (WebFile.gzipMagic.SequenceEqual(magic))
|
||||||
|
{
|
||||||
|
return FileType.WebFile;
|
||||||
|
}
|
||||||
|
reader.Position = 0x20;
|
||||||
|
magic = reader.ReadBytes(6);
|
||||||
|
reader.Position = 0;
|
||||||
|
if (WebFile.brotliMagic.SequenceEqual(magic))
|
||||||
|
{
|
||||||
|
return FileType.WebFile;
|
||||||
|
}
|
||||||
|
return FileType.AssetsFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ namespace Lz4
|
||||||
Reset(input, inputLength);
|
Reset(input, inputLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset(Stream input, long inputLength = long.MaxValue)
|
private void Reset(Stream input, long inputLength = long.MaxValue)
|
||||||
{
|
{
|
||||||
this.inputLength = inputLength;
|
this.inputLength = inputLength;
|
||||||
this.input = input;
|
this.input = input;
|
||||||
|
@ -40,6 +40,7 @@ namespace Lz4
|
||||||
input.Close();
|
input.Close();
|
||||||
}
|
}
|
||||||
input = null;
|
input = null;
|
||||||
|
decodeBuffer = null;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
public class ObjectReader : EndianBinaryReader
|
public class ObjectReader : EndianBinaryReader
|
||||||
{
|
{
|
||||||
public AssetsFile assetsFile;
|
public SerializedFile assetsFile;
|
||||||
public long m_PathID;
|
public long m_PathID;
|
||||||
public uint byteStart;
|
public uint byteStart;
|
||||||
public uint byteSize;
|
public uint byteSize;
|
||||||
|
@ -18,11 +18,9 @@ namespace AssetStudio
|
||||||
private uint m_Version;
|
private uint m_Version;
|
||||||
|
|
||||||
public int[] version => assetsFile.version;
|
public int[] version => assetsFile.version;
|
||||||
public string[] buildType => assetsFile.buildType;
|
public BuildType buildType => assetsFile.buildType;
|
||||||
|
|
||||||
public string exportName; //TODO Remove it
|
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.endian)
|
||||||
|
|
||||||
public ObjectReader(EndianBinaryReader reader, AssetsFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.endian)
|
|
||||||
{
|
{
|
||||||
this.assetsFile = assetsFile;
|
this.assetsFile = assetsFile;
|
||||||
m_PathID = objectInfo.m_PathID;
|
m_PathID = objectInfo.m_PathID;
|
|
@ -2,35 +2,35 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// 有关程序集的一般信息由以下
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// 控制。更改这些特性值可修改
|
||||||
// associated with an assembly.
|
// 与程序集关联的信息。
|
||||||
[assembly: AssemblyTitle("AssetStudio")]
|
[assembly: AssemblyTitle("AssetStudio")]
|
||||||
[assembly: AssemblyDescription("AssetStudio is a tool for exploring, extracting and exporting assets and assetbundles.")]
|
[assembly: AssemblyDescription("")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("AssetStudio")]
|
[assembly: AssemblyProduct("AssetStudio")]
|
||||||
[assembly: AssemblyCopyright("")]
|
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||||
// to COM components. If you need to access a type in this assembly from
|
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
//请将此类型的 ComVisible 特性设置为 true。
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||||
[assembly: Guid("05c04c20-dd89-4895-9f06-33d5cfbfe925")]
|
[assembly: Guid("af56b63c-1764-41b7-9e60-8d485422ac3b")]
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
// 程序集的版本信息由下列四个值组成:
|
||||||
//
|
//
|
||||||
// Major Version
|
// 主版本
|
||||||
// Minor Version
|
// 次版本
|
||||||
// Build Number
|
// 生成号
|
||||||
// Revision
|
// 修订号
|
||||||
//
|
//
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||||
// by using the '*' as shown below:
|
//通过使用 "*",如下所示:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.11.0.0")]
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
[assembly: AssemblyFileVersion("0.11.0.0")]
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
|
|
|
@ -3,26 +3,26 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public static class ResourcesHelper
|
internal static class ResourcesHelper
|
||||||
{
|
{
|
||||||
public static byte[] GetData(string path, string sourceFilePath, long offset, int size)
|
public static byte[] GetData(string path, SerializedFile assetsFile, long offset, int size)
|
||||||
{
|
{
|
||||||
var resourceFileName = Path.GetFileName(path);
|
var resourceFileName = Path.GetFileName(path);
|
||||||
|
|
||||||
if (Studio.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader))
|
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader))
|
||||||
{
|
{
|
||||||
reader.Position = offset;
|
reader.Position = offset;
|
||||||
return reader.ReadBytes(size);
|
return reader.ReadBytes(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
var resourceFilePath = Path.GetDirectoryName(sourceFilePath) + "\\" + resourceFileName;
|
var currentDirectory = Path.GetDirectoryName(assetsFile.fullName);
|
||||||
|
var resourceFilePath = currentDirectory + "\\" + resourceFileName;
|
||||||
if (!File.Exists(resourceFilePath))
|
if (!File.Exists(resourceFilePath))
|
||||||
{
|
{
|
||||||
var findFiles = Directory.GetFiles(Path.GetDirectoryName(sourceFilePath), resourceFileName, SearchOption.AllDirectories);
|
var findFiles = Directory.GetFiles(currentDirectory, resourceFileName, SearchOption.AllDirectories);
|
||||||
if (findFiles.Length > 0)
|
if (findFiles.Length > 0)
|
||||||
{
|
{
|
||||||
resourceFilePath = findFiles[0];
|
resourceFilePath = findFiles[0];
|
||||||
|
@ -36,11 +36,8 @@ namespace AssetStudio
|
||||||
return resourceReader.ReadBytes(size);
|
return resourceReader.ReadBytes(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
|
||||||
MessageBox.Show($"can't find the resource file {resourceFileName}");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,41 +6,41 @@ using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public class AssetsFile
|
public class SerializedFile
|
||||||
{
|
{
|
||||||
|
public AssetsManager assetsManager;
|
||||||
public EndianBinaryReader reader;
|
public EndianBinaryReader reader;
|
||||||
public string filePath;
|
public string fullName;
|
||||||
public string parentPath;
|
public string originalPath;
|
||||||
public string fileName;
|
public string fileName;
|
||||||
public string upperFileName;
|
public string upperFileName;
|
||||||
public int[] version = { 0, 0, 0, 0 };
|
public int[] version = { 0, 0, 0, 0 };
|
||||||
public string[] buildType;
|
public BuildType buildType;
|
||||||
public string platformStr;
|
|
||||||
public bool valid;
|
public bool valid;
|
||||||
public Dictionary<long, ObjectReader> ObjectReaders = new Dictionary<long, ObjectReader>();
|
public Dictionary<long, ObjectReader> ObjectReaders = new Dictionary<long, ObjectReader>();
|
||||||
public Dictionary<long, GameObject> GameObjects = new Dictionary<long, GameObject>();
|
public Dictionary<long, GameObject> GameObjects = new Dictionary<long, GameObject>();
|
||||||
public Dictionary<long, Transform> Transforms = new Dictionary<long, Transform>();
|
public Dictionary<long, Transform> Transforms = new Dictionary<long, Transform>();
|
||||||
|
|
||||||
//class SerializedFile
|
|
||||||
public SerializedFileHeader header;
|
public SerializedFileHeader header;
|
||||||
private EndianType m_FileEndianess;
|
private EndianType 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 Dictionary<long, ObjectInfo> m_Objects;
|
private 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 AssetsFile(string fullName, EndianBinaryReader reader)
|
public SerializedFile(AssetsManager assetsManager, string fullName, EndianBinaryReader reader)
|
||||||
{
|
{
|
||||||
|
this.assetsManager = assetsManager;
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
filePath = fullName;
|
this.fullName = fullName;
|
||||||
fileName = Path.GetFileName(fullName);
|
fileName = Path.GetFileName(fullName);
|
||||||
upperFileName = fileName.ToUpper();
|
upperFileName = fileName.ToUpper();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//SerializedFile::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();
|
||||||
|
@ -59,7 +59,7 @@ namespace AssetStudio
|
||||||
m_FileEndianess = (EndianType)reader.ReadByte();
|
m_FileEndianess = (EndianType)reader.ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
//SerializedFile::ReadMetadata
|
//ReadMetadata
|
||||||
if (m_FileEndianess == EndianType.LittleEndian)
|
if (m_FileEndianess == EndianType.LittleEndian)
|
||||||
{
|
{
|
||||||
reader.endian = EndianType.LittleEndian;
|
reader.endian = EndianType.LittleEndian;
|
||||||
|
@ -67,6 +67,7 @@ namespace AssetStudio
|
||||||
if (header.m_Version >= 7)
|
if (header.m_Version >= 7)
|
||||||
{
|
{
|
||||||
unityVersion = reader.ReadStringToNull();
|
unityVersion = reader.ReadStringToNull();
|
||||||
|
SetVersion(unityVersion);
|
||||||
}
|
}
|
||||||
if (header.m_Version >= 8)
|
if (header.m_Version >= 8)
|
||||||
{
|
{
|
||||||
|
@ -76,13 +77,12 @@ namespace AssetStudio
|
||||||
m_TargetPlatform = BuildTarget.UnknownPlatform;
|
m_TargetPlatform = BuildTarget.UnknownPlatform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
platformStr = m_TargetPlatform.ToString();
|
|
||||||
if (header.m_Version >= 13)
|
if (header.m_Version >= 13)
|
||||||
{
|
{
|
||||||
m_EnableTypeTree = reader.ReadBoolean();
|
m_EnableTypeTree = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read types
|
//ReadTypes
|
||||||
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++)
|
||||||
|
@ -95,9 +95,9 @@ namespace AssetStudio
|
||||||
var bigIDEnabled = reader.ReadInt32();
|
var bigIDEnabled = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read Objects
|
//ReadObjects
|
||||||
int objectCount = reader.ReadInt32();
|
int objectCount = reader.ReadInt32();
|
||||||
m_Objects = new Dictionary<long, ObjectInfo>(objectCount);
|
m_Objects = new List<ObjectInfo>(objectCount);
|
||||||
for (int i = 0; i < objectCount; i++)
|
for (int i = 0; i < objectCount; i++)
|
||||||
{
|
{
|
||||||
var objectInfo = new ObjectInfo();
|
var objectInfo = new ObjectInfo();
|
||||||
|
@ -130,23 +130,11 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
var stripped = reader.ReadByte();
|
var stripped = reader.ReadByte();
|
||||||
}
|
}
|
||||||
m_Objects.Add(objectInfo.m_PathID, objectInfo);
|
m_Objects.Add(objectInfo);
|
||||||
|
|
||||||
//Create Reader
|
//Create Reader
|
||||||
var objectReader = new ObjectReader(reader, this, objectInfo);
|
var objectReader = new ObjectReader(reader, this, objectInfo);
|
||||||
ObjectReaders.Add(objectInfo.m_PathID, objectReader);
|
ObjectReaders.Add(objectInfo.m_PathID, objectReader);
|
||||||
|
|
||||||
#region read BuildSettings to get version for version 2.x files
|
|
||||||
if (objectReader.type == ClassIDType.BuildSettings && header.m_Version == 6)
|
|
||||||
{
|
|
||||||
var nextAsset = reader.Position;
|
|
||||||
|
|
||||||
var buildSettings = new BuildSettings(objectReader);
|
|
||||||
unityVersion = buildSettings.m_Version;
|
|
||||||
|
|
||||||
reader.Position = nextAsset;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header.m_Version >= 11)
|
if (header.m_Version >= 11)
|
||||||
|
@ -194,10 +182,6 @@ namespace AssetStudio
|
||||||
//var userInformation = reader.ReadStringToNull();
|
//var userInformation = reader.ReadStringToNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
buildType = Regex.Replace(unityVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
var versionSplit = Regex.Replace(unityVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
version = versionSplit.Select(int.Parse).ToArray();
|
|
||||||
|
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -206,6 +190,14 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetVersion(string stringVersion)
|
||||||
|
{
|
||||||
|
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
buildType = new BuildType(buildSplit[0]);
|
||||||
|
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
version = versionSplit.Select(int.Parse).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
private SerializedType ReadSerializedType()
|
private SerializedType ReadSerializedType()
|
||||||
{
|
{
|
||||||
var type = new SerializedType();
|
var type = new SerializedType();
|
|
@ -11,18 +11,18 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
var decoder = new Decoder();
|
var decoder = new Decoder();
|
||||||
|
|
||||||
inStream.Seek(0, 0);
|
inStream.Seek(0, SeekOrigin.Begin);
|
||||||
var newOutStream = new MemoryStream();
|
var newOutStream = new MemoryStream();
|
||||||
|
|
||||||
var properties = new byte[5];
|
var properties = new byte[5];
|
||||||
if (inStream.Read(properties, 0, 5) != 5)
|
if (inStream.Read(properties, 0, 5) != 5)
|
||||||
throw (new Exception("input .lzma is too short"));
|
throw new Exception("input .lzma is too short");
|
||||||
long outSize = 0;
|
long outSize = 0;
|
||||||
for (var i = 0; i < 8; i++)
|
for (var i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
var v = inStream.ReadByte();
|
var v = inStream.ReadByte();
|
||||||
if (v < 0)
|
if (v < 0)
|
||||||
throw (new Exception("Can't Read 1"));
|
throw new Exception("Can't Read 1");
|
||||||
outSize |= ((long)(byte)v) << (8 * i);
|
outSize |= ((long)(byte)v) << (8 * i);
|
||||||
}
|
}
|
||||||
decoder.SetDecoderProperties(properties);
|
decoder.SetDecoderProperties(properties);
|
|
@ -1,22 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
public class GameObjectTreeNode : TreeNode
|
|
||||||
{
|
|
||||||
public GameObject gameObject;
|
|
||||||
|
|
||||||
public GameObjectTreeNode(GameObject gameObject)
|
|
||||||
{
|
|
||||||
if (gameObject != null)
|
|
||||||
{
|
|
||||||
this.gameObject = gameObject;
|
|
||||||
Text = gameObject.m_Name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,183 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using static AssetStudio.Studio;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
static class Importer
|
|
||||||
{
|
|
||||||
public static List<string> importFiles = new List<string>(); //files to load
|
|
||||||
public static HashSet<string> importFilesHash = new HashSet<string>(); //to improve the loading speed
|
|
||||||
public static HashSet<string> assetsfileListHash = new HashSet<string>(); //to improve the loading speed
|
|
||||||
|
|
||||||
public static void LoadFile(string fullName)
|
|
||||||
{
|
|
||||||
switch (CheckFileType(fullName, out var reader))
|
|
||||||
{
|
|
||||||
case FileType.AssetsFile:
|
|
||||||
LoadAssetsFile(fullName, reader);
|
|
||||||
break;
|
|
||||||
case FileType.BundleFile:
|
|
||||||
LoadBundleFile(fullName, reader);
|
|
||||||
break;
|
|
||||||
case FileType.WebFile:
|
|
||||||
LoadWebFile(fullName, reader);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void LoadAssetsFile(string fullName, EndianBinaryReader reader, string parentPath = null)
|
|
||||||
{
|
|
||||||
var fileName = Path.GetFileName(fullName);
|
|
||||||
StatusStripUpdate("Loading " + fileName);
|
|
||||||
if (!assetsfileListHash.Contains(fileName.ToUpper()))
|
|
||||||
{
|
|
||||||
var assetsFile = new AssetsFile(fullName, reader);
|
|
||||||
if (assetsFile.valid)
|
|
||||||
{
|
|
||||||
assetsFile.parentPath = parentPath;
|
|
||||||
assetsfileList.Add(assetsFile);
|
|
||||||
assetsfileListHash.Add(assetsFile.upperFileName);
|
|
||||||
|
|
||||||
#region for 2.6.x find mainData and get string version
|
|
||||||
if (assetsFile.header.m_Version == 6 && fileName != "mainData")
|
|
||||||
{
|
|
||||||
var mainDataFile = assetsfileList.Find(aFile => aFile.fileName == "mainData");
|
|
||||||
if (mainDataFile != null)
|
|
||||||
{
|
|
||||||
assetsFile.unityVersion = mainDataFile.unityVersion;
|
|
||||||
assetsFile.version = mainDataFile.version;
|
|
||||||
assetsFile.buildType = mainDataFile.buildType;
|
|
||||||
}
|
|
||||||
else if (File.Exists(Path.GetDirectoryName(fullName) + "\\mainData"))
|
|
||||||
{
|
|
||||||
mainDataFile = new AssetsFile(Path.GetDirectoryName(fullName) + "\\mainData", new EndianBinaryReader(File.OpenRead(Path.GetDirectoryName(fullName) + "\\mainData")));
|
|
||||||
assetsFile.unityVersion = mainDataFile.unityVersion;
|
|
||||||
assetsFile.version = mainDataFile.version;
|
|
||||||
assetsFile.buildType = mainDataFile.buildType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
int value = 0;
|
|
||||||
foreach (var sharedFile in assetsFile.m_Externals)
|
|
||||||
{
|
|
||||||
var sharedFilePath = Path.GetDirectoryName(fullName) + "\\" + sharedFile.fileName;
|
|
||||||
var sharedFileName = sharedFile.fileName;
|
|
||||||
|
|
||||||
if (!importFilesHash.Contains(sharedFileName.ToUpper()))
|
|
||||||
{
|
|
||||||
if (!File.Exists(sharedFilePath))
|
|
||||||
{
|
|
||||||
var findFiles = Directory.GetFiles(Path.GetDirectoryName(fullName), sharedFileName, SearchOption.AllDirectories);
|
|
||||||
if (findFiles.Length > 0)
|
|
||||||
{
|
|
||||||
sharedFilePath = findFiles[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File.Exists(sharedFilePath))
|
|
||||||
{
|
|
||||||
importFiles.Add(sharedFilePath);
|
|
||||||
importFilesHash.Add(sharedFileName.ToUpper());
|
|
||||||
value++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value > 0)
|
|
||||||
ProgressBarMaximumAdd(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
reader.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void LoadBundleFile(string fullName, EndianBinaryReader reader, string parentPath = null)
|
|
||||||
{
|
|
||||||
var fileName = Path.GetFileName(fullName);
|
|
||||||
StatusStripUpdate("Decompressing " + fileName);
|
|
||||||
var bundleFile = new BundleFile(reader, fullName);
|
|
||||||
reader.Dispose();
|
|
||||||
foreach (var file in bundleFile.fileList)
|
|
||||||
{
|
|
||||||
if (!assetsfileListHash.Contains(file.fileName.ToUpper()))
|
|
||||||
{
|
|
||||||
StatusStripUpdate("Loading " + file.fileName);
|
|
||||||
var assetsFile = new AssetsFile(Path.GetDirectoryName(fullName) + "\\" + file.fileName, new EndianBinaryReader(file.stream));
|
|
||||||
if (assetsFile.valid)
|
|
||||||
{
|
|
||||||
assetsFile.parentPath = parentPath ?? fullName;
|
|
||||||
|
|
||||||
if (assetsFile.header.m_Version == 6) //2.6.x and earlier don't have a string version before the preload table
|
|
||||||
{
|
|
||||||
//make use of the bundle file version
|
|
||||||
assetsFile.unityVersion = bundleFile.versionEngine;
|
|
||||||
assetsFile.version = Regex.Matches(bundleFile.versionEngine, @"\d").Cast<Match>().Select(m => int.Parse(m.Value)).ToArray();
|
|
||||||
assetsFile.buildType = Regex.Replace(bundleFile.versionEngine, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
assetsfileList.Add(assetsFile);
|
|
||||||
assetsfileListHash.Add(assetsFile.upperFileName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resourceFileReaders.Add(assetsFile.upperFileName, assetsFile.reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void LoadWebFile(string fullName, EndianBinaryReader reader)
|
|
||||||
{
|
|
||||||
var fileName = Path.GetFileName(fullName);
|
|
||||||
StatusStripUpdate("Loading " + fileName);
|
|
||||||
var webFile = new WebFile(reader);
|
|
||||||
reader.Dispose();
|
|
||||||
foreach (var file in webFile.fileList)
|
|
||||||
{
|
|
||||||
var dummyName = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
|
|
||||||
switch (CheckFileType(file.stream, out reader))
|
|
||||||
{
|
|
||||||
case FileType.AssetsFile:
|
|
||||||
LoadAssetsFile(dummyName, reader, fullName);
|
|
||||||
break;
|
|
||||||
case FileType.BundleFile:
|
|
||||||
LoadBundleFile(dummyName, reader, fullName);
|
|
||||||
break;
|
|
||||||
case FileType.WebFile:
|
|
||||||
LoadWebFile(dummyName, reader);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
resourceFileReaders.Add(file.fileName.ToUpper(), reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void MergeSplitAssets(string dirPath)
|
|
||||||
{
|
|
||||||
string[] splitFiles = Directory.GetFiles(dirPath, "*.split0");
|
|
||||||
foreach (var splitFile in splitFiles)
|
|
||||||
{
|
|
||||||
string destFile = Path.GetFileNameWithoutExtension(splitFile);
|
|
||||||
string destPath = Path.GetDirectoryName(splitFile) + "\\";
|
|
||||||
var destFull = destPath + destFile;
|
|
||||||
if (!File.Exists(destFull))
|
|
||||||
{
|
|
||||||
string[] splitParts = Directory.GetFiles(destPath, destFile + ".split*");
|
|
||||||
using (var destStream = File.Create(destFull))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < splitParts.Length; i++)
|
|
||||||
{
|
|
||||||
string splitPart = destFull + ".split" + i;
|
|
||||||
using (var sourceStream = File.OpenRead(splitPart))
|
|
||||||
sourceStream.CopyTo(destStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,759 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using static AssetStudio.Exporter;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
internal static class Studio
|
|
||||||
{
|
|
||||||
public static List<AssetsFile> assetsfileList = new List<AssetsFile>(); //loaded files
|
|
||||||
public static Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>();
|
|
||||||
public static Dictionary<string, EndianBinaryReader> resourceFileReaders = new Dictionary<string, EndianBinaryReader>(); //use for read res files
|
|
||||||
public static List<AssetItem> exportableAssets = new List<AssetItem>(); //used to hold all assets while the ListView is filtered
|
|
||||||
private static HashSet<string> assetsNameHash = new HashSet<string>(); //avoid the same name asset
|
|
||||||
public static List<AssetItem> visibleAssets = new List<AssetItem>(); //used to build the ListView from all or filtered assets
|
|
||||||
public static Dictionary<string, SortedDictionary<int, TypeTreeItem>> AllTypeMap = new Dictionary<string, SortedDictionary<int, TypeTreeItem>>();
|
|
||||||
public static List<GameObjectTreeNode> treeNodeCollection = new List<GameObjectTreeNode>();
|
|
||||||
public static Dictionary<GameObject, GameObjectTreeNode> treeNodeDictionary = new Dictionary<GameObject, GameObjectTreeNode>();
|
|
||||||
public static string mainPath;
|
|
||||||
public static string productName = string.Empty;
|
|
||||||
|
|
||||||
//UI
|
|
||||||
public static Action<int> SetProgressBarValue;
|
|
||||||
public static Action<int> SetProgressBarMaximum;
|
|
||||||
public static Action ProgressBarPerformStep;
|
|
||||||
public static Action<string> StatusStripUpdate;
|
|
||||||
public static Action<int> ProgressBarMaximumAdd;
|
|
||||||
|
|
||||||
public enum FileType
|
|
||||||
{
|
|
||||||
AssetsFile,
|
|
||||||
BundleFile,
|
|
||||||
WebFile
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FileType CheckFileType(Stream stream, out EndianBinaryReader reader)
|
|
||||||
{
|
|
||||||
reader = new EndianBinaryReader(stream);
|
|
||||||
return CheckFileType(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FileType CheckFileType(string fileName, out EndianBinaryReader reader)
|
|
||||||
{
|
|
||||||
reader = new EndianBinaryReader(File.OpenRead(fileName));
|
|
||||||
return CheckFileType(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static FileType CheckFileType(EndianBinaryReader reader)
|
|
||||||
{
|
|
||||||
var signature = reader.ReadStringToNull();
|
|
||||||
reader.Position = 0;
|
|
||||||
switch (signature)
|
|
||||||
{
|
|
||||||
case "UnityWeb":
|
|
||||||
case "UnityRaw":
|
|
||||||
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":
|
|
||||||
case "UnityFS":
|
|
||||||
return FileType.BundleFile;
|
|
||||||
case "UnityWebData1.0":
|
|
||||||
return FileType.WebFile;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
var magic = reader.ReadBytes(2);
|
|
||||||
reader.Position = 0;
|
|
||||||
if (WebFile.gzipMagic.SequenceEqual(magic))
|
|
||||||
{
|
|
||||||
return FileType.WebFile;
|
|
||||||
}
|
|
||||||
reader.Position = 0x20;
|
|
||||||
magic = reader.ReadBytes(6);
|
|
||||||
reader.Position = 0;
|
|
||||||
if (WebFile.brotliMagic.SequenceEqual(magic))
|
|
||||||
{
|
|
||||||
return FileType.WebFile;
|
|
||||||
}
|
|
||||||
return FileType.AssetsFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ExtractFile(string[] fileNames)
|
|
||||||
{
|
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
|
||||||
{
|
|
||||||
int extractedCount = 0;
|
|
||||||
foreach (var fileName in fileNames)
|
|
||||||
{
|
|
||||||
var type = CheckFileType(fileName, out var reader);
|
|
||||||
if (type == FileType.BundleFile)
|
|
||||||
extractedCount += ExtractBundleFile(fileName, reader);
|
|
||||||
else if (type == FileType.WebFile)
|
|
||||||
extractedCount += ExtractWebDataFile(fileName, reader);
|
|
||||||
else
|
|
||||||
reader.Dispose();
|
|
||||||
ProgressBarPerformStep();
|
|
||||||
}
|
|
||||||
StatusStripUpdate($"Finished extracting {extractedCount} files.");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int ExtractBundleFile(string bundleFileName, EndianBinaryReader reader)
|
|
||||||
{
|
|
||||||
StatusStripUpdate($"Decompressing {Path.GetFileName(bundleFileName)} ...");
|
|
||||||
var bundleFile = new BundleFile(reader, bundleFileName);
|
|
||||||
reader.Dispose();
|
|
||||||
if (bundleFile.fileList.Count > 0)
|
|
||||||
{
|
|
||||||
var extractPath = bundleFileName + "_unpacked\\";
|
|
||||||
Directory.CreateDirectory(extractPath);
|
|
||||||
return ExtractStreamFile(extractPath, bundleFile.fileList);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int ExtractWebDataFile(string webFileName, EndianBinaryReader reader)
|
|
||||||
{
|
|
||||||
StatusStripUpdate($"Decompressing {Path.GetFileName(webFileName)} ...");
|
|
||||||
var webFile = new WebFile(reader);
|
|
||||||
reader.Dispose();
|
|
||||||
if (webFile.fileList.Count > 0)
|
|
||||||
{
|
|
||||||
var extractPath = webFileName + "_unpacked\\";
|
|
||||||
Directory.CreateDirectory(extractPath);
|
|
||||||
return ExtractStreamFile(extractPath, webFile.fileList);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int ExtractStreamFile(string extractPath, List<StreamFile> fileList)
|
|
||||||
{
|
|
||||||
int extractedCount = 0;
|
|
||||||
foreach (var file in fileList)
|
|
||||||
{
|
|
||||||
var filePath = extractPath + file.fileName;
|
|
||||||
if (!Directory.Exists(extractPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(extractPath);
|
|
||||||
}
|
|
||||||
if (!File.Exists(filePath) && file.stream is MemoryStream stream)
|
|
||||||
{
|
|
||||||
File.WriteAllBytes(filePath, stream.ToArray());
|
|
||||||
extractedCount += 1;
|
|
||||||
}
|
|
||||||
file.stream.Dispose();
|
|
||||||
}
|
|
||||||
return extractedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void BuildAssetStructures(bool loadAssets, bool displayAll, bool buildHierarchy, bool buildClassStructures, bool displayOriginalName)
|
|
||||||
{
|
|
||||||
var tempDic = new Dictionary<ObjectReader, AssetItem>();
|
|
||||||
// first loop - read asset data & create list
|
|
||||||
if (loadAssets)
|
|
||||||
{
|
|
||||||
SetProgressBarValue(0);
|
|
||||||
SetProgressBarMaximum(assetsfileList.Sum(x => x.ObjectReaders.Count));
|
|
||||||
StatusStripUpdate("Building asset list...");
|
|
||||||
|
|
||||||
var fileIDfmt = "D" + assetsfileList.Count.ToString().Length;
|
|
||||||
|
|
||||||
for (var i = 0; i < assetsfileList.Count; i++)
|
|
||||||
{
|
|
||||||
var assetsFile = assetsfileList[i];
|
|
||||||
var tempExportableAssets = new List<AssetItem>();
|
|
||||||
var fileID = i.ToString(fileIDfmt);
|
|
||||||
AssetBundle ab = null;
|
|
||||||
var j = 0;
|
|
||||||
var assetIDfmt = "D" + assetsFile.m_Objects.Count.ToString().Length;
|
|
||||||
foreach (var objectReader in assetsFile.ObjectReaders.Values)
|
|
||||||
{
|
|
||||||
var assetItem = new AssetItem(objectReader);
|
|
||||||
tempDic.Add(objectReader, assetItem);
|
|
||||||
assetItem.UniqueID = fileID + j.ToString(assetIDfmt);
|
|
||||||
var exportable = false;
|
|
||||||
switch (assetItem.Type)
|
|
||||||
{
|
|
||||||
case ClassIDType.GameObject:
|
|
||||||
{
|
|
||||||
var m_GameObject = new GameObject(objectReader);
|
|
||||||
assetItem.Text = m_GameObject.m_Name;
|
|
||||||
assetsFile.GameObjects.Add(objectReader.m_PathID, m_GameObject);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.Transform:
|
|
||||||
{
|
|
||||||
var m_Transform = new Transform(objectReader);
|
|
||||||
assetsFile.Transforms.Add(objectReader.m_PathID, m_Transform);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.RectTransform:
|
|
||||||
{
|
|
||||||
var m_Rect = new RectTransform(objectReader);
|
|
||||||
assetsFile.Transforms.Add(objectReader.m_PathID, m_Rect);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.Texture2D:
|
|
||||||
{
|
|
||||||
var m_Texture2D = new Texture2D(objectReader, false);
|
|
||||||
if (!string.IsNullOrEmpty(m_Texture2D.path))
|
|
||||||
assetItem.FullSize = objectReader.byteSize + m_Texture2D.size;
|
|
||||||
assetItem.Text = m_Texture2D.m_Name;
|
|
||||||
exportable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.AudioClip:
|
|
||||||
{
|
|
||||||
var m_AudioClip = new AudioClip(objectReader, false);
|
|
||||||
if (!string.IsNullOrEmpty(m_AudioClip.m_Source))
|
|
||||||
assetItem.FullSize = objectReader.byteSize + m_AudioClip.m_Size;
|
|
||||||
assetItem.Text = m_AudioClip.m_Name;
|
|
||||||
exportable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.VideoClip:
|
|
||||||
{
|
|
||||||
var m_VideoClip = new VideoClip(objectReader, false);
|
|
||||||
if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath))
|
|
||||||
assetItem.FullSize = objectReader.byteSize + (long)m_VideoClip.m_Size;
|
|
||||||
assetItem.Text = m_VideoClip.m_Name;
|
|
||||||
exportable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.Shader:
|
|
||||||
{
|
|
||||||
var m_Shader = new Shader(objectReader);
|
|
||||||
assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
|
|
||||||
exportable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.Mesh:
|
|
||||||
case ClassIDType.TextAsset:
|
|
||||||
case ClassIDType.AnimationClip:
|
|
||||||
case ClassIDType.Font:
|
|
||||||
case ClassIDType.MovieTexture:
|
|
||||||
case ClassIDType.Sprite:
|
|
||||||
{
|
|
||||||
var obj = new NamedObject(objectReader);
|
|
||||||
assetItem.Text = obj.m_Name;
|
|
||||||
exportable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.Avatar:
|
|
||||||
case ClassIDType.AnimatorController:
|
|
||||||
case ClassIDType.AnimatorOverrideController:
|
|
||||||
case ClassIDType.Material:
|
|
||||||
case ClassIDType.MonoScript:
|
|
||||||
case ClassIDType.SpriteAtlas:
|
|
||||||
{
|
|
||||||
var obj = new NamedObject(objectReader);
|
|
||||||
assetItem.Text = obj.m_Name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.Animator:
|
|
||||||
{
|
|
||||||
exportable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.MonoBehaviour:
|
|
||||||
{
|
|
||||||
var m_MonoBehaviour = new MonoBehaviour(objectReader);
|
|
||||||
if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var script))
|
|
||||||
{
|
|
||||||
var m_Script = new MonoScript(script);
|
|
||||||
assetItem.Text = m_Script.m_ClassName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assetItem.Text = m_MonoBehaviour.m_Name;
|
|
||||||
}
|
|
||||||
exportable = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.PlayerSettings:
|
|
||||||
{
|
|
||||||
var plSet = new PlayerSettings(objectReader);
|
|
||||||
productName = plSet.productName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.AssetBundle:
|
|
||||||
{
|
|
||||||
ab = new AssetBundle(objectReader);
|
|
||||||
assetItem.Text = ab.m_Name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (assetItem.Text == "")
|
|
||||||
{
|
|
||||||
assetItem.Text = assetItem.TypeString + " #" + assetItem.UniqueID;
|
|
||||||
}
|
|
||||||
assetItem.SubItems.AddRange(new[] { assetItem.TypeString, assetItem.FullSize.ToString() });
|
|
||||||
//处理同名文件
|
|
||||||
if (!assetsNameHash.Add((assetItem.TypeString + assetItem.Text).ToUpper()))
|
|
||||||
{
|
|
||||||
assetItem.Text += " #" + assetItem.UniqueID;
|
|
||||||
}
|
|
||||||
//处理非法文件名
|
|
||||||
assetItem.Text = FixFileName(assetItem.Text);
|
|
||||||
if (displayAll)
|
|
||||||
{
|
|
||||||
exportable = true;
|
|
||||||
}
|
|
||||||
if (exportable)
|
|
||||||
{
|
|
||||||
tempExportableAssets.Add(assetItem);
|
|
||||||
}
|
|
||||||
objectReader.exportName = assetItem.Text;
|
|
||||||
|
|
||||||
ProgressBarPerformStep();
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if (displayOriginalName)
|
|
||||||
{
|
|
||||||
foreach (var x in tempExportableAssets)
|
|
||||||
{
|
|
||||||
var replacename = ab?.m_Container.Find(y => y.second.asset.m_PathID == x.reader.m_PathID)?.first;
|
|
||||||
if (!string.IsNullOrEmpty(replacename))
|
|
||||||
{
|
|
||||||
var ex = Path.GetExtension(replacename);
|
|
||||||
x.Text = !string.IsNullOrEmpty(ex) ? replacename.Replace(ex, "") : replacename;
|
|
||||||
x.reader.exportName = x.Text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exportableAssets.AddRange(tempExportableAssets);
|
|
||||||
tempExportableAssets.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
visibleAssets = exportableAssets;
|
|
||||||
assetsNameHash.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// second loop - build tree structure
|
|
||||||
if (buildHierarchy)
|
|
||||||
{
|
|
||||||
var gameObjectCount = assetsfileList.Sum(x => x.GameObjects.Count);
|
|
||||||
if (gameObjectCount > 0)
|
|
||||||
{
|
|
||||||
SetProgressBarValue(0);
|
|
||||||
SetProgressBarMaximum(gameObjectCount);
|
|
||||||
StatusStripUpdate("Building tree structure...");
|
|
||||||
|
|
||||||
foreach (var assetsFile in assetsfileList)
|
|
||||||
{
|
|
||||||
var fileNode = new GameObjectTreeNode(null); //RootNode
|
|
||||||
fileNode.Text = assetsFile.fileName;
|
|
||||||
|
|
||||||
foreach (var m_GameObject in assetsFile.GameObjects.Values)
|
|
||||||
{
|
|
||||||
foreach (var m_Component in m_GameObject.m_Components)
|
|
||||||
{
|
|
||||||
if (m_Component.TryGet(out var asset))
|
|
||||||
{
|
|
||||||
switch (asset.type)
|
|
||||||
{
|
|
||||||
case ClassIDType.Transform:
|
|
||||||
{
|
|
||||||
m_GameObject.m_Transform = m_Component;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.MeshRenderer:
|
|
||||||
{
|
|
||||||
m_GameObject.m_MeshRenderer = m_Component;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.MeshFilter:
|
|
||||||
{
|
|
||||||
m_GameObject.m_MeshFilter = m_Component;
|
|
||||||
if (m_Component.TryGet(out var objectReader))
|
|
||||||
{
|
|
||||||
var m_MeshFilter = new MeshFilter(objectReader);
|
|
||||||
if (m_MeshFilter.m_Mesh.TryGet(out objectReader))
|
|
||||||
{
|
|
||||||
var item = tempDic[objectReader];
|
|
||||||
item.gameObject = m_GameObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.SkinnedMeshRenderer:
|
|
||||||
{
|
|
||||||
m_GameObject.m_SkinnedMeshRenderer = m_Component;
|
|
||||||
if (m_Component.TryGet(out var objectReader))
|
|
||||||
{
|
|
||||||
var m_SkinnedMeshRenderer = new SkinnedMeshRenderer(objectReader);
|
|
||||||
if (m_SkinnedMeshRenderer.m_Mesh.TryGet(out objectReader))
|
|
||||||
{
|
|
||||||
var item = tempDic[objectReader];
|
|
||||||
item.gameObject = m_GameObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ClassIDType.Animator:
|
|
||||||
{
|
|
||||||
m_GameObject.m_Animator = m_Component;
|
|
||||||
var item = tempDic[asset];
|
|
||||||
item.Text = m_GameObject.reader.exportName;
|
|
||||||
asset.exportName = m_GameObject.reader.exportName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var parentNode = fileNode;
|
|
||||||
|
|
||||||
if (m_GameObject.m_Transform != null && m_GameObject.m_Transform.TryGetTransform(out var m_Transform))
|
|
||||||
{
|
|
||||||
if (m_Transform.m_Father.TryGetTransform(out var m_Father))
|
|
||||||
{
|
|
||||||
if (m_Father.m_GameObject.TryGetGameObject(out var parentGameObject))
|
|
||||||
{
|
|
||||||
if (!treeNodeDictionary.TryGetValue(parentGameObject, out parentNode))
|
|
||||||
{
|
|
||||||
parentNode = new GameObjectTreeNode(parentGameObject);
|
|
||||||
treeNodeDictionary.Add(parentGameObject, parentNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!treeNodeDictionary.TryGetValue(m_GameObject, out var currentNode))
|
|
||||||
{
|
|
||||||
currentNode = new GameObjectTreeNode(m_GameObject);
|
|
||||||
treeNodeDictionary.Add(m_GameObject, currentNode);
|
|
||||||
}
|
|
||||||
parentNode.Nodes.Add(currentNode);
|
|
||||||
|
|
||||||
ProgressBarPerformStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileNode.Nodes.Count > 0)
|
|
||||||
{
|
|
||||||
treeNodeCollection.Add(fileNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempDic.Clear();
|
|
||||||
|
|
||||||
// build list of class strucutres
|
|
||||||
if (buildClassStructures)
|
|
||||||
{
|
|
||||||
foreach (var assetsFile in assetsfileList)
|
|
||||||
{
|
|
||||||
if (AllTypeMap.TryGetValue(assetsFile.unityVersion, out var curVer))
|
|
||||||
{
|
|
||||||
foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null))
|
|
||||||
{
|
|
||||||
var key = type.classID;
|
|
||||||
if (type.m_ScriptTypeIndex >= 0)
|
|
||||||
{
|
|
||||||
key = -1 - type.m_ScriptTypeIndex;
|
|
||||||
}
|
|
||||||
curVer[key] = new TypeTreeItem(key, type.m_Nodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var items = new SortedDictionary<int, TypeTreeItem>();
|
|
||||||
foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null))
|
|
||||||
{
|
|
||||||
var key = type.classID;
|
|
||||||
if (type.m_ScriptTypeIndex >= 0)
|
|
||||||
{
|
|
||||||
key = -1 - type.m_ScriptTypeIndex;
|
|
||||||
}
|
|
||||||
items.Add(key, new TypeTreeItem(key, type.m_Nodes));
|
|
||||||
}
|
|
||||||
AllTypeMap.Add(assetsFile.unityVersion, items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string FixFileName(string str)
|
|
||||||
{
|
|
||||||
if (str.Length >= 260) return Path.GetRandomFileName();
|
|
||||||
return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string[] ProcessingSplitFiles(List<string> selectFile)
|
|
||||||
{
|
|
||||||
var splitFiles = selectFile.Where(x => x.Contains(".split"))
|
|
||||||
.Select(x => Path.GetDirectoryName(x) + "\\" + Path.GetFileNameWithoutExtension(x))
|
|
||||||
.Distinct()
|
|
||||||
.ToList();
|
|
||||||
selectFile.RemoveAll(x => x.Contains(".split"));
|
|
||||||
foreach (var file in splitFiles)
|
|
||||||
{
|
|
||||||
if (File.Exists(file))
|
|
||||||
{
|
|
||||||
selectFile.Add(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return selectFile.Distinct().ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ExportAssets(string savePath, List<AssetItem> toExportAssets, int assetGroupSelectedIndex, bool openAfterExport)
|
|
||||||
{
|
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
|
||||||
{
|
|
||||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
|
|
||||||
|
|
||||||
int toExport = toExportAssets.Count;
|
|
||||||
int exportedCount = 0;
|
|
||||||
|
|
||||||
SetProgressBarValue(0);
|
|
||||||
SetProgressBarMaximum(toExport);
|
|
||||||
foreach (var asset in toExportAssets)
|
|
||||||
{
|
|
||||||
var exportpath = savePath + "\\";
|
|
||||||
if (assetGroupSelectedIndex == 1)
|
|
||||||
{
|
|
||||||
exportpath += Path.GetFileNameWithoutExtension(asset.sourceFile.filePath) + "_export\\";
|
|
||||||
}
|
|
||||||
else if (assetGroupSelectedIndex == 0)
|
|
||||||
{
|
|
||||||
exportpath = savePath + "\\" + asset.TypeString + "\\";
|
|
||||||
}
|
|
||||||
StatusStripUpdate($"Exporting {asset.TypeString}: {asset.Text}");
|
|
||||||
var reader = asset.reader;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
switch (asset.Type)
|
|
||||||
{
|
|
||||||
case ClassIDType.Texture2D:
|
|
||||||
if (ExportTexture2D(reader, exportpath, true))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.AudioClip:
|
|
||||||
if (ExportAudioClip(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.Shader:
|
|
||||||
if (ExportShader(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.TextAsset:
|
|
||||||
if (ExportTextAsset(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.MonoBehaviour:
|
|
||||||
if (ExportMonoBehaviour(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.Font:
|
|
||||||
if (ExportFont(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.Mesh:
|
|
||||||
if (ExportMesh(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.VideoClip:
|
|
||||||
if (ExportVideoClip(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.MovieTexture:
|
|
||||||
if (ExportMovieTexture(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.Sprite:
|
|
||||||
if (ExportSprite(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.Animator:
|
|
||||||
if (ExportAnimator(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ClassIDType.AnimationClip:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (ExportRawFile(reader, exportpath))
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"Export {asset.Type}:{asset.Text} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
|
||||||
}
|
|
||||||
ProgressBarPerformStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
var statusText = exportedCount == 0 ? "Nothing exported." : $"Finished exporting {exportedCount} assets.";
|
|
||||||
|
|
||||||
if (toExport > exportedCount)
|
|
||||||
{
|
|
||||||
statusText += $" {toExport - exportedCount} assets skipped (not extractable or files already exist)";
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusStripUpdate(statusText);
|
|
||||||
|
|
||||||
if (openAfterExport && exportedCount > 0)
|
|
||||||
{
|
|
||||||
Process.Start(savePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ExportSplitObjects(string savePath, TreeNodeCollection nodes)
|
|
||||||
{
|
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
|
||||||
{
|
|
||||||
foreach (GameObjectTreeNode node in nodes)
|
|
||||||
{
|
|
||||||
//遍历一级子节点
|
|
||||||
foreach (GameObjectTreeNode j in node.Nodes)
|
|
||||||
{
|
|
||||||
ProgressBarPerformStep();
|
|
||||||
//收集所有子节点
|
|
||||||
var gameObjects = new List<GameObject>();
|
|
||||||
CollectNode(j, gameObjects);
|
|
||||||
//跳过一些不需要导出的object
|
|
||||||
if (gameObjects.All(x => x.m_SkinnedMeshRenderer == null && x.m_MeshFilter == null))
|
|
||||||
continue;
|
|
||||||
//处理非法文件名
|
|
||||||
var filename = FixFileName(j.Text);
|
|
||||||
//每个文件存放在单独的文件夹
|
|
||||||
var targetPath = $"{savePath}{filename}\\";
|
|
||||||
//重名文件处理
|
|
||||||
for (int i = 1; ; i++)
|
|
||||||
{
|
|
||||||
if (Directory.Exists(targetPath))
|
|
||||||
{
|
|
||||||
targetPath = $"{savePath}{filename} ({i})\\";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Directory.CreateDirectory(targetPath);
|
|
||||||
//导出FBX
|
|
||||||
StatusStripUpdate($"Exporting {filename}.fbx");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ExportGameObject(j.gameObject, targetPath);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}");
|
|
||||||
}
|
|
||||||
StatusStripUpdate($"Finished exporting {filename}.fbx");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StatusStripUpdate("Finished");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CollectNode(GameObjectTreeNode node, List<GameObject> gameObjects)
|
|
||||||
{
|
|
||||||
gameObjects.Add(node.gameObject);
|
|
||||||
foreach (GameObjectTreeNode i in node.Nodes)
|
|
||||||
{
|
|
||||||
CollectNode(i, gameObjects);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ExportAnimatorWithAnimationClip(AssetItem animator, List<AssetItem> animationList, string exportPath)
|
|
||||||
{
|
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
|
||||||
{
|
|
||||||
StatusStripUpdate($"Exporting {animator.Text}");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ExportAnimator(animator.reader, exportPath, animationList);
|
|
||||||
StatusStripUpdate($"Finished exporting {animator.Text}");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}");
|
|
||||||
StatusStripUpdate("Error in export");
|
|
||||||
}
|
|
||||||
ProgressBarPerformStep();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ExportObjectsWithAnimationClip(string exportPath, TreeNodeCollection nodes, List<AssetItem> animationList = null)
|
|
||||||
{
|
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
|
||||||
{
|
|
||||||
var gameObjects = new List<GameObject>();
|
|
||||||
GetSelectedParentNode(nodes, gameObjects);
|
|
||||||
if (gameObjects.Count > 0)
|
|
||||||
{
|
|
||||||
SetProgressBarValue(0);
|
|
||||||
SetProgressBarMaximum(gameObjects.Count);
|
|
||||||
foreach (var gameObject in gameObjects)
|
|
||||||
{
|
|
||||||
StatusStripUpdate($"Exporting {gameObject.m_Name}");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ExportGameObject(gameObject, exportPath, animationList);
|
|
||||||
StatusStripUpdate($"Finished exporting {gameObject.m_Name}");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}");
|
|
||||||
StatusStripUpdate("Error in export");
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgressBarPerformStep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StatusStripUpdate("No Object can be exported.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void GetSelectedParentNode(TreeNodeCollection nodes, List<GameObject> gameObjects)
|
|
||||||
{
|
|
||||||
foreach (GameObjectTreeNode i in nodes)
|
|
||||||
{
|
|
||||||
if (i.Checked)
|
|
||||||
{
|
|
||||||
gameObjects.Add(i.gameObject);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GetSelectedParentNode(i.Nodes, gameObjects);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Dynamic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -154,15 +153,14 @@ namespace AssetStudio
|
||||||
reader.AlignStream(4);
|
reader.AlignStream(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExpandoObject ReadDynamicType(List<TypeTreeNode> members, EndianBinaryReader reader)
|
public static Dictionary<string, object> ReadBoxingType(List<TypeTreeNode> members, EndianBinaryReader reader)
|
||||||
{
|
{
|
||||||
var obj = new ExpandoObject();
|
var obj = new Dictionary<string, object>();
|
||||||
var objdic = (IDictionary<string, object>)obj;
|
|
||||||
for (int i = 0; i < members.Count; i++)
|
for (int i = 0; i < members.Count; i++)
|
||||||
{
|
{
|
||||||
var member = members[i];
|
var member = members[i];
|
||||||
var varNameStr = member.m_Name;
|
var varNameStr = member.m_Name;
|
||||||
objdic[varNameStr] = ReadValue(members, reader, ref i);
|
obj[varNameStr] = ReadValue(members, reader, ref i);
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -274,13 +272,12 @@ namespace AssetStudio
|
||||||
var @class = GetMembers(members, level, i);
|
var @class = GetMembers(members, level, i);
|
||||||
@class.RemoveAt(0);
|
@class.RemoveAt(0);
|
||||||
i += @class.Count;
|
i += @class.Count;
|
||||||
var obj = new ExpandoObject();
|
var obj = new Dictionary<string, object>();
|
||||||
var objdic = (IDictionary<string, object>)obj;
|
|
||||||
for (int j = 0; j < @class.Count; j++)
|
for (int j = 0; j < @class.Count; j++)
|
||||||
{
|
{
|
||||||
var classmember = @class[j];
|
var classmember = @class[j];
|
||||||
var name = classmember.m_Name;
|
var name = classmember.m_Name;
|
||||||
objdic[name] = ReadValue(@class, reader, ref j);
|
obj[name] = ReadValue(@class, reader, ref j);
|
||||||
}
|
}
|
||||||
value = obj;
|
value = obj;
|
||||||
break;
|
break;
|
||||||
|
@ -308,16 +305,15 @@ namespace AssetStudio
|
||||||
return member2;
|
return member2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] WriteDynamicType(ExpandoObject obj, List<TypeTreeNode> members)
|
public static byte[] WriteBoxingType(Dictionary<string, object> obj, List<TypeTreeNode> members)
|
||||||
{
|
{
|
||||||
var stream = new MemoryStream();
|
var stream = new MemoryStream();
|
||||||
var write = new BinaryWriter(stream);
|
var write = new BinaryWriter(stream);
|
||||||
var objdic = (IDictionary<string, object>)obj;
|
|
||||||
for (int i = 0; i < members.Count; i++)
|
for (int i = 0; i < members.Count; i++)
|
||||||
{
|
{
|
||||||
var member = members[i];
|
var member = members[i];
|
||||||
var varNameStr = member.m_Name;
|
var varNameStr = member.m_Name;
|
||||||
WriteValue(objdic[varNameStr], members, write, ref i);
|
WriteValue(obj[varNameStr], members, write, ref i);
|
||||||
}
|
}
|
||||||
return stream.ToArray();
|
return stream.ToArray();
|
||||||
}
|
}
|
||||||
|
@ -431,13 +427,12 @@ namespace AssetStudio
|
||||||
var @class = GetMembers(members, level, i);
|
var @class = GetMembers(members, level, i);
|
||||||
@class.RemoveAt(0);
|
@class.RemoveAt(0);
|
||||||
i += @class.Count;
|
i += @class.Count;
|
||||||
var obj = (ExpandoObject)value;
|
var obj = (Dictionary<string, object>)value;
|
||||||
var objdic = (IDictionary<string, object>)obj;
|
|
||||||
for (int j = 0; j < @class.Count; j++)
|
for (int j = 0; j < @class.Count; j++)
|
||||||
{
|
{
|
||||||
var classmember = @class[j];
|
var classmember = @class[j];
|
||||||
var name = classmember.m_Name;
|
var name = classmember.m_Name;
|
||||||
WriteValue(objdic[name], @class, write, ref j);
|
WriteValue(obj[name], @class, write, ref j);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
|
@ -219,7 +219,7 @@ namespace AssetStudio
|
||||||
|
|
||||||
public static ImportedMesh FindMesh(string frameName, List<ImportedMesh> importedMeshList)
|
public static ImportedMesh FindMesh(string frameName, List<ImportedMesh> importedMeshList)
|
||||||
{
|
{
|
||||||
foreach (ImportedMesh mesh in importedMeshList)
|
foreach (var mesh in importedMeshList)
|
||||||
{
|
{
|
||||||
if (mesh.Name == frameName)
|
if (mesh.Name == frameName)
|
||||||
{
|
{
|
||||||
|
@ -232,15 +232,15 @@ namespace AssetStudio
|
||||||
|
|
||||||
public static ImportedMesh FindMesh(ImportedFrame frame, List<ImportedMesh> importedMeshList)
|
public static ImportedMesh FindMesh(ImportedFrame frame, List<ImportedMesh> importedMeshList)
|
||||||
{
|
{
|
||||||
string framePath = frame.Name;
|
var framePath = frame.Name;
|
||||||
ImportedFrame root = frame;
|
var root = frame;
|
||||||
while (root.Parent != null)
|
while (root.Parent != null)
|
||||||
{
|
{
|
||||||
root = root.Parent;
|
root = root.Parent;
|
||||||
framePath = root.Name + "/" + framePath;
|
framePath = root.Name + "/" + framePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ImportedMesh mesh in importedMeshList)
|
foreach (var mesh in importedMeshList)
|
||||||
{
|
{
|
||||||
if (mesh.Name == framePath)
|
if (mesh.Name == framePath)
|
||||||
{
|
{
|
||||||
|
@ -253,7 +253,7 @@ namespace AssetStudio
|
||||||
|
|
||||||
public static ImportedMaterial FindMaterial(string name, List<ImportedMaterial> importedMats)
|
public static ImportedMaterial FindMaterial(string name, List<ImportedMaterial> importedMats)
|
||||||
{
|
{
|
||||||
foreach (ImportedMaterial mat in importedMats)
|
foreach (var mat in importedMats)
|
||||||
{
|
{
|
||||||
if (mat.Name == name)
|
if (mat.Name == name)
|
||||||
{
|
{
|
||||||
|
@ -271,7 +271,7 @@ namespace AssetStudio
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ImportedTexture tex in importedTextureList)
|
foreach (var tex in importedTextureList)
|
||||||
{
|
{
|
||||||
if (tex.Name == name)
|
if (tex.Name == name)
|
||||||
{
|
{
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public enum LoggerEvent
|
||||||
|
{
|
||||||
|
Verbose,
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ILogger
|
||||||
|
{
|
||||||
|
void Log(LoggerEvent loggerEvent, string message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class DummyLogger : ILogger
|
||||||
|
{
|
||||||
|
public void Log(LoggerEvent loggerEvent, string message) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
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) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public static class Logger
|
||||||
|
{
|
||||||
|
public static ILogger Default = new DummyLogger();
|
||||||
|
|
||||||
|
public static void Verbose(string message) => Default.Log(LoggerEvent.Verbose, message);
|
||||||
|
public static void Debug(string message) => Default.Log(LoggerEvent.Debug, 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 Error(string message) => Default.Log(LoggerEvent.Error, message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public static class Progress
|
||||||
|
{
|
||||||
|
public static IProgress Default = new DummyProgress();
|
||||||
|
private static int preValue;
|
||||||
|
|
||||||
|
public static void Reset()
|
||||||
|
{
|
||||||
|
preValue = 0;
|
||||||
|
Default.Report(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Report(int current, int total)
|
||||||
|
{
|
||||||
|
var value = (int)(current * 100f / total);
|
||||||
|
Report(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Report(int value)
|
||||||
|
{
|
||||||
|
if (value > preValue)
|
||||||
|
{
|
||||||
|
preValue = value;
|
||||||
|
Default.Report(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,15 +14,13 @@ namespace AssetStudio
|
||||||
public static byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
|
public static byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
|
||||||
public List<StreamFile> fileList = new List<StreamFile>();
|
public List<StreamFile> fileList = new List<StreamFile>();
|
||||||
|
|
||||||
|
private class WebData
|
||||||
public class WebData
|
|
||||||
{
|
{
|
||||||
public int dataOffset;
|
public int dataOffset;
|
||||||
public int dataLength;
|
public int dataLength;
|
||||||
public string path;
|
public string path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public WebFile(EndianBinaryReader reader)
|
public WebFile(EndianBinaryReader reader)
|
||||||
{
|
{
|
||||||
var magic = reader.ReadBytes(2);
|
var magic = reader.ReadBytes(2);
|
|
@ -1,69 +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="AssetStudio.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
|
||||||
</sectionGroup>
|
|
||||||
</configSections>
|
|
||||||
<userSettings>
|
|
||||||
<AssetStudio.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="displayOriginalName" serializeAs="String">
|
|
||||||
<value>False</value>
|
|
||||||
</setting>
|
|
||||||
<setting name="eulerFilter" serializeAs="String">
|
|
||||||
<value>True</value>
|
|
||||||
</setting>
|
|
||||||
<setting name="filterPrecision" serializeAs="String">
|
|
||||||
<value>0.25</value>
|
|
||||||
</setting>
|
|
||||||
<setting name="allFrames" serializeAs="String">
|
|
||||||
<value>False</value>
|
|
||||||
</setting>
|
|
||||||
<setting name="allBones" serializeAs="String">
|
|
||||||
<value>True</value>
|
|
||||||
</setting>
|
|
||||||
<setting name="skins" serializeAs="String">
|
|
||||||
<value>True</value>
|
|
||||||
</setting>
|
|
||||||
<setting name="boneSize" serializeAs="String">
|
|
||||||
<value>10</value>
|
|
||||||
</setting>
|
|
||||||
<setting name="flatInbetween" serializeAs="String">
|
|
||||||
<value>False</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>
|
|
||||||
</AssetStudio.Properties.Settings>
|
|
||||||
</userSettings>
|
|
||||||
</configuration>
|
|
|
@ -9,7 +9,7 @@ using namespace System::Security::Permissions;
|
||||||
[assembly:AssemblyConfigurationAttribute(L"")];
|
[assembly:AssemblyConfigurationAttribute(L"")];
|
||||||
[assembly:AssemblyCompanyAttribute(L"")];
|
[assembly:AssemblyCompanyAttribute(L"")];
|
||||||
[assembly:AssemblyProductAttribute(L"AssetStudioFBX")];
|
[assembly:AssemblyProductAttribute(L"AssetStudioFBX")];
|
||||||
[assembly:AssemblyCopyrightAttribute(L"Copyright © 2018")];
|
[assembly:AssemblyCopyrightAttribute(L"Copyright © Perfare 2018")];
|
||||||
[assembly:AssemblyTrademarkAttribute(L"")];
|
[assembly:AssemblyTrademarkAttribute(L"")];
|
||||||
[assembly:AssemblyCultureAttribute(L"")];
|
[assembly:AssemblyCultureAttribute(L"")];
|
||||||
|
|
||||||
|
|
|
@ -150,8 +150,8 @@
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj">
|
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
|
||||||
<Project>{9131c403-7fe8-444d-9af5-5fe5df76ff24}</Project>
|
<Project>{af56b63c-1764-41b7-9e60-8d485422ac3b}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|
|
@ -487,42 +487,39 @@ namespace AssetStudio
|
||||||
pMeshNode->AddMaterial(pMat);
|
pMeshNode->AddMaterial(pMat);
|
||||||
|
|
||||||
bool hasTexture = false;
|
bool hasTexture = false;
|
||||||
FbxFileTexture* pTextureDiffuse = ExportTexture(ImportedHelpers::FindTexture((String^)mat->Textures[0], imported->TextureList), pMesh);
|
FbxFileTexture* pTextureDiffuse = ExportTexture(ImportedHelpers::FindTexture(mat->Textures[0], imported->TextureList), pMesh);
|
||||||
if (pTextureDiffuse != NULL)
|
if (pTextureDiffuse != NULL)
|
||||||
{
|
{
|
||||||
LinkTexture(mat, 0, pTextureDiffuse, pMat->Diffuse);
|
LinkTexture(mat, 0, pTextureDiffuse, pMat->Diffuse);
|
||||||
hasTexture = true;
|
hasTexture = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FbxFileTexture* pTextureAmbient = ExportTexture(ImportedHelpers::FindTexture((String^)mat->Textures[1], imported->TextureList), pMesh);
|
FbxFileTexture* pTextureAmbient = ExportTexture(ImportedHelpers::FindTexture(mat->Textures[1], imported->TextureList), pMesh);
|
||||||
if (pTextureAmbient != NULL)
|
if (pTextureAmbient != NULL)
|
||||||
{
|
{
|
||||||
LinkTexture(mat, 1, pTextureAmbient, pMat->Ambient);
|
LinkTexture(mat, 1, pTextureAmbient, pMat->Ambient);
|
||||||
hasTexture = true;
|
hasTexture = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FbxFileTexture* pTextureEmissive = ExportTexture(ImportedHelpers::FindTexture((String^)mat->Textures[2], imported->TextureList), pMesh);
|
FbxFileTexture* pTextureEmissive = ExportTexture(ImportedHelpers::FindTexture(mat->Textures[2], imported->TextureList), pMesh);
|
||||||
if (pTextureEmissive != NULL)
|
if (pTextureEmissive != NULL)
|
||||||
{
|
{
|
||||||
LinkTexture(mat, 2, pTextureEmissive, pMat->Emissive);
|
LinkTexture(mat, 2, pTextureEmissive, pMat->Emissive);
|
||||||
hasTexture = true;
|
hasTexture = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FbxFileTexture* pTextureSpecular = ExportTexture(ImportedHelpers::FindTexture((String^)mat->Textures[3], imported->TextureList), pMesh);
|
FbxFileTexture* pTextureSpecular = ExportTexture(ImportedHelpers::FindTexture(mat->Textures[3], imported->TextureList), pMesh);
|
||||||
if (pTextureSpecular != NULL)
|
if (pTextureSpecular != NULL)
|
||||||
{
|
{
|
||||||
LinkTexture(mat, 3, pTextureSpecular, pMat->Specular);
|
LinkTexture(mat, 3, pTextureSpecular, pMat->Specular);
|
||||||
hasTexture = true;
|
hasTexture = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mat->Textures->Length > 4)
|
FbxFileTexture* pTextureBump = ExportTexture(ImportedHelpers::FindTexture(mat->Textures[4], imported->TextureList), pMesh);
|
||||||
|
if (pTextureBump != NULL)
|
||||||
{
|
{
|
||||||
FbxFileTexture* pTextureBump = ExportTexture(ImportedHelpers::FindTexture((String^)mat->Textures[4], imported->TextureList), pMesh);
|
LinkTexture(mat, 4, pTextureBump, pMat->Bump);
|
||||||
if (pTextureBump != NULL)
|
hasTexture = true;
|
||||||
{
|
|
||||||
LinkTexture(mat, 4, pTextureBump, pMat->Bump);
|
|
||||||
hasTexture = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasTexture)
|
if (hasTexture)
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||||
|
<ProductVersion>8.0.30703</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}</ProjectGuid>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>AssetStudioGUI</RootNamespace>
|
||||||
|
<AssemblyName>AssetStudioGUI</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
|
<TargetFrameworkProfile>
|
||||||
|
</TargetFrameworkProfile>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
|
<PublishUrl>publish\</PublishUrl>
|
||||||
|
<Install>true</Install>
|
||||||
|
<InstallFrom>Disk</InstallFrom>
|
||||||
|
<UpdateEnabled>false</UpdateEnabled>
|
||||||
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
|
<UpdateInterval>7</UpdateInterval>
|
||||||
|
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||||
|
<UpdatePeriodically>false</UpdatePeriodically>
|
||||||
|
<UpdateRequired>false</UpdateRequired>
|
||||||
|
<MapFileExtensions>true</MapFileExtensions>
|
||||||
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<OutputPath>bin\x86\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="dnlib, Version=3.0.0.0, Culture=neutral, PublicKeyToken=50e96378b6e77999, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\AssetStudio\Libraries\dnlib.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="OpenTK, Version=3.0.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\AssetStudio\Libraries\OpenTK.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="OpenTK.GLControl, Version=3.0.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\AssetStudio\Libraries\OpenTK.GLControl.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="GUILogger.cs" />
|
||||||
|
<Compile Include="GUIProgress.cs" />
|
||||||
|
<Compile Include="Components\GameObjectTreeNode.cs" />
|
||||||
|
<Compile Include="Components\OpenFolderDialog.cs" />
|
||||||
|
<Compile Include="Components\AssetItem.cs" />
|
||||||
|
<Compile Include="Exporter.cs" />
|
||||||
|
<Compile Include="Studio.cs" />
|
||||||
|
<Compile Include="ExportOptions.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="ExportOptions.Designer.cs">
|
||||||
|
<DependentUpon>ExportOptions.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Components\GOHierarchy.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="AssetStudioGUIForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="AssetStudioGUIForm.Designer.cs">
|
||||||
|
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Components\TypeTreeItem.cs" />
|
||||||
|
<Compile Include="Components\TreeViewExtensions.cs" />
|
||||||
|
<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>
|
||||||
|
<EmbeddedResource Include="AssetStudioGUIForm.resx">
|
||||||
|
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<None Include="app.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>
|
||||||
|
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Microsoft .NET Framework 4 Client Profile %28x86 and x64%29</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Windows Installer 4.5</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Resources\preview.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Resources\as.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\AssetStudioTools\AssetStudioTools.csproj">
|
||||||
|
<Project>{9131c403-7fe8-444d-9af5-5fe5df76ff24}</Project>
|
||||||
|
<Name>AssetStudioTools</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
|
||||||
|
<Project>{af56b63c-1764-41b7-9e60-8d485422ac3b}</Project>
|
||||||
|
<Name>AssetStudio</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<PostBuildEvent>xcopy /y "$(SolutionDir)AssetStudio\Libraries" "$(TargetDir)"
|
||||||
|
xcopy /y "$(SolutionDir)AssetStudio\Libraries\$(PlatformName)" "$(TargetDir)"</PostBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
|
@ -1,6 +1,6 @@
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
partial class AssetStudioForm
|
partial class AssetStudioGUIForm
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
this.components = new System.ComponentModel.Container();
|
this.components = new System.ComponentModel.Container();
|
||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AssetStudioForm));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AssetStudioGUIForm));
|
||||||
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
|
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
|
||||||
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.loadFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.loadFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
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();
|
||||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||||
this.sceneTreeView = new AssetStudio.GOHierarchy();
|
this.sceneTreeView = new AssetStudioGUI.GOHierarchy();
|
||||||
this.treeSearch = new System.Windows.Forms.TextBox();
|
this.treeSearch = new System.Windows.Forms.TextBox();
|
||||||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||||
this.assetListView = new System.Windows.Forms.ListView();
|
this.assetListView = new System.Windows.Forms.ListView();
|
||||||
|
@ -574,7 +574,7 @@
|
||||||
// previewPanel
|
// previewPanel
|
||||||
//
|
//
|
||||||
this.previewPanel.BackColor = System.Drawing.SystemColors.ControlDark;
|
this.previewPanel.BackColor = System.Drawing.SystemColors.ControlDark;
|
||||||
this.previewPanel.BackgroundImage = global::AssetStudio.Properties.Resources.preview;
|
this.previewPanel.BackgroundImage = global::AssetStudioGUI.Properties.Resources.preview;
|
||||||
this.previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
this.previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||||
this.previewPanel.Controls.Add(this.assetInfoLabel);
|
this.previewPanel.Controls.Add(this.assetInfoLabel);
|
||||||
this.previewPanel.Controls.Add(this.FMODpanel);
|
this.previewPanel.Controls.Add(this.FMODpanel);
|
||||||
|
@ -913,20 +913,20 @@
|
||||||
this.showOriginalFileToolStripMenuItem.Visible = false;
|
this.showOriginalFileToolStripMenuItem.Visible = false;
|
||||||
this.showOriginalFileToolStripMenuItem.Click += new System.EventHandler(this.showOriginalFileToolStripMenuItem_Click);
|
this.showOriginalFileToolStripMenuItem.Click += new System.EventHandler(this.showOriginalFileToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
// AssetStudioForm
|
// AssetStudioGUIForm
|
||||||
//
|
//
|
||||||
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.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);
|
||||||
this.Icon = global::AssetStudio.Properties.Resources._as;
|
this.Icon = global::AssetStudioGUI.Properties.Resources._as;
|
||||||
this.KeyPreview = true;
|
this.KeyPreview = true;
|
||||||
this.MainMenuStrip = this.menuStrip1;
|
this.MainMenuStrip = this.menuStrip1;
|
||||||
this.MinimumSize = new System.Drawing.Size(620, 372);
|
this.MinimumSize = new System.Drawing.Size(620, 372);
|
||||||
this.Name = "AssetStudioForm";
|
this.Name = "AssetStudioGUIForm";
|
||||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
this.Text = "AssetStudio";
|
this.Text = "AssetStudioGUI";
|
||||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AssetStudioForm_KeyDown);
|
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AssetStudioForm_KeyDown);
|
||||||
this.menuStrip1.ResumeLayout(false);
|
this.menuStrip1.ResumeLayout(false);
|
||||||
this.menuStrip1.PerformLayout();
|
this.menuStrip1.PerformLayout();
|
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,11 @@
|
||||||
using System;
|
using System.Windows.Forms;
|
||||||
using System.Linq;
|
using AssetStudio;
|
||||||
using System.Text;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
public class AssetItem : ListViewItem
|
internal class AssetItem : ListViewItem
|
||||||
{
|
{
|
||||||
public AssetsFile sourceFile;
|
public SerializedFile sourceFile;
|
||||||
public ObjectReader reader;
|
public ObjectReader reader;
|
||||||
public long FullSize;
|
public long FullSize;
|
||||||
public ClassIDType Type;
|
public ClassIDType Type;
|
|
@ -4,9 +4,9 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
public class GOHierarchy : TreeView
|
internal class GOHierarchy : TreeView
|
||||||
{
|
{
|
||||||
protected override void WndProc(ref Message m)
|
protected override void WndProc(ref Message m)
|
||||||
{
|
{
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using AssetStudio;
|
||||||
|
|
||||||
|
namespace AssetStudioGUI
|
||||||
|
{
|
||||||
|
internal class GameObjectTreeNode : TreeNode
|
||||||
|
{
|
||||||
|
public GameObject gameObject;
|
||||||
|
|
||||||
|
public GameObjectTreeNode(string name)
|
||||||
|
{
|
||||||
|
Text = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameObjectTreeNode(GameObject gameObject)
|
||||||
|
{
|
||||||
|
this.gameObject = gameObject;
|
||||||
|
Text = gameObject.m_Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,9 +4,9 @@ using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
class OpenFolderDialog
|
internal class OpenFolderDialog
|
||||||
{
|
{
|
||||||
public string InitialFolder { get; set; }
|
public string InitialFolder { get; set; }
|
||||||
public string DefaultFolder { get; set; }
|
public string DefaultFolder { get; set; }
|
|
@ -1,13 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
public static class TreeViewExtensions
|
internal static class TreeViewExtensions
|
||||||
{
|
{
|
||||||
private const int TVIF_STATE = 0x8;
|
private const int TVIF_STATE = 0x8;
|
||||||
private const int TVIS_STATEIMAGEMASK = 0xF000;
|
private const int TVIS_STATEIMAGEMASK = 0xF000;
|
|
@ -1,14 +1,13 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using AssetStudio;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
public class TypeTreeItem : ListViewItem
|
internal class TypeTreeItem : ListViewItem
|
||||||
{
|
{
|
||||||
public List<TypeTreeNode> m_Nodes;
|
private List<TypeTreeNode> m_Nodes;
|
||||||
|
|
||||||
public TypeTreeItem(int typeID, List<TypeTreeNode> m_Nodes)
|
public TypeTreeItem(int typeID, List<TypeTreeNode> m_Nodes)
|
||||||
{
|
{
|
|
@ -1,4 +1,4 @@
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
partial class ExportOptions
|
partial class ExportOptions
|
||||||
{
|
{
|
|
@ -8,7 +8,7 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
public partial class ExportOptions : Form
|
public partial class ExportOptions : Form
|
||||||
{
|
{
|
|
@ -1,25 +1,24 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using AssetStudio;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
static class Exporter
|
internal static class Exporter
|
||||||
{
|
{
|
||||||
public static bool ExportTexture2D(ObjectReader reader, string exportPathName, bool flip)
|
public static bool ExportTexture2D(AssetItem item, string exportPathName)
|
||||||
{
|
{
|
||||||
var m_Texture2D = new Texture2D(reader, true);
|
var m_Texture2D = new Texture2D(item.reader, true);
|
||||||
if (m_Texture2D.image_data == null || m_Texture2D.image_data.Length == 0)
|
if (m_Texture2D.image_data == null || m_Texture2D.image_data.Length == 0)
|
||||||
return false;
|
return false;
|
||||||
var converter = new Texture2DConverter(m_Texture2D);
|
var converter = new Texture2DConverter(m_Texture2D);
|
||||||
var convertTexture = (bool)Properties.Settings.Default["convertTexture"];
|
var convertTexture = (bool)Properties.Settings.Default["convertTexture"];
|
||||||
if (convertTexture)
|
if (convertTexture)
|
||||||
{
|
{
|
||||||
var bitmap = converter.ConvertToBitmap(flip);
|
var bitmap = converter.ConvertToBitmap(true);
|
||||||
if (bitmap == null)
|
if (bitmap == null)
|
||||||
return false;
|
return false;
|
||||||
ImageFormat format = null;
|
ImageFormat format = null;
|
||||||
|
@ -36,7 +35,7 @@ namespace AssetStudio
|
||||||
format = ImageFormat.Jpeg;
|
format = ImageFormat.Jpeg;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var exportFullName = exportPathName + reader.exportName + "." + ext.ToLower();
|
var exportFullName = exportPathName + item.Text + "." + ext.ToLower();
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
bitmap.Save(exportFullName, format);
|
bitmap.Save(exportFullName, format);
|
||||||
|
@ -45,7 +44,7 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var exportFullName = exportPathName + reader.exportName + converter.GetExtensionName();
|
var exportFullName = exportPathName + item.Text + converter.GetExtensionName();
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
File.WriteAllBytes(exportFullName, converter.ConvertToContainer());
|
File.WriteAllBytes(exportFullName, converter.ConvertToContainer());
|
||||||
|
@ -53,16 +52,16 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportAudioClip(ObjectReader reader, string exportPath)
|
public static bool ExportAudioClip(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var m_AudioClip = new AudioClip(reader, true);
|
var m_AudioClip = new AudioClip(item.reader, true);
|
||||||
if (m_AudioClip.m_AudioData == null)
|
if (m_AudioClip.m_AudioData == null)
|
||||||
return false;
|
return false;
|
||||||
var convertAudio = (bool)Properties.Settings.Default["convertAudio"];
|
var convertAudio = (bool)Properties.Settings.Default["convertAudio"];
|
||||||
var converter = new AudioClipConverter(m_AudioClip);
|
var converter = new AudioClipConverter(m_AudioClip);
|
||||||
if (convertAudio && converter.IsFMODSupport)
|
if (convertAudio && converter.IsFMODSupport)
|
||||||
{
|
{
|
||||||
var exportFullName = exportPath + reader.exportName + ".wav";
|
var exportFullName = exportPath + item.Text + ".wav";
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
var buffer = converter.ConvertToWav();
|
var buffer = converter.ConvertToWav();
|
||||||
|
@ -72,7 +71,7 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var exportFullName = exportPath + reader.exportName + converter.GetExtensionName();
|
var exportFullName = exportPath + item.Text + converter.GetExtensionName();
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
File.WriteAllBytes(exportFullName, m_AudioClip.m_AudioData);
|
File.WriteAllBytes(exportFullName, m_AudioClip.m_AudioData);
|
||||||
|
@ -80,10 +79,10 @@ namespace AssetStudio
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportShader(ObjectReader reader, string exportPath)
|
public static bool ExportShader(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var m_Shader = new Shader(reader);
|
var m_Shader = new Shader(item.reader);
|
||||||
var exportFullName = exportPath + reader.exportName + ".shader";
|
var exportFullName = exportPath + item.Text + ".shader";
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
var str = ShaderConverter.Convert(m_Shader);
|
var str = ShaderConverter.Convert(m_Shader);
|
||||||
|
@ -91,22 +90,22 @@ namespace AssetStudio
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportTextAsset(ObjectReader reader, string exportPath)
|
public static bool ExportTextAsset(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var m_TextAsset = new TextAsset(reader);
|
var m_TextAsset = new TextAsset(item.reader);
|
||||||
var exportFullName = exportPath + reader.exportName + ".txt";
|
var exportFullName = exportPath + item.Text + ".txt";
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
File.WriteAllBytes(exportFullName, m_TextAsset.m_Script);
|
File.WriteAllBytes(exportFullName, m_TextAsset.m_Script);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportMonoBehaviour(ObjectReader reader, string exportPath)
|
public static bool ExportMonoBehaviour(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var exportFullName = exportPath + reader.exportName + ".txt";
|
var exportFullName = exportPath + item.Text + ".txt";
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
var m_MonoBehaviour = new MonoBehaviour(reader);
|
var reader = item.reader;
|
||||||
string str;
|
string str;
|
||||||
if (reader.serializedType?.m_Nodes != null)
|
if (reader.serializedType?.m_Nodes != null)
|
||||||
{
|
{
|
||||||
|
@ -114,15 +113,15 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
str = ScriptHelper.GetScriptString(reader);
|
str = Studio.GetScriptString(reader);
|
||||||
}
|
}
|
||||||
File.WriteAllText(exportFullName, str);
|
File.WriteAllText(exportFullName, str);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportFont(ObjectReader reader, string exportPath)
|
public static bool ExportFont(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var m_Font = new Font(reader);
|
var m_Font = new Font(item.reader);
|
||||||
if (m_Font.m_FontData != null)
|
if (m_Font.m_FontData != null)
|
||||||
{
|
{
|
||||||
var extension = ".ttf";
|
var extension = ".ttf";
|
||||||
|
@ -130,7 +129,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
extension = ".otf";
|
extension = ".otf";
|
||||||
}
|
}
|
||||||
var exportFullName = exportPath + reader.exportName + extension;
|
var exportFullName = exportPath + item.Text + extension;
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
File.WriteAllBytes(exportFullName, m_Font.m_FontData);
|
File.WriteAllBytes(exportFullName, m_Font.m_FontData);
|
||||||
|
@ -139,12 +138,12 @@ namespace AssetStudio
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportMesh(ObjectReader reader, string exportPath)
|
public static bool ExportMesh(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var m_Mesh = new Mesh(reader);
|
var m_Mesh = new Mesh(item.reader);
|
||||||
if (m_Mesh.m_VertexCount <= 0)
|
if (m_Mesh.m_VertexCount <= 0)
|
||||||
return false;
|
return false;
|
||||||
var exportFullName = exportPath + reader.exportName + ".obj";
|
var exportFullName = exportPath + item.Text + ".obj";
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
@ -166,20 +165,20 @@ namespace AssetStudio
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region UV
|
#region UV
|
||||||
if (m_Mesh.m_UV1 != null && m_Mesh.m_UV1.Length == m_Mesh.m_VertexCount * 2)
|
if (m_Mesh.m_UV0 != null && m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 2)
|
||||||
|
{
|
||||||
|
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||||
|
{
|
||||||
|
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV0[v * 2], m_Mesh.m_UV0[v * 2 + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_Mesh.m_UV1 != null && m_Mesh.m_UV1.Length == m_Mesh.m_VertexCount * 2)
|
||||||
{
|
{
|
||||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||||
{
|
{
|
||||||
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV1[v * 2], m_Mesh.m_UV1[v * 2 + 1]);
|
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV1[v * 2], m_Mesh.m_UV1[v * 2 + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_Mesh.m_UV2 != null && m_Mesh.m_UV2.Length == m_Mesh.m_VertexCount * 2)
|
|
||||||
{
|
|
||||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
|
||||||
{
|
|
||||||
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV2[v * 2], m_Mesh.m_UV2[v * 2 + 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Normals
|
#region Normals
|
||||||
|
@ -220,12 +219,12 @@ namespace AssetStudio
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportVideoClip(ObjectReader reader, string exportPath)
|
public static bool ExportVideoClip(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var m_VideoClip = new VideoClip(reader, true);
|
var m_VideoClip = new VideoClip(item.reader, true);
|
||||||
if (m_VideoClip.m_VideoData != null)
|
if (m_VideoClip.m_VideoData != null)
|
||||||
{
|
{
|
||||||
var exportFullName = exportPath + reader.exportName + Path.GetExtension(m_VideoClip.m_OriginalPath);
|
var exportFullName = exportPath + item.Text + Path.GetExtension(m_VideoClip.m_OriginalPath);
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
File.WriteAllBytes(exportFullName, m_VideoClip.m_VideoData);
|
File.WriteAllBytes(exportFullName, m_VideoClip.m_VideoData);
|
||||||
|
@ -234,17 +233,17 @@ namespace AssetStudio
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportMovieTexture(ObjectReader reader, string exportPath)
|
public static bool ExportMovieTexture(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var m_MovieTexture = new MovieTexture(reader);
|
var m_MovieTexture = new MovieTexture(item.reader);
|
||||||
var exportFullName = exportPath + reader.exportName + ".ogv";
|
var exportFullName = exportPath + item.Text + ".ogv";
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
File.WriteAllBytes(exportFullName, m_MovieTexture.m_MovieData);
|
File.WriteAllBytes(exportFullName, m_MovieTexture.m_MovieData);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportSprite(ObjectReader reader, string exportPath)
|
public static bool ExportSprite(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
ImageFormat format = null;
|
ImageFormat format = null;
|
||||||
var type = (string)Properties.Settings.Default["convertType"];
|
var type = (string)Properties.Settings.Default["convertType"];
|
||||||
|
@ -260,10 +259,10 @@ namespace AssetStudio
|
||||||
format = ImageFormat.Jpeg;
|
format = ImageFormat.Jpeg;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var exportFullName = exportPath + reader.exportName + "." + type.ToLower();
|
var exportFullName = exportPath + item.Text + "." + type.ToLower();
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
var bitmap = SpriteHelper.GetImageFromSprite(new Sprite(reader));
|
var bitmap = SpriteHelper.GetImageFromSprite(new Sprite(item.reader));
|
||||||
if (bitmap != null)
|
if (bitmap != null)
|
||||||
{
|
{
|
||||||
bitmap.Save(exportFullName, format);
|
bitmap.Save(exportFullName, format);
|
||||||
|
@ -273,12 +272,12 @@ namespace AssetStudio
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportRawFile(ObjectReader reader, string exportPath)
|
public static bool ExportRawFile(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var exportFullName = exportPath + reader.exportName + ".dat";
|
var exportFullName = exportPath + item.Text + ".dat";
|
||||||
if (ExportFileExists(exportFullName))
|
if (ExportFileExists(exportFullName))
|
||||||
return false;
|
return false;
|
||||||
File.WriteAllBytes(exportFullName, reader.GetRawData());
|
File.WriteAllBytes(exportFullName, item.reader.GetRawData());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,22 +291,22 @@ namespace AssetStudio
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportAnimator(ObjectReader animator, string exportPath, List<AssetItem> animationList = null)
|
public static bool ExportAnimator(AssetItem item, string exportPath, List<AssetItem> animationList = null)
|
||||||
{
|
{
|
||||||
var m_Animator = new Animator(animator);
|
var m_Animator = new Animator(item.reader);
|
||||||
var convert = animationList != null ? new ModelConverter(m_Animator, animationList) : new ModelConverter(m_Animator);
|
var convert = animationList != null ? new ModelConverter(m_Animator, animationList.Select(x => x.reader).ToArray()) : new ModelConverter(m_Animator);
|
||||||
exportPath = exportPath + Studio.FixFileName(animator.exportName) + ".fbx";
|
exportPath = exportPath + item.Text + ".fbx";
|
||||||
return ModelConverter(convert, exportPath);
|
return ExportFbx(convert, exportPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
|
public static bool ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
|
||||||
{
|
{
|
||||||
var convert = animationList != null ? new ModelConverter(gameObject, animationList) : new ModelConverter(gameObject);
|
var convert = animationList != null ? new ModelConverter(gameObject, animationList.Select(x => x.reader).ToArray()) : new ModelConverter(gameObject);
|
||||||
exportPath = exportPath + Studio.FixFileName(gameObject.m_Name) + ".fbx";
|
exportPath = exportPath + Studio.FixFileName(gameObject.m_Name) + ".fbx";
|
||||||
return ModelConverter(convert, exportPath);
|
return ExportFbx(convert, exportPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ModelConverter(ModelConverter convert, string exportPath)
|
private static bool ExportFbx(IImported convert, string exportPath)
|
||||||
{
|
{
|
||||||
var eulerFilter = (bool)Properties.Settings.Default["eulerFilter"];
|
var eulerFilter = (bool)Properties.Settings.Default["eulerFilter"];
|
||||||
var filterPrecision = (float)(decimal)Properties.Settings.Default["filterPrecision"];
|
var filterPrecision = (float)(decimal)Properties.Settings.Default["filterPrecision"];
|
||||||
|
@ -319,7 +318,7 @@ namespace AssetStudio
|
||||||
var flatInbetween = (bool)Properties.Settings.Default["flatInbetween"];
|
var flatInbetween = (bool)Properties.Settings.Default["flatInbetween"];
|
||||||
var fbxVersion = (int)Properties.Settings.Default["fbxVersion"];
|
var fbxVersion = (int)Properties.Settings.Default["fbxVersion"];
|
||||||
var fbxFormat = (int)Properties.Settings.Default["fbxFormat"];
|
var fbxFormat = (int)Properties.Settings.Default["fbxFormat"];
|
||||||
Fbx.Exporter.Export(exportPath, convert, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, flatInbetween, fbxVersion, fbxFormat == 1);
|
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, flatInbetween, fbxVersion, fbxFormat == 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using AssetStudio;
|
||||||
|
|
||||||
|
namespace AssetStudioGUI
|
||||||
|
{
|
||||||
|
class GUILogger : ILogger
|
||||||
|
{
|
||||||
|
private Action<string> action;
|
||||||
|
|
||||||
|
public GUILogger(Action<string> action)
|
||||||
|
{
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(LoggerEvent loggerEvent, string message)
|
||||||
|
{
|
||||||
|
action(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
static class Program
|
static class Program
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
Application.EnableVisualStyles();
|
Application.EnableVisualStyles();
|
||||||
Application.SetCompatibleTextRenderingDefault(false);
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
Application.Run(new AssetStudioForm());
|
Application.Run(new AssetStudioGUIForm());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("AssetStudioGUI")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("AssetStudioGUI")]
|
||||||
|
[assembly: AssemblyCopyright("")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("05c04c20-dd89-4895-9f06-33d5cfbfe925")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -8,7 +8,7 @@
|
||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace AssetStudio.Properties {
|
namespace AssetStudioGUI.Properties {
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,16 +39,15 @@ namespace AssetStudio.Properties {
|
||||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
get {
|
get {
|
||||||
if (object.ReferenceEquals(resourceMan, null)) {
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AssetStudio.Properties.Resources", typeof(Resources).Assembly);
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AssetStudioGUI.Properties.Resources", typeof(Resources).Assembly);
|
||||||
resourceMan = temp;
|
resourceMan = temp;
|
||||||
}
|
}
|
||||||
return resourceMan;
|
return resourceMan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 使用此强类型资源类,为所有资源查找
|
/// 重写当前线程的 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 {
|
|
@ -8,11 +8,11 @@
|
||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace AssetStudio.Properties {
|
namespace AssetStudioGUI.Properties {
|
||||||
|
|
||||||
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.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())));
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AssetStudio.Properties" GeneratedClassName="Settings">
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AssetStudioGUI.Properties" GeneratedClassName="Settings">
|
||||||
<Profiles />
|
<Profiles />
|
||||||
<Settings>
|
<Settings>
|
||||||
<Setting Name="displayAll" Type="System.Boolean" Scope="User">
|
<Setting Name="displayAll" Type="System.Boolean" Scope="User">
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
|
@ -0,0 +1,711 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using AssetStudio;
|
||||||
|
using dnlib.DotNet;
|
||||||
|
using static AssetStudioGUI.Exporter;
|
||||||
|
|
||||||
|
namespace AssetStudioGUI
|
||||||
|
{
|
||||||
|
internal static class Studio
|
||||||
|
{
|
||||||
|
public static AssetsManager assetsManager = new AssetsManager();
|
||||||
|
private static HashSet<string> assetsNameHash = new HashSet<string>();
|
||||||
|
public static List<AssetItem> exportableAssets = new List<AssetItem>();
|
||||||
|
public static List<AssetItem> visibleAssets = new List<AssetItem>();
|
||||||
|
public static Dictionary<string, SortedDictionary<int, TypeTreeItem>> AllTypeMap = new Dictionary<string, SortedDictionary<int, TypeTreeItem>>();
|
||||||
|
public static Dictionary<GameObject, GameObjectTreeNode> treeNodeDictionary = new Dictionary<GameObject, GameObjectTreeNode>();
|
||||||
|
public static bool ModuleLoaded;
|
||||||
|
public static Dictionary<string, ModuleDef> LoadedModuleDic = new Dictionary<string, ModuleDef>();
|
||||||
|
|
||||||
|
public static void ExtractFile(string[] fileNames)
|
||||||
|
{
|
||||||
|
ThreadPool.QueueUserWorkItem(state =>
|
||||||
|
{
|
||||||
|
int extractedCount = 0;
|
||||||
|
Progress.Reset();
|
||||||
|
for (var i = 0; i < fileNames.Length; i++)
|
||||||
|
{
|
||||||
|
var fileName = fileNames[i];
|
||||||
|
var type = ImportHelper.CheckFileType(fileName, out var reader);
|
||||||
|
if (type == FileType.BundleFile)
|
||||||
|
extractedCount += ExtractBundleFile(fileName, reader);
|
||||||
|
else if (type == FileType.WebFile)
|
||||||
|
extractedCount += ExtractWebDataFile(fileName, reader);
|
||||||
|
else
|
||||||
|
reader.Dispose();
|
||||||
|
Progress.Report(i + 1, fileName.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info($"Finished extracting {extractedCount} files.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ExtractBundleFile(string bundleFileName, EndianBinaryReader reader)
|
||||||
|
{
|
||||||
|
Logger.Info($"Decompressing {Path.GetFileName(bundleFileName)} ...");
|
||||||
|
var bundleFile = new BundleFile(reader, bundleFileName);
|
||||||
|
reader.Dispose();
|
||||||
|
if (bundleFile.fileList.Count > 0)
|
||||||
|
{
|
||||||
|
var extractPath = bundleFileName + "_unpacked\\";
|
||||||
|
Directory.CreateDirectory(extractPath);
|
||||||
|
return ExtractStreamFile(extractPath, bundleFile.fileList);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ExtractWebDataFile(string webFileName, EndianBinaryReader reader)
|
||||||
|
{
|
||||||
|
Logger.Info($"Decompressing {Path.GetFileName(webFileName)} ...");
|
||||||
|
var webFile = new WebFile(reader);
|
||||||
|
reader.Dispose();
|
||||||
|
if (webFile.fileList.Count > 0)
|
||||||
|
{
|
||||||
|
var extractPath = webFileName + "_unpacked\\";
|
||||||
|
Directory.CreateDirectory(extractPath);
|
||||||
|
return ExtractStreamFile(extractPath, webFile.fileList);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ExtractStreamFile(string extractPath, List<StreamFile> fileList)
|
||||||
|
{
|
||||||
|
int extractedCount = 0;
|
||||||
|
foreach (var file in fileList)
|
||||||
|
{
|
||||||
|
var filePath = extractPath + file.fileName;
|
||||||
|
if (!Directory.Exists(extractPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(extractPath);
|
||||||
|
}
|
||||||
|
if (!File.Exists(filePath) && file.stream is MemoryStream stream)
|
||||||
|
{
|
||||||
|
File.WriteAllBytes(filePath, stream.ToArray());
|
||||||
|
extractedCount += 1;
|
||||||
|
}
|
||||||
|
file.stream.Dispose();
|
||||||
|
}
|
||||||
|
return extractedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BuildAssetList(Dictionary<ObjectReader, AssetItem> tempDic, bool displayAll, bool displayOriginalName, out string productName)
|
||||||
|
{
|
||||||
|
productName = string.Empty;
|
||||||
|
Logger.Info("Building asset list...");
|
||||||
|
|
||||||
|
var progressCount = assetsManager.assetsFileList.Sum(x => x.ObjectReaders.Count);
|
||||||
|
int j = 0;
|
||||||
|
Progress.Reset();
|
||||||
|
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||||
|
{
|
||||||
|
var tempExportableAssets = new List<AssetItem>();
|
||||||
|
AssetBundle ab = null;
|
||||||
|
foreach (var objectReader in assetsFile.ObjectReaders.Values)
|
||||||
|
{
|
||||||
|
var assetItem = new AssetItem(objectReader);
|
||||||
|
tempDic.Add(objectReader, assetItem);
|
||||||
|
assetItem.UniqueID = " #" + j;
|
||||||
|
var exportable = false;
|
||||||
|
switch (assetItem.Type)
|
||||||
|
{
|
||||||
|
case ClassIDType.GameObject:
|
||||||
|
{
|
||||||
|
var m_GameObject = new GameObject(objectReader);
|
||||||
|
assetItem.Text = m_GameObject.m_Name;
|
||||||
|
assetsFile.GameObjects.Add(objectReader.m_PathID, m_GameObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.Transform:
|
||||||
|
{
|
||||||
|
var m_Transform = new Transform(objectReader);
|
||||||
|
assetsFile.Transforms.Add(objectReader.m_PathID, m_Transform);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.RectTransform:
|
||||||
|
{
|
||||||
|
var m_Rect = new RectTransform(objectReader);
|
||||||
|
assetsFile.Transforms.Add(objectReader.m_PathID, m_Rect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.Texture2D:
|
||||||
|
{
|
||||||
|
var m_Texture2D = new Texture2D(objectReader, false);
|
||||||
|
if (!string.IsNullOrEmpty(m_Texture2D.path))
|
||||||
|
assetItem.FullSize = objectReader.byteSize + m_Texture2D.size;
|
||||||
|
assetItem.Text = m_Texture2D.m_Name;
|
||||||
|
exportable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.AudioClip:
|
||||||
|
{
|
||||||
|
var m_AudioClip = new AudioClip(objectReader, false);
|
||||||
|
if (!string.IsNullOrEmpty(m_AudioClip.m_Source))
|
||||||
|
assetItem.FullSize = objectReader.byteSize + m_AudioClip.m_Size;
|
||||||
|
assetItem.Text = m_AudioClip.m_Name;
|
||||||
|
exportable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.VideoClip:
|
||||||
|
{
|
||||||
|
var m_VideoClip = new VideoClip(objectReader, false);
|
||||||
|
if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath))
|
||||||
|
assetItem.FullSize = objectReader.byteSize + (long)m_VideoClip.m_Size;
|
||||||
|
assetItem.Text = m_VideoClip.m_Name;
|
||||||
|
exportable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.Shader:
|
||||||
|
{
|
||||||
|
var m_Shader = new Shader(objectReader);
|
||||||
|
assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
|
||||||
|
exportable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.Mesh:
|
||||||
|
case ClassIDType.TextAsset:
|
||||||
|
case ClassIDType.AnimationClip:
|
||||||
|
case ClassIDType.Font:
|
||||||
|
case ClassIDType.MovieTexture:
|
||||||
|
case ClassIDType.Sprite:
|
||||||
|
{
|
||||||
|
var obj = new NamedObject(objectReader);
|
||||||
|
assetItem.Text = obj.m_Name;
|
||||||
|
exportable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.Avatar:
|
||||||
|
case ClassIDType.AnimatorController:
|
||||||
|
case ClassIDType.AnimatorOverrideController:
|
||||||
|
case ClassIDType.Material:
|
||||||
|
case ClassIDType.MonoScript:
|
||||||
|
case ClassIDType.SpriteAtlas:
|
||||||
|
{
|
||||||
|
var obj = new NamedObject(objectReader);
|
||||||
|
assetItem.Text = obj.m_Name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.Animator:
|
||||||
|
{
|
||||||
|
exportable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.MonoBehaviour:
|
||||||
|
{
|
||||||
|
var m_MonoBehaviour = new MonoBehaviour(objectReader);
|
||||||
|
if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var script))
|
||||||
|
{
|
||||||
|
var m_Script = new MonoScript(script);
|
||||||
|
assetItem.Text = m_Script.m_ClassName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assetItem.Text = m_MonoBehaviour.m_Name;
|
||||||
|
}
|
||||||
|
exportable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.PlayerSettings:
|
||||||
|
{
|
||||||
|
var plSet = new PlayerSettings(objectReader);
|
||||||
|
productName = plSet.productName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.AssetBundle:
|
||||||
|
{
|
||||||
|
ab = new AssetBundle(objectReader);
|
||||||
|
assetItem.Text = ab.m_Name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (assetItem.Text == "")
|
||||||
|
{
|
||||||
|
assetItem.Text = assetItem.TypeString + assetItem.UniqueID;
|
||||||
|
}
|
||||||
|
assetItem.SubItems.AddRange(new[] { assetItem.TypeString, assetItem.FullSize.ToString() });
|
||||||
|
//处理同名文件
|
||||||
|
if (!assetsNameHash.Add((assetItem.TypeString + assetItem.Text).ToUpper()))
|
||||||
|
{
|
||||||
|
assetItem.Text += assetItem.UniqueID;
|
||||||
|
}
|
||||||
|
//处理非法文件名
|
||||||
|
assetItem.Text = FixFileName(assetItem.Text);
|
||||||
|
if (displayAll)
|
||||||
|
{
|
||||||
|
exportable = true;
|
||||||
|
}
|
||||||
|
if (exportable)
|
||||||
|
{
|
||||||
|
tempExportableAssets.Add(assetItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
Progress.Report(++j, progressCount);
|
||||||
|
}
|
||||||
|
if (displayOriginalName && ab != null)
|
||||||
|
{
|
||||||
|
foreach (var x in tempExportableAssets)
|
||||||
|
{
|
||||||
|
var replacename = ab.m_Container.Find(y => y.second.asset.m_PathID == x.reader.m_PathID)?.first;
|
||||||
|
if (!string.IsNullOrEmpty(replacename))
|
||||||
|
{
|
||||||
|
var ex = Path.GetExtension(replacename);
|
||||||
|
x.Text = !string.IsNullOrEmpty(ex) ? replacename.Replace(ex, "") : replacename;
|
||||||
|
if (!assetsNameHash.Add((x.TypeString + x.Text).ToUpper()))
|
||||||
|
{
|
||||||
|
x.Text = Path.GetDirectoryName(replacename) + "\\" + Path.GetFileNameWithoutExtension(replacename) + x.UniqueID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exportableAssets.AddRange(tempExportableAssets);
|
||||||
|
tempExportableAssets.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
visibleAssets = exportableAssets;
|
||||||
|
assetsNameHash.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<GameObjectTreeNode> BuildTreeStructure(Dictionary<ObjectReader, AssetItem> tempDic)
|
||||||
|
{
|
||||||
|
var treeNodeCollection = new List<GameObjectTreeNode>();
|
||||||
|
var gameObjectCount = assetsManager.assetsFileList.Sum(x => x.GameObjects.Count);
|
||||||
|
if (gameObjectCount > 0)
|
||||||
|
{
|
||||||
|
Logger.Info("Building tree structure...");
|
||||||
|
int i = 0;
|
||||||
|
Progress.Reset();
|
||||||
|
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||||
|
{
|
||||||
|
var fileNode = new GameObjectTreeNode(assetsFile.fileName); //RootNode
|
||||||
|
|
||||||
|
foreach (var m_GameObject in assetsFile.GameObjects.Values)
|
||||||
|
{
|
||||||
|
foreach (var m_Component in m_GameObject.m_Components)
|
||||||
|
{
|
||||||
|
if (m_Component.TryGet(out var asset))
|
||||||
|
{
|
||||||
|
switch (asset.type)
|
||||||
|
{
|
||||||
|
case ClassIDType.Transform:
|
||||||
|
{
|
||||||
|
m_GameObject.m_Transform = m_Component;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.MeshRenderer:
|
||||||
|
{
|
||||||
|
m_GameObject.m_MeshRenderer = m_Component;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.MeshFilter:
|
||||||
|
{
|
||||||
|
m_GameObject.m_MeshFilter = m_Component;
|
||||||
|
if (m_Component.TryGet(out var objectReader))
|
||||||
|
{
|
||||||
|
var m_MeshFilter = new MeshFilter(objectReader);
|
||||||
|
if (m_MeshFilter.m_Mesh.TryGet(out objectReader))
|
||||||
|
{
|
||||||
|
var item = tempDic[objectReader];
|
||||||
|
item.gameObject = m_GameObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.SkinnedMeshRenderer:
|
||||||
|
{
|
||||||
|
m_GameObject.m_SkinnedMeshRenderer = m_Component;
|
||||||
|
if (m_Component.TryGet(out var objectReader))
|
||||||
|
{
|
||||||
|
var m_SkinnedMeshRenderer = new SkinnedMeshRenderer(objectReader);
|
||||||
|
if (m_SkinnedMeshRenderer.m_Mesh.TryGet(out objectReader))
|
||||||
|
{
|
||||||
|
var item = tempDic[objectReader];
|
||||||
|
item.gameObject = m_GameObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ClassIDType.Animator:
|
||||||
|
{
|
||||||
|
m_GameObject.m_Animator = m_Component;
|
||||||
|
var item = tempDic[asset];
|
||||||
|
item.Text = tempDic[m_GameObject.reader].Text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var parentNode = fileNode;
|
||||||
|
|
||||||
|
if (m_GameObject.m_Transform != null && m_GameObject.m_Transform.TryGetTransform(out var m_Transform))
|
||||||
|
{
|
||||||
|
if (m_Transform.m_Father.TryGetTransform(out var m_Father))
|
||||||
|
{
|
||||||
|
if (m_Father.m_GameObject.TryGetGameObject(out var parentGameObject))
|
||||||
|
{
|
||||||
|
if (!treeNodeDictionary.TryGetValue(parentGameObject, out parentNode))
|
||||||
|
{
|
||||||
|
parentNode = new GameObjectTreeNode(parentGameObject);
|
||||||
|
treeNodeDictionary.Add(parentGameObject, parentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!treeNodeDictionary.TryGetValue(m_GameObject, out var currentNode))
|
||||||
|
{
|
||||||
|
currentNode = new GameObjectTreeNode(m_GameObject);
|
||||||
|
treeNodeDictionary.Add(m_GameObject, currentNode);
|
||||||
|
}
|
||||||
|
parentNode.Nodes.Add(currentNode);
|
||||||
|
|
||||||
|
Progress.Report(++i, gameObjectCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileNode.Nodes.Count > 0)
|
||||||
|
{
|
||||||
|
treeNodeCollection.Add(fileNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return treeNodeCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BuildClassStructure()
|
||||||
|
{
|
||||||
|
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||||
|
{
|
||||||
|
if (AllTypeMap.TryGetValue(assetsFile.unityVersion, out var curVer))
|
||||||
|
{
|
||||||
|
foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null))
|
||||||
|
{
|
||||||
|
var key = type.classID;
|
||||||
|
if (type.m_ScriptTypeIndex >= 0)
|
||||||
|
{
|
||||||
|
key = -1 - type.m_ScriptTypeIndex;
|
||||||
|
}
|
||||||
|
curVer[key] = new TypeTreeItem(key, type.m_Nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var items = new SortedDictionary<int, TypeTreeItem>();
|
||||||
|
foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null))
|
||||||
|
{
|
||||||
|
var key = type.classID;
|
||||||
|
if (type.m_ScriptTypeIndex >= 0)
|
||||||
|
{
|
||||||
|
key = -1 - type.m_ScriptTypeIndex;
|
||||||
|
}
|
||||||
|
items.Add(key, new TypeTreeItem(key, type.m_Nodes));
|
||||||
|
}
|
||||||
|
AllTypeMap.Add(assetsFile.unityVersion, items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FixFileName(string str)
|
||||||
|
{
|
||||||
|
if (str.Length >= 260) return Path.GetRandomFileName();
|
||||||
|
return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ExportAssets(string savePath, List<AssetItem> toExportAssets, int assetGroupSelectedIndex, bool openAfterExport)
|
||||||
|
{
|
||||||
|
ThreadPool.QueueUserWorkItem(state =>
|
||||||
|
{
|
||||||
|
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
|
int toExportCount = toExportAssets.Count;
|
||||||
|
int exportedCount = 0;
|
||||||
|
int i = 0;
|
||||||
|
Progress.Reset();
|
||||||
|
foreach (var asset in toExportAssets)
|
||||||
|
{
|
||||||
|
var exportpath = savePath + "\\";
|
||||||
|
if (assetGroupSelectedIndex == 1)
|
||||||
|
{
|
||||||
|
exportpath += Path.GetFileNameWithoutExtension(asset.sourceFile.fullName) + "_export\\";
|
||||||
|
}
|
||||||
|
else if (assetGroupSelectedIndex == 0)
|
||||||
|
{
|
||||||
|
exportpath = savePath + "\\" + asset.TypeString + "\\";
|
||||||
|
}
|
||||||
|
Logger.Info($"Exporting {asset.TypeString}: {asset.Text}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (asset.Type)
|
||||||
|
{
|
||||||
|
case ClassIDType.Texture2D:
|
||||||
|
if (ExportTexture2D(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.AudioClip:
|
||||||
|
if (ExportAudioClip(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.Shader:
|
||||||
|
if (ExportShader(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.TextAsset:
|
||||||
|
if (ExportTextAsset(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.MonoBehaviour:
|
||||||
|
if (ExportMonoBehaviour(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.Font:
|
||||||
|
if (ExportFont(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.Mesh:
|
||||||
|
if (ExportMesh(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.VideoClip:
|
||||||
|
if (ExportVideoClip(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.MovieTexture:
|
||||||
|
if (ExportMovieTexture(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.Sprite:
|
||||||
|
if (ExportSprite(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.Animator:
|
||||||
|
if (ExportAnimator(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClassIDType.AnimationClip:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (ExportRawFile(asset, exportpath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Export {asset.Type}:{asset.Text} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Progress.Report(++i, toExportCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
var statusText = exportedCount == 0 ? "Nothing exported." : $"Finished exporting {exportedCount} assets.";
|
||||||
|
|
||||||
|
if (toExportCount > exportedCount)
|
||||||
|
{
|
||||||
|
statusText += $" {toExportCount - exportedCount} assets skipped (not extractable or files already exist)";
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info(statusText);
|
||||||
|
|
||||||
|
if (openAfterExport && exportedCount > 0)
|
||||||
|
{
|
||||||
|
Process.Start(savePath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ExportSplitObjects(string savePath, TreeNodeCollection nodes)
|
||||||
|
{
|
||||||
|
ThreadPool.QueueUserWorkItem(state =>
|
||||||
|
{
|
||||||
|
var count = nodes.Cast<TreeNode>().Sum(x => x.Nodes.Count);
|
||||||
|
int k = 0;
|
||||||
|
Progress.Reset();
|
||||||
|
foreach (GameObjectTreeNode node in nodes)
|
||||||
|
{
|
||||||
|
//遍历一级子节点
|
||||||
|
foreach (GameObjectTreeNode j in node.Nodes)
|
||||||
|
{
|
||||||
|
//收集所有子节点
|
||||||
|
var gameObjects = new List<GameObject>();
|
||||||
|
CollectNode(j, gameObjects);
|
||||||
|
//跳过一些不需要导出的object
|
||||||
|
if (gameObjects.All(x => x.m_SkinnedMeshRenderer == null && x.m_MeshFilter == null))
|
||||||
|
continue;
|
||||||
|
//处理非法文件名
|
||||||
|
var filename = FixFileName(j.Text);
|
||||||
|
//每个文件存放在单独的文件夹
|
||||||
|
var targetPath = $"{savePath}{filename}\\";
|
||||||
|
//重名文件处理
|
||||||
|
for (int i = 1; ; i++)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(targetPath))
|
||||||
|
{
|
||||||
|
targetPath = $"{savePath}{filename} ({i})\\";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Directory.CreateDirectory(targetPath);
|
||||||
|
//导出FBX
|
||||||
|
Logger.Info($"Exporting {filename}.fbx");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ExportGameObject(j.gameObject, targetPath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Progress.Report(++k, count);
|
||||||
|
Logger.Info($"Finished exporting {filename}.fbx");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Logger.Info("Finished");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CollectNode(GameObjectTreeNode node, List<GameObject> gameObjects)
|
||||||
|
{
|
||||||
|
gameObjects.Add(node.gameObject);
|
||||||
|
foreach (GameObjectTreeNode i in node.Nodes)
|
||||||
|
{
|
||||||
|
CollectNode(i, gameObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ExportAnimatorWithAnimationClip(AssetItem animator, List<AssetItem> animationList, string exportPath)
|
||||||
|
{
|
||||||
|
ThreadPool.QueueUserWorkItem(state =>
|
||||||
|
{
|
||||||
|
Logger.Info($"Exporting {animator.Text}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ExportAnimator(animator, exportPath, animationList);
|
||||||
|
Logger.Info($"Finished exporting {animator.Text}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}");
|
||||||
|
Logger.Info("Error in export");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ExportObjectsWithAnimationClip(string exportPath, TreeNodeCollection nodes, List<AssetItem> animationList = null)
|
||||||
|
{
|
||||||
|
ThreadPool.QueueUserWorkItem(state =>
|
||||||
|
{
|
||||||
|
var gameObjects = new List<GameObject>();
|
||||||
|
GetSelectedParentNode(nodes, gameObjects);
|
||||||
|
if (gameObjects.Count > 0)
|
||||||
|
{
|
||||||
|
var count = gameObjects.Count;
|
||||||
|
int i = 0;
|
||||||
|
Progress.Reset();
|
||||||
|
foreach (var gameObject in gameObjects)
|
||||||
|
{
|
||||||
|
Logger.Info($"Exporting {gameObject.m_Name}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ExportGameObject(gameObject, exportPath, animationList);
|
||||||
|
Logger.Info($"Finished exporting {gameObject.m_Name}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}");
|
||||||
|
Logger.Info("Error in export");
|
||||||
|
}
|
||||||
|
|
||||||
|
Progress.Report(++i, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Info("No Object can be exported.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GetSelectedParentNode(TreeNodeCollection nodes, List<GameObject> gameObjects)
|
||||||
|
{
|
||||||
|
foreach (GameObjectTreeNode i in nodes)
|
||||||
|
{
|
||||||
|
if (i.Checked)
|
||||||
|
{
|
||||||
|
gameObjects.Add(i.gameObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetSelectedParentNode(i.Nodes, gameObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetScriptString(ObjectReader reader)
|
||||||
|
{
|
||||||
|
if (!ModuleLoaded)
|
||||||
|
{
|
||||||
|
var openFolderDialog = new OpenFolderDialog();
|
||||||
|
openFolderDialog.Title = "Select Assembly Folder";
|
||||||
|
if (openFolderDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
var files = Directory.GetFiles(openFolderDialog.Folder, "*.dll");
|
||||||
|
var moduleContext = new ModuleContext();
|
||||||
|
var asmResolver = new AssemblyResolver(moduleContext, true);
|
||||||
|
var resolver = new Resolver(asmResolver);
|
||||||
|
moduleContext.AssemblyResolver = asmResolver;
|
||||||
|
moduleContext.Resolver = resolver;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
var module = ModuleDefMD.Load(file, moduleContext);
|
||||||
|
LoadedModuleDic.Add(Path.GetFileName(file), module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ScriptHelper.GetScriptString(reader, LoadedModuleDic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?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>
|
||||||
|
<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="displayOriginalName" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="eulerFilter" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="filterPrecision" serializeAs="String">
|
||||||
|
<value>0.25</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="allFrames" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="allBones" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="skins" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="boneSize" serializeAs="String">
|
||||||
|
<value>10</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="flatInbetween" serializeAs="String">
|
||||||
|
<value>False</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>
|
||||||
|
</AssetStudioGUI.Properties.Settings>
|
||||||
|
</userSettings>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,101 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>AssetStudio</RootNamespace>
|
||||||
|
<AssemblyName>AssetStudioTools</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<OutputPath>bin\x86\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="dnlib">
|
||||||
|
<HintPath>..\AssetStudio\Libraries\dnlib.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="SharpDX, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\AssetStudio\Libraries\SharpDX.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="SharpDX.D3DCompiler">
|
||||||
|
<HintPath>..\AssetStudio\Libraries\SharpDX.D3DCompiler.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="SharpDX.Mathematics">
|
||||||
|
<HintPath>..\AssetStudio\Libraries\SharpDX.Mathematics.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Half">
|
||||||
|
<HintPath>..\AssetStudio\Libraries\System.Half.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="AudioClipConverter.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="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="ScriptHelper.cs" />
|
||||||
|
<Compile Include="ShaderConverter.cs" />
|
||||||
|
<Compile Include="SpriteHelper.cs" />
|
||||||
|
<Compile Include="Texture2DConverter.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\AssetStudioFBX\AssetStudioFBX.vcxproj">
|
||||||
|
<Project>{4f8ef5ef-732b-49cf-9eb3-b23e19ae6267}</Project>
|
||||||
|
<Name>AssetStudioFBX</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
|
||||||
|
<Project>{af56b63c-1764-41b7-9e60-8d485422ac3b}</Project>
|
||||||
|
<Name>AssetStudio</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
|
@ -1,6 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
@ -32,13 +30,13 @@ namespace AssetStudio
|
||||||
result = sound.getSubSound(0, out var subsound);
|
result = sound.getSubSound(0, out var subsound);
|
||||||
if (result != FMOD.RESULT.OK)
|
if (result != FMOD.RESULT.OK)
|
||||||
return null;
|
return null;
|
||||||
result = subsound.getFormat(out var type, out var format, out int NumChannels, out int BitsPerSample);
|
result = subsound.getFormat(out var type, out var format, out int channels, out int bits);
|
||||||
if (result != FMOD.RESULT.OK)
|
if (result != FMOD.RESULT.OK)
|
||||||
return null;
|
return null;
|
||||||
result = subsound.getDefaults(out var frequency, out int priority);
|
result = subsound.getDefaults(out var frequency, out int priority);
|
||||||
if (result != FMOD.RESULT.OK)
|
if (result != FMOD.RESULT.OK)
|
||||||
return null;
|
return null;
|
||||||
var SampleRate = (int)frequency;
|
var sampleRate = (int)frequency;
|
||||||
result = subsound.getLength(out var length, FMOD.TIMEUNIT.PCMBYTES);
|
result = subsound.getLength(out var length, FMOD.TIMEUNIT.PCMBYTES);
|
||||||
if (result != FMOD.RESULT.OK)
|
if (result != FMOD.RESULT.OK)
|
||||||
return null;
|
return null;
|
||||||
|
@ -52,11 +50,11 @@ namespace AssetStudio
|
||||||
Encoding.UTF8.GetBytes("WAVEfmt ").CopyTo(buffer, 8);
|
Encoding.UTF8.GetBytes("WAVEfmt ").CopyTo(buffer, 8);
|
||||||
BitConverter.GetBytes(16).CopyTo(buffer, 16);
|
BitConverter.GetBytes(16).CopyTo(buffer, 16);
|
||||||
BitConverter.GetBytes((short)1).CopyTo(buffer, 20);
|
BitConverter.GetBytes((short)1).CopyTo(buffer, 20);
|
||||||
BitConverter.GetBytes((short)NumChannels).CopyTo(buffer, 22);
|
BitConverter.GetBytes((short)channels).CopyTo(buffer, 22);
|
||||||
BitConverter.GetBytes(SampleRate).CopyTo(buffer, 24);
|
BitConverter.GetBytes(sampleRate).CopyTo(buffer, 24);
|
||||||
BitConverter.GetBytes(SampleRate * NumChannels * BitsPerSample / 8).CopyTo(buffer, 28);
|
BitConverter.GetBytes(sampleRate * channels * bits / 8).CopyTo(buffer, 28);
|
||||||
BitConverter.GetBytes((short)(NumChannels * BitsPerSample / 8)).CopyTo(buffer, 32);
|
BitConverter.GetBytes((short)(channels * bits / 8)).CopyTo(buffer, 32);
|
||||||
BitConverter.GetBytes((short)BitsPerSample).CopyTo(buffer, 34);
|
BitConverter.GetBytes((short)bits).CopyTo(buffer, 34);
|
||||||
Encoding.UTF8.GetBytes("data").CopyTo(buffer, 36);
|
Encoding.UTF8.GetBytes("data").CopyTo(buffer, 36);
|
||||||
BitConverter.GetBytes(len1).CopyTo(buffer, 40);
|
BitConverter.GetBytes(len1).CopyTo(buffer, 40);
|
||||||
Marshal.Copy(ptr1, buffer, 44, (int)len1);
|
Marshal.Copy(ptr1, buffer, 44, (int)len1);
|
|
@ -8,7 +8,7 @@ using SharpDX;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
class ModelConverter : IImported
|
public class ModelConverter : IImported
|
||||||
{
|
{
|
||||||
public List<ImportedFrame> FrameList { get; protected set; } = new List<ImportedFrame>();
|
public List<ImportedFrame> FrameList { get; protected set; } = new List<ImportedFrame>();
|
||||||
public List<ImportedMesh> MeshList { get; protected set; } = new List<ImportedMesh>();
|
public List<ImportedMesh> MeshList { get; protected set; } = new List<ImportedMesh>();
|
||||||
|
@ -21,6 +21,7 @@ namespace AssetStudio
|
||||||
private Dictionary<uint, string> morphChannelInfo = new Dictionary<uint, string>();
|
private Dictionary<uint, string> morphChannelInfo = new Dictionary<uint, string>();
|
||||||
private HashSet<ObjectReader> animationClipHashSet = new HashSet<ObjectReader>();
|
private HashSet<ObjectReader> animationClipHashSet = new HashSet<ObjectReader>();
|
||||||
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
|
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
|
||||||
|
private Dictionary<ObjectReader, string> textureNameDictionary = new Dictionary<ObjectReader, string>();
|
||||||
|
|
||||||
public ModelConverter(GameObject m_GameObject)
|
public ModelConverter(GameObject m_GameObject)
|
||||||
{
|
{
|
||||||
|
@ -35,7 +36,7 @@ namespace AssetStudio
|
||||||
ConvertAnimations();
|
ConvertAnimations();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModelConverter(GameObject m_GameObject, List<AssetItem> animationList)
|
public ModelConverter(GameObject m_GameObject, ObjectReader[] animationList)
|
||||||
{
|
{
|
||||||
if (m_GameObject.m_Animator != null && m_GameObject.m_Animator.TryGet(out var m_Animator))
|
if (m_GameObject.m_Animator != null && m_GameObject.m_Animator.TryGet(out var m_Animator))
|
||||||
{
|
{
|
||||||
|
@ -44,9 +45,9 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
InitWithGameObject(m_GameObject);
|
InitWithGameObject(m_GameObject);
|
||||||
foreach (var assetPreloadData in animationList)
|
foreach (var animationClip in animationList)
|
||||||
{
|
{
|
||||||
animationClipHashSet.Add(assetPreloadData.reader);
|
animationClipHashSet.Add(animationClip);
|
||||||
}
|
}
|
||||||
ConvertAnimations();
|
ConvertAnimations();
|
||||||
}
|
}
|
||||||
|
@ -58,12 +59,12 @@ namespace AssetStudio
|
||||||
ConvertAnimations();
|
ConvertAnimations();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModelConverter(Animator m_Animator, List<AssetItem> animationList)
|
public ModelConverter(Animator m_Animator, ObjectReader[] animationList)
|
||||||
{
|
{
|
||||||
InitWithAnimator(m_Animator);
|
InitWithAnimator(m_Animator);
|
||||||
foreach (var assetPreloadData in animationList)
|
foreach (var animationClip in animationList)
|
||||||
{
|
{
|
||||||
animationClipHashSet.Add(assetPreloadData.reader);
|
animationClipHashSet.Add(animationClip);
|
||||||
}
|
}
|
||||||
ConvertAnimations();
|
ConvertAnimations();
|
||||||
}
|
}
|
||||||
|
@ -338,14 +339,14 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//UV
|
//UV
|
||||||
if (mesh.m_UV1 != null && mesh.m_UV1.Length == mesh.m_VertexCount * 2)
|
if (mesh.m_UV0 != null && mesh.m_UV0.Length == mesh.m_VertexCount * 2)
|
||||||
|
{
|
||||||
|
iVertex.UV = new[] { mesh.m_UV0[j * 2], -mesh.m_UV0[j * 2 + 1] };
|
||||||
|
}
|
||||||
|
else if (mesh.m_UV1 != null && mesh.m_UV1.Length == mesh.m_VertexCount * 2)
|
||||||
{
|
{
|
||||||
iVertex.UV = new[] { mesh.m_UV1[j * 2], -mesh.m_UV1[j * 2 + 1] };
|
iVertex.UV = new[] { mesh.m_UV1[j * 2], -mesh.m_UV1[j * 2 + 1] };
|
||||||
}
|
}
|
||||||
else if (mesh.m_UV2 != null && mesh.m_UV2.Length == mesh.m_VertexCount * 2)
|
|
||||||
{
|
|
||||||
iVertex.UV = new[] { mesh.m_UV2[j * 2], -mesh.m_UV2[j * 2 + 1] };
|
|
||||||
}
|
|
||||||
//Tangent
|
//Tangent
|
||||||
if (mesh.m_Tangents != null && mesh.m_Tangents.Length == mesh.m_VertexCount * 4)
|
if (mesh.m_Tangents != null && mesh.m_Tangents.Length == mesh.m_VertexCount * 4)
|
||||||
{
|
{
|
||||||
|
@ -534,7 +535,7 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO
|
//TODO combine mesh
|
||||||
if (combine)
|
if (combine)
|
||||||
{
|
{
|
||||||
meshR.m_GameObject.TryGetGameObject(out var m_GameObject);
|
meshR.m_GameObject.TryGetGameObject(out var m_GameObject);
|
||||||
|
@ -673,25 +674,55 @@ namespace AssetStudio
|
||||||
iMat.TexScales = new Vector2[5];
|
iMat.TexScales = new Vector2[5];
|
||||||
foreach (var texEnv in mat.m_TexEnvs)
|
foreach (var texEnv in mat.m_TexEnvs)
|
||||||
{
|
{
|
||||||
Texture2D tex2D = null;
|
Texture2D m_Texture2D = null;
|
||||||
if (texEnv.m_Texture.TryGet(out var TexturePD) && TexturePD.type == ClassIDType.Texture2D)//TODO other Texture
|
if (texEnv.m_Texture.TryGet(out var m_Texture) && m_Texture.type == ClassIDType.Texture2D) //TODO other Texture
|
||||||
{
|
{
|
||||||
tex2D = new Texture2D(TexturePD, true);
|
m_Texture2D = new Texture2D(m_Texture, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tex2D == null)
|
if (m_Texture2D == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int dest = texEnv.name == "_MainTex" ? 0 : texEnv.name == "_BumpMap" ? 4 : texEnv.name.Contains("Spec") ? 2 : texEnv.name.Contains("Norm") ? 3 : -1;
|
int dest = -1;
|
||||||
|
if (texEnv.name == "_MainTex")
|
||||||
|
dest = 0;
|
||||||
|
else if (texEnv.name == "_BumpMap")
|
||||||
|
dest = 4;
|
||||||
|
else if (texEnv.name.Contains("Spec"))
|
||||||
|
dest = 2;
|
||||||
|
else if (texEnv.name.Contains("Norm"))
|
||||||
|
dest = 3;
|
||||||
if (dest < 0 || iMat.Textures[dest] != null)
|
if (dest < 0 || iMat.Textures[dest] != null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
iMat.Textures[dest] = TexturePD.exportName + ".png";
|
|
||||||
|
if (textureNameDictionary.TryGetValue(m_Texture, out var textureName))
|
||||||
|
{
|
||||||
|
iMat.Textures[dest] = textureName;
|
||||||
|
}
|
||||||
|
else if (ImportedHelpers.FindTexture(m_Texture2D.m_Name + ".png", TextureList) != null) //已有相同名字的图片
|
||||||
|
{
|
||||||
|
for (int i = 1; ; i++)
|
||||||
|
{
|
||||||
|
var name = m_Texture2D.m_Name + $" ({i}).png";
|
||||||
|
if (ImportedHelpers.FindTexture(name, TextureList) == null)
|
||||||
|
{
|
||||||
|
iMat.Textures[dest] = name;
|
||||||
|
textureNameDictionary.Add(m_Texture, name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iMat.Textures[dest] = m_Texture2D.m_Name + ".png";
|
||||||
|
textureNameDictionary.Add(m_Texture, iMat.Textures[dest]);
|
||||||
|
}
|
||||||
iMat.TexOffsets[dest] = new Vector2(texEnv.m_Offset[0], texEnv.m_Offset[1]);
|
iMat.TexOffsets[dest] = new Vector2(texEnv.m_Offset[0], texEnv.m_Offset[1]);
|
||||||
iMat.TexScales[dest] = new Vector2(texEnv.m_Scale[0], texEnv.m_Scale[1]);
|
iMat.TexScales[dest] = new Vector2(texEnv.m_Scale[0], texEnv.m_Scale[1]);
|
||||||
ConvertTexture2D(tex2D, iMat.Textures[dest]);
|
ConvertTexture2D(m_Texture2D, iMat.Textures[dest]);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialList.Add(iMat);
|
MaterialList.Add(iMat);
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public static class ModelExporter
|
||||||
|
{
|
||||||
|
public static void ExportFbx(string path, IImported imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, bool flatInbetween, int versionIndex, bool isAscii)
|
||||||
|
{
|
||||||
|
Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, flatInbetween, versionIndex, isAscii);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
|
||||||
// 有关程序集的一般信息由以下
|
// 有关程序集的一般信息由以下
|
||||||
// 控制。更改这些特性值可修改
|
// 控制。更改这些特性值可修改
|
||||||
// 与程序集关联的信息。
|
// 与程序集关联的信息。
|
||||||
[assembly: AssemblyTitle("AssetStudioUtility")]
|
[assembly: AssemblyTitle("AssetStudioTools")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("AssetStudioUtility")]
|
[assembly: AssemblyProduct("AssetStudioTools")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
[assembly: AssemblyCopyright("Copyright © Perfare 2018")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
|
@ -11,45 +9,14 @@ namespace AssetStudio
|
||||||
//TODO unfinished
|
//TODO unfinished
|
||||||
public static class ScriptHelper
|
public static class ScriptHelper
|
||||||
{
|
{
|
||||||
public static bool moduleLoaded;
|
public static string GetScriptString(ObjectReader reader, Dictionary<string, ModuleDef> moduleDic)
|
||||||
public static Dictionary<string, ModuleDef> LoadedModuleDic = new Dictionary<string, ModuleDef>();
|
|
||||||
|
|
||||||
public static string GetScriptString(ObjectReader reader)
|
|
||||||
{
|
{
|
||||||
if (!moduleLoaded)
|
|
||||||
{
|
|
||||||
var openFolderDialog = new OpenFolderDialog();
|
|
||||||
openFolderDialog.Title = "Select Assembly Folder";
|
|
||||||
if (openFolderDialog.ShowDialog() == DialogResult.OK)
|
|
||||||
{
|
|
||||||
var files = Directory.GetFiles(openFolderDialog.Folder, "*.dll");
|
|
||||||
var moduleContext = new ModuleContext();
|
|
||||||
var asmResolver = new AssemblyResolver(moduleContext, true);
|
|
||||||
var resolver = new Resolver(asmResolver);
|
|
||||||
moduleContext.AssemblyResolver = asmResolver;
|
|
||||||
moduleContext.Resolver = resolver;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
|
||||||
var module = ModuleDefMD.Load(file, moduleContext);
|
|
||||||
LoadedModuleDic.Add(Path.GetFileName(file), module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleLoaded = true;
|
|
||||||
}
|
|
||||||
var m_MonoBehaviour = new MonoBehaviour(reader);
|
var m_MonoBehaviour = new MonoBehaviour(reader);
|
||||||
var sb = CreateMonoBehaviourHeader(m_MonoBehaviour);
|
var sb = CreateMonoBehaviourHeader(m_MonoBehaviour);
|
||||||
if (m_MonoBehaviour.m_Script.TryGet(out var script))
|
if (m_MonoBehaviour.m_Script.TryGet(out var script))
|
||||||
{
|
{
|
||||||
var m_Script = new MonoScript(script);
|
var m_Script = new MonoScript(script);
|
||||||
if (!LoadedModuleDic.TryGetValue(m_Script.m_AssemblyName, out var module))
|
if (!moduleDic.TryGetValue(m_Script.m_AssemblyName, out var module))
|
||||||
{
|
{
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
@ -153,7 +120,6 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
var size = reader.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
|
sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
|
||||||
sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
|
|
||||||
sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
|
sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
|
@ -173,7 +139,6 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
var size = reader.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
|
sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
|
||||||
sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
|
|
||||||
sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
|
sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
|
@ -50,7 +50,7 @@ namespace AssetStudio
|
||||||
|
|
||||||
public class ShaderProgram
|
public class ShaderProgram
|
||||||
{
|
{
|
||||||
public ShaderSubProgram[] m_SubPrograms;
|
private ShaderSubProgram[] m_SubPrograms;
|
||||||
|
|
||||||
public ShaderProgram(BinaryReader reader)
|
public ShaderProgram(BinaryReader reader)
|
||||||
{
|
{
|
|
@ -1,14 +1,10 @@
|
||||||
using System;
|
using System.Drawing;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
static class SpriteHelper
|
public static class SpriteHelper
|
||||||
{
|
{
|
||||||
public static Bitmap GetImageFromSprite(Sprite m_Sprite)
|
public static Bitmap GetImageFromSprite(Sprite m_Sprite)
|
||||||
{
|
{
|
|
@ -1,11 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
|
@ -16,7 +14,7 @@ namespace AssetStudio
|
||||||
private int m_Height;
|
private int m_Height;
|
||||||
private TextureFormat m_TextureFormat;
|
private TextureFormat m_TextureFormat;
|
||||||
private int image_data_size;
|
private int image_data_size;
|
||||||
public byte[] image_data;
|
private byte[] image_data;
|
||||||
private int[] version;
|
private int[] version;
|
||||||
|
|
||||||
//DDS Start
|
//DDS Start
|
||||||
|
@ -967,9 +965,9 @@ namespace AssetStudio
|
||||||
IntPtr uncompressedData;
|
IntPtr uncompressedData;
|
||||||
int uncompressedSize;
|
int uncompressedSize;
|
||||||
bool result;
|
bool result;
|
||||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3) //2017.3 and up
|
||||||
|| m_TextureFormat == TextureFormat.ETC_RGB4Crunched
|
|| m_TextureFormat == TextureFormat.ETC_RGB4Crunched
|
||||||
|| m_TextureFormat == TextureFormat.ETC2_RGBA8Crunched) //2017.3 and up
|
|| m_TextureFormat == TextureFormat.ETC2_RGBA8Crunched)
|
||||||
{
|
{
|
||||||
result = DecompressUnityCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize);
|
result = DecompressUnityCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize);
|
||||||
}
|
}
|
|
@ -1,49 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<ProjectGuid>{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}</ProjectGuid>
|
|
||||||
<OutputType>Library</OutputType>
|
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
||||||
<RootNamespace>AssetStudioUtility</RootNamespace>
|
|
||||||
<AssemblyName>AssetStudioUtility</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
|
||||||
<FileAlignment>512</FileAlignment>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>bin\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="SharpDX.Mathematics">
|
|
||||||
<HintPath>..\AssetStudio\Libraries\SharpDX.Mathematics.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Core" />
|
|
||||||
<Reference Include="System.Xml.Linq" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="Imported.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
</Project>
|
|
Loading…
Reference in New Issue