parent
b93866d196
commit
8ea998b81f
|
@ -3,11 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2024
|
||||
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
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBX", "AssetStudioFBX\AssetStudioFBX.vcxproj", "{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}"
|
||||
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
|
||||
Global
|
||||
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|x86.ActiveCfg = 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.Build.0 = Debug|Any CPU
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.Build.0 = Release|Any CPU
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.Build.0 = Debug|x64
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.Build.0 = Debug|x86
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.ActiveCfg = Release|x64
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.Build.0 = Release|x64
|
||||
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.ActiveCfg = Release|x86
|
||||
{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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace SevenZip
|
||||
{
|
||||
class CRC
|
||||
public class CRC
|
||||
{
|
||||
public static readonly uint[] Table;
|
||||
|
||||
|
|
|
@ -1,163 +1,72 @@
|
|||
<?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>
|
||||
<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>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{AF56B63C-1764-41B7-9E60-8D485422AC3B}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AssetStudio</RootNamespace>
|
||||
<AssemblyName>AssetStudio</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>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<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>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<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">
|
||||
<HintPath>Libraries\SharpDX.Mathematics.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Half">
|
||||
<HintPath>Libraries\System.Half.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<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="7zip\Common\CommandLineParser.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="7zip\Common\CRC.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="7zip\Common\InBuffer.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="7zip\Common\OutBuffer.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="7zip\Compress\LZMA\LzmaBase.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="7zip\Compress\LZMA\LzmaDecoder.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="7zip\Compress\LZMA\LzmaEncoder.cs">
|
||||
<SubType>Code</SubType>
|
||||
</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="7zip\Common\CommandLineParser.cs" />
|
||||
<Compile Include="7zip\Common\CRC.cs" />
|
||||
<Compile Include="7zip\Common\InBuffer.cs" />
|
||||
<Compile Include="7zip\Common\OutBuffer.cs" />
|
||||
<Compile Include="7zip\Compress\LZMA\LzmaBase.cs" />
|
||||
<Compile Include="7zip\Compress\LZMA\LzmaDecoder.cs" />
|
||||
<Compile Include="7zip\Compress\LZMA\LzmaEncoder.cs" />
|
||||
<Compile Include="7zip\Compress\LZ\IMatchFinder.cs" />
|
||||
<Compile Include="7zip\Compress\LZ\LzBinTree.cs" />
|
||||
<Compile Include="7zip\Compress\LZ\LzInWindow.cs" />
|
||||
<Compile Include="7zip\Compress\LZ\LzOutWindow.cs" />
|
||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoder.cs" />
|
||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBit.cs" />
|
||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBitTree.cs" />
|
||||
<Compile Include="7zip\ICoder.cs" />
|
||||
<Compile Include="Utility\IImported.cs" />
|
||||
<Compile Include="SerializedFile.cs" />
|
||||
<Compile Include="AssetsManager.cs" />
|
||||
<Compile Include="Extensions\BinaryReaderExtensions.cs" />
|
||||
<Compile Include="Extensions\BinaryWriterExtensions.cs" />
|
||||
<Compile Include="Brotli\BitReader.cs" />
|
||||
<Compile Include="Brotli\BrotliInputStream.cs" />
|
||||
<Compile Include="Brotli\BrotliRuntimeException.cs" />
|
||||
|
@ -173,170 +82,67 @@
|
|||
<Compile Include="Brotli\Transform.cs" />
|
||||
<Compile Include="Brotli\Utils.cs" />
|
||||
<Compile Include="Brotli\WordTransformType.cs" />
|
||||
<Compile Include="Classes\Behaviour.cs" />
|
||||
<Compile Include="Classes\Component.cs" />
|
||||
<Compile Include="Classes\EditorExtension.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="BuildTarget.cs" />
|
||||
<Compile Include="BuildType.cs" />
|
||||
<Compile Include="BundleFile.cs" />
|
||||
<Compile Include="Classes\Animation.cs" />
|
||||
<Compile Include="Classes\AnimationClip.cs" />
|
||||
<Compile Include="Classes\Animator.cs" />
|
||||
<Compile Include="Classes\AnimatorController.cs" />
|
||||
<Compile Include="Classes\AnimatorOverrideController.cs" />
|
||||
<Compile Include="Classes\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\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\Avatar.cs" />
|
||||
<Compile Include="Classes\Behaviour.cs" />
|
||||
<Compile Include="Classes\BuildSettings.cs" />
|
||||
<Compile Include="StudioClasses\BundleFile.cs" />
|
||||
<Compile Include="StudioClasses\TypeTreeItem.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\Component.cs" />
|
||||
<Compile Include="Classes\EditorExtension.cs" />
|
||||
<Compile Include="Classes\Font.cs" />
|
||||
<Compile Include="GOHierarchy.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Lz4DecoderStream.cs" />
|
||||
<Compile Include="Classes\GameObject.cs" />
|
||||
<Compile Include="Classes\Material.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\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\RectTransform.cs" />
|
||||
<Compile Include="Classes\MeshRenderer.cs" />
|
||||
<Compile Include="Classes\Renderer.cs" />
|
||||
<Compile Include="Classes\Shader.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\Texture.cs" />
|
||||
<Compile Include="Classes\Texture2D.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="StudioClasses\AssetsFile.cs" />
|
||||
<Compile Include="StudioClasses\ModelConverter.cs" />
|
||||
<Compile Include="StudioClasses\Texture2DConverter.cs" />
|
||||
<Compile Include="StudioClasses\WebFile.cs" />
|
||||
<Compile Include="AssetStudioForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AssetStudioForm.Designer.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" />
|
||||
<Compile Include="ResourcesHelper.cs" />
|
||||
<Compile Include="SerializedFileHeader.cs" />
|
||||
<Compile Include="SerializedType.cs" />
|
||||
<Compile Include="SevenZipHelper.cs" />
|
||||
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||
<Compile Include="TypeTreeHelper.cs" />
|
||||
<Compile Include="TypeTreeNode.cs" />
|
||||
<Compile Include="WebFile.cs" />
|
||||
</ItemGroup>
|
||||
<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>
|
|
@ -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++)
|
||||
{
|
||||
var file = new StreamFile();
|
||||
file.fileName = reader.ReadStringToNull();
|
||||
file.fileName = Path.GetFileName(reader.ReadStringToNull());
|
||||
int fileOffset = reader.ReadInt32();
|
||||
fileOffset += offset;
|
||||
int fileSize = reader.ReadInt32();
|
|
@ -1,9 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SharpDX;
|
||||
|
||||
namespace AssetStudio
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Text;
|
|||
|
||||
namespace AssetStudio
|
||||
{
|
||||
class AnimatorOverrideController : NamedObject
|
||||
public class AnimatorOverrideController : NamedObject
|
||||
{
|
||||
public PPtr m_Controller;
|
||||
public PPtr[][] m_Clips;
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace AssetStudio
|
|||
if (reader.byteSize + reader.byteStart - reader.Position != tsize)
|
||||
{
|
||||
m_Offset = reader.ReadInt32();
|
||||
m_Source = sourceFile.filePath + ".resS";
|
||||
m_Source = sourceFile.fullName + ".resS";
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -83,7 +83,7 @@ namespace AssetStudio
|
|||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace AssetStudio
|
|||
{
|
||||
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()];
|
||||
for (int i = 0; i < m_ShaderKeywords.Length; i++)
|
||||
|
|
|
@ -20,10 +20,10 @@ namespace AssetStudio
|
|||
public float[] m_Vertices;
|
||||
public float[] m_Normals;
|
||||
public float[] m_Colors;
|
||||
public float[] m_UV0;
|
||||
public float[] m_UV1;
|
||||
public float[] m_UV2;
|
||||
public float[] m_UV3;
|
||||
public float[] m_UV4;
|
||||
public float[] m_Tangents;
|
||||
public uint[] m_BoneNameHashes;
|
||||
public BlendShapeData m_Shapes;
|
||||
|
@ -295,7 +295,7 @@ namespace AssetStudio
|
|||
#endregion
|
||||
|
||||
#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();
|
||||
if (m_Shapes_size > 0)
|
||||
|
@ -359,7 +359,7 @@ namespace AssetStudio
|
|||
reader.AlignStream(4);
|
||||
//This is a bug fixed in 2017.3.1p1 and later versions
|
||||
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
|
||||
{
|
||||
var m_IndexFormat = reader.ReadInt32();
|
||||
|
@ -407,12 +407,12 @@ namespace AssetStudio
|
|||
}
|
||||
|
||||
int m_UV1_size = reader.ReadInt32();
|
||||
m_UV1 = new float[m_UV1_size * 2];
|
||||
for (int v = 0; v < m_UV1_size * 2; v++) { m_UV1[v] = reader.ReadSingle(); }
|
||||
m_UV0 = new float[m_UV1_size * 2];
|
||||
for (int v = 0; v < m_UV1_size * 2; v++) { m_UV0[v] = reader.ReadSingle(); }
|
||||
|
||||
int m_UV2_size = reader.ReadInt32();
|
||||
m_UV2 = new float[m_UV2_size * 2];
|
||||
for (int v = 0; v < m_UV2_size * 2; v++) { m_UV2[v] = reader.ReadSingle(); }
|
||||
m_UV1 = new float[m_UV2_size * 2];
|
||||
for (int v = 0; v < m_UV2_size * 2; v++) { m_UV1[v] = reader.ReadSingle(); }
|
||||
|
||||
if (version[0] == 2 && version[1] <= 5)
|
||||
{
|
||||
|
@ -631,16 +631,16 @@ namespace AssetStudio
|
|||
m_Colors = componentsFloatArray;
|
||||
break;
|
||||
case 4: //kShaderChannelTexCoord0
|
||||
m_UV1 = componentsFloatArray;
|
||||
m_UV0 = componentsFloatArray;
|
||||
break;
|
||||
case 5: //kShaderChannelTexCoord1
|
||||
m_UV2 = componentsFloatArray;
|
||||
m_UV1 = componentsFloatArray;
|
||||
break;
|
||||
case 6: //kShaderChannelTexCoord2
|
||||
m_UV3 = componentsFloatArray;
|
||||
m_UV2 = componentsFloatArray;
|
||||
break;
|
||||
case 7: //kShaderChannelTexCoord3
|
||||
m_UV4 = componentsFloatArray;
|
||||
m_UV3 = componentsFloatArray;
|
||||
break;
|
||||
//kShaderChannelTexCoord4 8
|
||||
//kShaderChannelTexCoord5 9
|
||||
|
@ -744,15 +744,15 @@ namespace AssetStudio
|
|||
m_Colors = componentsFloatArray;
|
||||
break;
|
||||
case 3: //kShaderChannelTexCoord0
|
||||
m_UV1 = componentsFloatArray;
|
||||
m_UV0 = componentsFloatArray;
|
||||
break;
|
||||
case 4: //kShaderChannelTexCoord1
|
||||
m_UV2 = componentsFloatArray;
|
||||
m_UV1 = componentsFloatArray;
|
||||
break;
|
||||
case 5: //kShaderChannelTangent & kShaderChannelTexCoord2
|
||||
if (version[0] >= 5)
|
||||
{
|
||||
m_UV3 = componentsFloatArray;
|
||||
m_UV2 = componentsFloatArray;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -760,7 +760,7 @@ namespace AssetStudio
|
|||
}
|
||||
break;
|
||||
case 6: //kShaderChannelTexCoord3
|
||||
m_UV4 = componentsFloatArray;
|
||||
m_UV3 = componentsFloatArray;
|
||||
break;
|
||||
case 7: //kShaderChannelTangent
|
||||
m_Tangents = componentsFloatArray;
|
||||
|
@ -831,8 +831,8 @@ namespace AssetStudio
|
|||
case 0: m_Vertices = componentsArray; break;
|
||||
case 1: m_Normals = componentsArray; break;
|
||||
case 2: m_Colors = componentsArray; break;
|
||||
case 3: m_UV1 = componentsArray; break;
|
||||
case 4: m_UV2 = componentsArray; break;
|
||||
case 3: m_UV0 = componentsArray; break;
|
||||
case 4: m_UV1 = componentsArray; break;
|
||||
case 5: m_Tangents = componentsArray; break;
|
||||
}
|
||||
|
||||
|
@ -864,18 +864,18 @@ namespace AssetStudio
|
|||
var m_UV_Packed = new PackedFloatVector(reader);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -7,10 +7,10 @@ namespace AssetStudio
|
|||
{
|
||||
public abstract class Object
|
||||
{
|
||||
protected AssetsFile sourceFile;
|
||||
protected SerializedFile sourceFile;
|
||||
public ObjectReader reader;
|
||||
public int[] version;
|
||||
protected string[] buildType;
|
||||
protected BuildType buildType;
|
||||
public BuildTarget platform;
|
||||
|
||||
protected Object(ObjectReader reader)
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
using static AssetStudio.Studio;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class PPtr
|
||||
{
|
||||
public int m_FileID;
|
||||
public long m_PathID;
|
||||
|
||||
//custom
|
||||
public AssetsFile assetsFile;
|
||||
public SerializedFile assetsFile;
|
||||
public int index = -2; //-2 - Prepare, -1 - Missing
|
||||
|
||||
private bool TryGetAssetsFile(out AssetsFile result)
|
||||
private bool TryGetAssetsFile(out SerializedFile result)
|
||||
{
|
||||
result = null;
|
||||
if (m_FileID == 0)
|
||||
|
@ -22,6 +19,10 @@ namespace AssetStudio
|
|||
|
||||
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)
|
||||
{
|
||||
var m_External = assetsFile.m_Externals[m_FileID - 1];
|
|
@ -105,7 +105,7 @@ namespace AssetStudio
|
|||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace AssetStudio
|
|||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
|
@ -14,13 +14,11 @@ namespace AssetStudio
|
|||
public class EndianBinaryReader : BinaryReader
|
||||
{
|
||||
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)
|
||||
: base(stream)
|
||||
{ this.endian = endian; }
|
||||
public EndianBinaryReader(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream)
|
||||
{
|
||||
this.endian = endian;
|
||||
}
|
||||
|
||||
public long Position
|
||||
{
|
||||
|
@ -32,9 +30,9 @@ namespace AssetStudio
|
|||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a16 = ReadBytes(2);
|
||||
Array.Reverse(a16);
|
||||
return BitConverter.ToInt16(a16, 0);
|
||||
var buff = ReadBytes(2);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToInt16(buff, 0);
|
||||
}
|
||||
return base.ReadInt16();
|
||||
}
|
||||
|
@ -43,9 +41,9 @@ namespace AssetStudio
|
|||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a32 = ReadBytes(4);
|
||||
Array.Reverse(a32);
|
||||
return BitConverter.ToInt32(a32, 0);
|
||||
var buff = ReadBytes(4);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToInt32(buff, 0);
|
||||
}
|
||||
return base.ReadInt32();
|
||||
}
|
||||
|
@ -54,9 +52,9 @@ namespace AssetStudio
|
|||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a64 = ReadBytes(8);
|
||||
Array.Reverse(a64);
|
||||
return BitConverter.ToInt64(a64, 0);
|
||||
var buff = ReadBytes(8);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToInt64(buff, 0);
|
||||
}
|
||||
return base.ReadInt64();
|
||||
}
|
||||
|
@ -65,9 +63,9 @@ namespace AssetStudio
|
|||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a16 = ReadBytes(2);
|
||||
Array.Reverse(a16);
|
||||
return BitConverter.ToUInt16(a16, 0);
|
||||
var buff = ReadBytes(2);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt16(buff, 0);
|
||||
}
|
||||
return base.ReadUInt16();
|
||||
}
|
||||
|
@ -76,9 +74,9 @@ namespace AssetStudio
|
|||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a32 = ReadBytes(4);
|
||||
Array.Reverse(a32);
|
||||
return BitConverter.ToUInt32(a32, 0);
|
||||
var buff = ReadBytes(4);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt32(buff, 0);
|
||||
}
|
||||
return base.ReadUInt32();
|
||||
}
|
||||
|
@ -87,9 +85,9 @@ namespace AssetStudio
|
|||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a64 = ReadBytes(8);
|
||||
Array.Reverse(a64);
|
||||
return BitConverter.ToUInt64(a64, 0);
|
||||
var buff = ReadBytes(8);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt64(buff, 0);
|
||||
}
|
||||
return base.ReadUInt64();
|
||||
}
|
||||
|
@ -98,9 +96,9 @@ namespace AssetStudio
|
|||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a32 = ReadBytes(4);
|
||||
Array.Reverse(a32);
|
||||
return BitConverter.ToSingle(a32, 0);
|
||||
var buff = ReadBytes(4);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToSingle(buff, 0);
|
||||
}
|
||||
return base.ReadSingle();
|
||||
}
|
||||
|
@ -109,9 +107,9 @@ namespace AssetStudio
|
|||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
{
|
||||
a64 = ReadBytes(8);
|
||||
Array.Reverse(a64);
|
||||
return BitConverter.ToUInt64(a64, 0);
|
||||
var buff = ReadBytes(8);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt64(buff, 0);
|
||||
}
|
||||
return base.ReadDouble();
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SharpDX;
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public void Reset(Stream input, long inputLength = long.MaxValue)
|
||||
private void Reset(Stream input, long inputLength = long.MaxValue)
|
||||
{
|
||||
this.inputLength = inputLength;
|
||||
this.input = input;
|
||||
|
@ -40,6 +40,7 @@ namespace Lz4
|
|||
input.Close();
|
||||
}
|
||||
input = null;
|
||||
decodeBuffer = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace AssetStudio
|
|||
{
|
||||
public class ObjectReader : EndianBinaryReader
|
||||
{
|
||||
public AssetsFile assetsFile;
|
||||
public SerializedFile assetsFile;
|
||||
public long m_PathID;
|
||||
public uint byteStart;
|
||||
public uint byteSize;
|
||||
|
@ -18,11 +18,9 @@ namespace AssetStudio
|
|||
private uint m_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, AssetsFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.endian)
|
||||
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.endian)
|
||||
{
|
||||
this.assetsFile = assetsFile;
|
||||
m_PathID = objectInfo.m_PathID;
|
|
@ -2,35 +2,35 @@
|
|||
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("AssetStudio")]
|
||||
[assembly: AssemblyDescription("AssetStudio is a tool for exploring, extracting and exporting assets and assetbundles.")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AssetStudio")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[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.
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[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")]
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[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("0.11.0.0")]
|
||||
[assembly: AssemblyFileVersion("0.11.0.0")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
|
@ -3,26 +3,26 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
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);
|
||||
|
||||
if (Studio.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader))
|
||||
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader))
|
||||
{
|
||||
reader.Position = offset;
|
||||
return reader.ReadBytes(size);
|
||||
}
|
||||
|
||||
var resourceFilePath = Path.GetDirectoryName(sourceFilePath) + "\\" + resourceFileName;
|
||||
var currentDirectory = Path.GetDirectoryName(assetsFile.fullName);
|
||||
var resourceFilePath = currentDirectory + "\\" + resourceFileName;
|
||||
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)
|
||||
{
|
||||
resourceFilePath = findFiles[0];
|
||||
|
@ -36,11 +36,8 @@ namespace AssetStudio
|
|||
return resourceReader.ReadBytes(size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show($"can't find the resource file {resourceFileName}");
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,41 +6,41 @@ using System.Text.RegularExpressions;
|
|||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class AssetsFile
|
||||
public class SerializedFile
|
||||
{
|
||||
public AssetsManager assetsManager;
|
||||
public EndianBinaryReader reader;
|
||||
public string filePath;
|
||||
public string parentPath;
|
||||
public string fullName;
|
||||
public string originalPath;
|
||||
public string fileName;
|
||||
public string upperFileName;
|
||||
public int[] version = { 0, 0, 0, 0 };
|
||||
public string[] buildType;
|
||||
public string platformStr;
|
||||
public BuildType buildType;
|
||||
public bool valid;
|
||||
public Dictionary<long, ObjectReader> ObjectReaders = new Dictionary<long, ObjectReader>();
|
||||
public Dictionary<long, GameObject> GameObjects = new Dictionary<long, GameObject>();
|
||||
public Dictionary<long, Transform> Transforms = new Dictionary<long, Transform>();
|
||||
|
||||
//class SerializedFile
|
||||
public SerializedFileHeader header;
|
||||
private EndianType m_FileEndianess;
|
||||
public string unityVersion = "2.5.0f5";
|
||||
public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform;
|
||||
private bool m_EnableTypeTree = true;
|
||||
public List<SerializedType> m_Types;
|
||||
public Dictionary<long, ObjectInfo> m_Objects;
|
||||
private List<ObjectInfo> m_Objects;
|
||||
private List<LocalSerializedObjectIdentifier> m_ScriptTypes;
|
||||
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;
|
||||
filePath = fullName;
|
||||
this.fullName = fullName;
|
||||
fileName = Path.GetFileName(fullName);
|
||||
upperFileName = fileName.ToUpper();
|
||||
try
|
||||
{
|
||||
//SerializedFile::ReadHeader
|
||||
//ReadHeader
|
||||
header = new SerializedFileHeader();
|
||||
header.m_MetadataSize = reader.ReadUInt32();
|
||||
header.m_FileSize = reader.ReadUInt32();
|
||||
|
@ -59,7 +59,7 @@ namespace AssetStudio
|
|||
m_FileEndianess = (EndianType)reader.ReadByte();
|
||||
}
|
||||
|
||||
//SerializedFile::ReadMetadata
|
||||
//ReadMetadata
|
||||
if (m_FileEndianess == EndianType.LittleEndian)
|
||||
{
|
||||
reader.endian = EndianType.LittleEndian;
|
||||
|
@ -67,6 +67,7 @@ namespace AssetStudio
|
|||
if (header.m_Version >= 7)
|
||||
{
|
||||
unityVersion = reader.ReadStringToNull();
|
||||
SetVersion(unityVersion);
|
||||
}
|
||||
if (header.m_Version >= 8)
|
||||
{
|
||||
|
@ -76,13 +77,12 @@ namespace AssetStudio
|
|||
m_TargetPlatform = BuildTarget.UnknownPlatform;
|
||||
}
|
||||
}
|
||||
platformStr = m_TargetPlatform.ToString();
|
||||
if (header.m_Version >= 13)
|
||||
{
|
||||
m_EnableTypeTree = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
//Read types
|
||||
//ReadTypes
|
||||
int typeCount = reader.ReadInt32();
|
||||
m_Types = new List<SerializedType>(typeCount);
|
||||
for (int i = 0; i < typeCount; i++)
|
||||
|
@ -95,9 +95,9 @@ namespace AssetStudio
|
|||
var bigIDEnabled = reader.ReadInt32();
|
||||
}
|
||||
|
||||
//Read Objects
|
||||
//ReadObjects
|
||||
int objectCount = reader.ReadInt32();
|
||||
m_Objects = new Dictionary<long, ObjectInfo>(objectCount);
|
||||
m_Objects = new List<ObjectInfo>(objectCount);
|
||||
for (int i = 0; i < objectCount; i++)
|
||||
{
|
||||
var objectInfo = new ObjectInfo();
|
||||
|
@ -130,23 +130,11 @@ namespace AssetStudio
|
|||
{
|
||||
var stripped = reader.ReadByte();
|
||||
}
|
||||
m_Objects.Add(objectInfo.m_PathID, objectInfo);
|
||||
m_Objects.Add(objectInfo);
|
||||
|
||||
//Create Reader
|
||||
var objectReader = new ObjectReader(reader, this, objectInfo);
|
||||
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)
|
||||
|
@ -194,10 +182,6 @@ namespace AssetStudio
|
|||
//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;
|
||||
}
|
||||
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()
|
||||
{
|
||||
var type = new SerializedType();
|
|
@ -11,18 +11,18 @@ namespace AssetStudio
|
|||
{
|
||||
var decoder = new Decoder();
|
||||
|
||||
inStream.Seek(0, 0);
|
||||
inStream.Seek(0, SeekOrigin.Begin);
|
||||
var newOutStream = new MemoryStream();
|
||||
|
||||
var properties = new byte[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;
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var v = inStream.ReadByte();
|
||||
if (v < 0)
|
||||
throw (new Exception("Can't Read 1"));
|
||||
throw new Exception("Can't Read 1");
|
||||
outSize |= ((long)(byte)v) << (8 * i);
|
||||
}
|
||||
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.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -154,15 +153,14 @@ namespace AssetStudio
|
|||
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 objdic = (IDictionary<string, object>)obj;
|
||||
var obj = new Dictionary<string, object>();
|
||||
for (int i = 0; i < members.Count; i++)
|
||||
{
|
||||
var member = members[i];
|
||||
var varNameStr = member.m_Name;
|
||||
objdic[varNameStr] = ReadValue(members, reader, ref i);
|
||||
obj[varNameStr] = ReadValue(members, reader, ref i);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
@ -274,13 +272,12 @@ namespace AssetStudio
|
|||
var @class = GetMembers(members, level, i);
|
||||
@class.RemoveAt(0);
|
||||
i += @class.Count;
|
||||
var obj = new ExpandoObject();
|
||||
var objdic = (IDictionary<string, object>)obj;
|
||||
var obj = new Dictionary<string, object>();
|
||||
for (int j = 0; j < @class.Count; j++)
|
||||
{
|
||||
var classmember = @class[j];
|
||||
var name = classmember.m_Name;
|
||||
objdic[name] = ReadValue(@class, reader, ref j);
|
||||
obj[name] = ReadValue(@class, reader, ref j);
|
||||
}
|
||||
value = obj;
|
||||
break;
|
||||
|
@ -308,16 +305,15 @@ namespace AssetStudio
|
|||
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 write = new BinaryWriter(stream);
|
||||
var objdic = (IDictionary<string, object>)obj;
|
||||
for (int i = 0; i < members.Count; i++)
|
||||
{
|
||||
var member = members[i];
|
||||
var varNameStr = member.m_Name;
|
||||
WriteValue(objdic[varNameStr], members, write, ref i);
|
||||
WriteValue(obj[varNameStr], members, write, ref i);
|
||||
}
|
||||
return stream.ToArray();
|
||||
}
|
||||
|
@ -431,13 +427,12 @@ namespace AssetStudio
|
|||
var @class = GetMembers(members, level, i);
|
||||
@class.RemoveAt(0);
|
||||
i += @class.Count;
|
||||
var obj = (ExpandoObject)value;
|
||||
var objdic = (IDictionary<string, object>)obj;
|
||||
var obj = (Dictionary<string, object>)value;
|
||||
for (int j = 0; j < @class.Count; j++)
|
||||
{
|
||||
var classmember = @class[j];
|
||||
var name = classmember.m_Name;
|
||||
WriteValue(objdic[name], @class, write, ref j);
|
||||
WriteValue(obj[name], @class, write, ref j);
|
||||
}
|
||||
break;
|
||||
}
|
|
@ -219,7 +219,7 @@ namespace AssetStudio
|
|||
|
||||
public static ImportedMesh FindMesh(string frameName, List<ImportedMesh> importedMeshList)
|
||||
{
|
||||
foreach (ImportedMesh mesh in importedMeshList)
|
||||
foreach (var mesh in importedMeshList)
|
||||
{
|
||||
if (mesh.Name == frameName)
|
||||
{
|
||||
|
@ -232,15 +232,15 @@ namespace AssetStudio
|
|||
|
||||
public static ImportedMesh FindMesh(ImportedFrame frame, List<ImportedMesh> importedMeshList)
|
||||
{
|
||||
string framePath = frame.Name;
|
||||
ImportedFrame root = frame;
|
||||
var framePath = frame.Name;
|
||||
var root = frame;
|
||||
while (root.Parent != null)
|
||||
{
|
||||
root = root.Parent;
|
||||
framePath = root.Name + "/" + framePath;
|
||||
}
|
||||
|
||||
foreach (ImportedMesh mesh in importedMeshList)
|
||||
foreach (var mesh in importedMeshList)
|
||||
{
|
||||
if (mesh.Name == framePath)
|
||||
{
|
||||
|
@ -253,7 +253,7 @@ namespace AssetStudio
|
|||
|
||||
public static ImportedMaterial FindMaterial(string name, List<ImportedMaterial> importedMats)
|
||||
{
|
||||
foreach (ImportedMaterial mat in importedMats)
|
||||
foreach (var mat in importedMats)
|
||||
{
|
||||
if (mat.Name == name)
|
||||
{
|
||||
|
@ -271,7 +271,7 @@ namespace AssetStudio
|
|||
return null;
|
||||
}
|
||||
|
||||
foreach (ImportedTexture tex in importedTextureList)
|
||||
foreach (var tex in importedTextureList)
|
||||
{
|
||||
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 List<StreamFile> fileList = new List<StreamFile>();
|
||||
|
||||
|
||||
public class WebData
|
||||
private class WebData
|
||||
{
|
||||
public int dataOffset;
|
||||
public int dataLength;
|
||||
public string path;
|
||||
}
|
||||
|
||||
|
||||
public WebFile(EndianBinaryReader reader)
|
||||
{
|
||||
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:AssemblyCompanyAttribute(L"")];
|
||||
[assembly:AssemblyProductAttribute(L"AssetStudioFBX")];
|
||||
[assembly:AssemblyCopyrightAttribute(L"Copyright © 2018")];
|
||||
[assembly:AssemblyCopyrightAttribute(L"Copyright © Perfare 2018")];
|
||||
[assembly:AssemblyTrademarkAttribute(L"")];
|
||||
[assembly:AssemblyCultureAttribute(L"")];
|
||||
|
||||
|
|
|
@ -150,8 +150,8 @@
|
|||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj">
|
||||
<Project>{9131c403-7fe8-444d-9af5-5fe5df76ff24}</Project>
|
||||
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
|
||||
<Project>{af56b63c-1764-41b7-9e60-8d485422ac3b}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
@ -487,42 +487,39 @@ namespace AssetStudio
|
|||
pMeshNode->AddMaterial(pMat);
|
||||
|
||||
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)
|
||||
{
|
||||
LinkTexture(mat, 0, pTextureDiffuse, pMat->Diffuse);
|
||||
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)
|
||||
{
|
||||
LinkTexture(mat, 1, pTextureAmbient, pMat->Ambient);
|
||||
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)
|
||||
{
|
||||
LinkTexture(mat, 2, pTextureEmissive, pMat->Emissive);
|
||||
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)
|
||||
{
|
||||
LinkTexture(mat, 3, pTextureSpecular, pMat->Specular);
|
||||
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);
|
||||
if (pTextureBump != NULL)
|
||||
{
|
||||
LinkTexture(mat, 4, pTextureBump, pMat->Bump);
|
||||
hasTexture = true;
|
||||
}
|
||||
LinkTexture(mat, 4, pTextureBump, pMat->Bump);
|
||||
hasTexture = true;
|
||||
}
|
||||
|
||||
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>
|
||||
/// Required designer variable.
|
||||
|
@ -29,7 +29,7 @@
|
|||
private void InitializeComponent()
|
||||
{
|
||||
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.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.loadFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -66,7 +66,7 @@
|
|||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||
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.tabPage2 = new System.Windows.Forms.TabPage();
|
||||
this.assetListView = new System.Windows.Forms.ListView();
|
||||
|
@ -574,7 +574,7 @@
|
|||
// previewPanel
|
||||
//
|
||||
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.Controls.Add(this.assetInfoLabel);
|
||||
this.previewPanel.Controls.Add(this.FMODpanel);
|
||||
|
@ -913,20 +913,20 @@
|
|||
this.showOriginalFileToolStripMenuItem.Visible = false;
|
||||
this.showOriginalFileToolStripMenuItem.Click += new System.EventHandler(this.showOriginalFileToolStripMenuItem_Click);
|
||||
//
|
||||
// AssetStudioForm
|
||||
// AssetStudioGUIForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1264, 681);
|
||||
this.Controls.Add(this.splitContainer1);
|
||||
this.Controls.Add(this.menuStrip1);
|
||||
this.Icon = global::AssetStudio.Properties.Resources._as;
|
||||
this.Icon = global::AssetStudioGUI.Properties.Resources._as;
|
||||
this.KeyPreview = true;
|
||||
this.MainMenuStrip = this.menuStrip1;
|
||||
this.MinimumSize = new System.Drawing.Size(620, 372);
|
||||
this.Name = "AssetStudioForm";
|
||||
this.Name = "AssetStudioGUIForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "AssetStudio";
|
||||
this.Text = "AssetStudioGUI";
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AssetStudioForm_KeyDown);
|
||||
this.menuStrip1.ResumeLayout(false);
|
||||
this.menuStrip1.PerformLayout();
|
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,11 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms;
|
||||
using AssetStudio;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
public class AssetItem : ListViewItem
|
||||
internal class AssetItem : ListViewItem
|
||||
{
|
||||
public AssetsFile sourceFile;
|
||||
public SerializedFile sourceFile;
|
||||
public ObjectReader reader;
|
||||
public long FullSize;
|
||||
public ClassIDType Type;
|
|
@ -4,9 +4,9 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
public class GOHierarchy : TreeView
|
||||
internal class GOHierarchy : TreeView
|
||||
{
|
||||
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.Windows.Forms;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
class OpenFolderDialog
|
||||
internal class OpenFolderDialog
|
||||
{
|
||||
public string InitialFolder { get; set; }
|
||||
public string DefaultFolder { get; set; }
|
|
@ -1,13 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
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 TVIS_STATEIMAGEMASK = 0xF000;
|
|
@ -1,14 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
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)
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
namespace AssetStudio
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
partial class ExportOptions
|
||||
{
|
|
@ -8,7 +8,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
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.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
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)
|
||||
return false;
|
||||
var converter = new Texture2DConverter(m_Texture2D);
|
||||
var convertTexture = (bool)Properties.Settings.Default["convertTexture"];
|
||||
if (convertTexture)
|
||||
{
|
||||
var bitmap = converter.ConvertToBitmap(flip);
|
||||
var bitmap = converter.ConvertToBitmap(true);
|
||||
if (bitmap == null)
|
||||
return false;
|
||||
ImageFormat format = null;
|
||||
|
@ -36,7 +35,7 @@ namespace AssetStudio
|
|||
format = ImageFormat.Jpeg;
|
||||
break;
|
||||
}
|
||||
var exportFullName = exportPathName + reader.exportName + "." + ext.ToLower();
|
||||
var exportFullName = exportPathName + item.Text + "." + ext.ToLower();
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
bitmap.Save(exportFullName, format);
|
||||
|
@ -45,7 +44,7 @@ namespace AssetStudio
|
|||
}
|
||||
else
|
||||
{
|
||||
var exportFullName = exportPathName + reader.exportName + converter.GetExtensionName();
|
||||
var exportFullName = exportPathName + item.Text + converter.GetExtensionName();
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
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)
|
||||
return false;
|
||||
var convertAudio = (bool)Properties.Settings.Default["convertAudio"];
|
||||
var converter = new AudioClipConverter(m_AudioClip);
|
||||
if (convertAudio && converter.IsFMODSupport)
|
||||
{
|
||||
var exportFullName = exportPath + reader.exportName + ".wav";
|
||||
var exportFullName = exportPath + item.Text + ".wav";
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
var buffer = converter.ConvertToWav();
|
||||
|
@ -72,7 +71,7 @@ namespace AssetStudio
|
|||
}
|
||||
else
|
||||
{
|
||||
var exportFullName = exportPath + reader.exportName + converter.GetExtensionName();
|
||||
var exportFullName = exportPath + item.Text + converter.GetExtensionName();
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullName, m_AudioClip.m_AudioData);
|
||||
|
@ -80,10 +79,10 @@ namespace AssetStudio
|
|||
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 exportFullName = exportPath + reader.exportName + ".shader";
|
||||
var m_Shader = new Shader(item.reader);
|
||||
var exportFullName = exportPath + item.Text + ".shader";
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
var str = ShaderConverter.Convert(m_Shader);
|
||||
|
@ -91,22 +90,22 @@ namespace AssetStudio
|
|||
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 exportFullName = exportPath + reader.exportName + ".txt";
|
||||
var m_TextAsset = new TextAsset(item.reader);
|
||||
var exportFullName = exportPath + item.Text + ".txt";
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullName, m_TextAsset.m_Script);
|
||||
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))
|
||||
return false;
|
||||
var m_MonoBehaviour = new MonoBehaviour(reader);
|
||||
var reader = item.reader;
|
||||
string str;
|
||||
if (reader.serializedType?.m_Nodes != null)
|
||||
{
|
||||
|
@ -114,15 +113,15 @@ namespace AssetStudio
|
|||
}
|
||||
else
|
||||
{
|
||||
str = ScriptHelper.GetScriptString(reader);
|
||||
str = Studio.GetScriptString(reader);
|
||||
}
|
||||
File.WriteAllText(exportFullName, str);
|
||||
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)
|
||||
{
|
||||
var extension = ".ttf";
|
||||
|
@ -130,7 +129,7 @@ namespace AssetStudio
|
|||
{
|
||||
extension = ".otf";
|
||||
}
|
||||
var exportFullName = exportPath + reader.exportName + extension;
|
||||
var exportFullName = exportPath + item.Text + extension;
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullName, m_Font.m_FontData);
|
||||
|
@ -139,12 +138,12 @@ namespace AssetStudio
|
|||
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)
|
||||
return false;
|
||||
var exportFullName = exportPath + reader.exportName + ".obj";
|
||||
var exportFullName = exportPath + item.Text + ".obj";
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
var sb = new StringBuilder();
|
||||
|
@ -166,20 +165,20 @@ namespace AssetStudio
|
|||
#endregion
|
||||
|
||||
#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++)
|
||||
{
|
||||
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
|
||||
|
||||
#region Normals
|
||||
|
@ -220,12 +219,12 @@ namespace AssetStudio
|
|||
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)
|
||||
{
|
||||
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))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullName, m_VideoClip.m_VideoData);
|
||||
|
@ -234,17 +233,17 @@ namespace AssetStudio
|
|||
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 exportFullName = exportPath + reader.exportName + ".ogv";
|
||||
var m_MovieTexture = new MovieTexture(item.reader);
|
||||
var exportFullName = exportPath + item.Text + ".ogv";
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullName, m_MovieTexture.m_MovieData);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportSprite(ObjectReader reader, string exportPath)
|
||||
public static bool ExportSprite(AssetItem item, string exportPath)
|
||||
{
|
||||
ImageFormat format = null;
|
||||
var type = (string)Properties.Settings.Default["convertType"];
|
||||
|
@ -260,10 +259,10 @@ namespace AssetStudio
|
|||
format = ImageFormat.Jpeg;
|
||||
break;
|
||||
}
|
||||
var exportFullName = exportPath + reader.exportName + "." + type.ToLower();
|
||||
var exportFullName = exportPath + item.Text + "." + type.ToLower();
|
||||
if (ExportFileExists(exportFullName))
|
||||
return false;
|
||||
var bitmap = SpriteHelper.GetImageFromSprite(new Sprite(reader));
|
||||
var bitmap = SpriteHelper.GetImageFromSprite(new Sprite(item.reader));
|
||||
if (bitmap != null)
|
||||
{
|
||||
bitmap.Save(exportFullName, format);
|
||||
|
@ -273,12 +272,12 @@ namespace AssetStudio
|
|||
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))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullName, reader.GetRawData());
|
||||
File.WriteAllBytes(exportFullName, item.reader.GetRawData());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -292,22 +291,22 @@ namespace AssetStudio
|
|||
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 convert = animationList != null ? new ModelConverter(m_Animator, animationList) : new ModelConverter(m_Animator);
|
||||
exportPath = exportPath + Studio.FixFileName(animator.exportName) + ".fbx";
|
||||
return ModelConverter(convert, exportPath);
|
||||
var m_Animator = new Animator(item.reader);
|
||||
var convert = animationList != null ? new ModelConverter(m_Animator, animationList.Select(x => x.reader).ToArray()) : new ModelConverter(m_Animator);
|
||||
exportPath = exportPath + item.Text + ".fbx";
|
||||
return ExportFbx(convert, exportPath);
|
||||
}
|
||||
|
||||
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";
|
||||
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 filterPrecision = (float)(decimal)Properties.Settings.Default["filterPrecision"];
|
||||
|
@ -319,7 +318,7 @@ namespace AssetStudio
|
|||
var flatInbetween = (bool)Properties.Settings.Default["flatInbetween"];
|
||||
var fbxVersion = (int)Properties.Settings.Default["fbxVersion"];
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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.Windows.Forms;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ namespace AssetStudio
|
|||
{
|
||||
Application.EnableVisualStyles();
|
||||
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>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AssetStudio.Properties {
|
||||
namespace AssetStudioGUI.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
|
@ -39,16 +39,15 @@ namespace AssetStudio.Properties {
|
|||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
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;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 使用此强类型资源类,为所有资源查找
|
||||
/// 重写当前线程的 CurrentUICulture 属性。
|
||||
/// 重写当前线程的 CurrentUICulture 属性
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
|
@ -8,11 +8,11 @@
|
|||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AssetStudio.Properties {
|
||||
namespace AssetStudioGUI.Properties {
|
||||
|
||||
|
||||
[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 {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
|
@ -1,5 +1,5 @@
|
|||
<?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 />
|
||||
<Settings>
|
||||
<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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
|
@ -32,13 +30,13 @@ namespace AssetStudio
|
|||
result = sound.getSubSound(0, out var subsound);
|
||||
if (result != FMOD.RESULT.OK)
|
||||
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)
|
||||
return null;
|
||||
result = subsound.getDefaults(out var frequency, out int priority);
|
||||
if (result != FMOD.RESULT.OK)
|
||||
return null;
|
||||
var SampleRate = (int)frequency;
|
||||
var sampleRate = (int)frequency;
|
||||
result = subsound.getLength(out var length, FMOD.TIMEUNIT.PCMBYTES);
|
||||
if (result != FMOD.RESULT.OK)
|
||||
return null;
|
||||
|
@ -52,11 +50,11 @@ namespace AssetStudio
|
|||
Encoding.UTF8.GetBytes("WAVEfmt ").CopyTo(buffer, 8);
|
||||
BitConverter.GetBytes(16).CopyTo(buffer, 16);
|
||||
BitConverter.GetBytes((short)1).CopyTo(buffer, 20);
|
||||
BitConverter.GetBytes((short)NumChannels).CopyTo(buffer, 22);
|
||||
BitConverter.GetBytes(SampleRate).CopyTo(buffer, 24);
|
||||
BitConverter.GetBytes(SampleRate * NumChannels * BitsPerSample / 8).CopyTo(buffer, 28);
|
||||
BitConverter.GetBytes((short)(NumChannels * BitsPerSample / 8)).CopyTo(buffer, 32);
|
||||
BitConverter.GetBytes((short)BitsPerSample).CopyTo(buffer, 34);
|
||||
BitConverter.GetBytes((short)channels).CopyTo(buffer, 22);
|
||||
BitConverter.GetBytes(sampleRate).CopyTo(buffer, 24);
|
||||
BitConverter.GetBytes(sampleRate * channels * bits / 8).CopyTo(buffer, 28);
|
||||
BitConverter.GetBytes((short)(channels * bits / 8)).CopyTo(buffer, 32);
|
||||
BitConverter.GetBytes((short)bits).CopyTo(buffer, 34);
|
||||
Encoding.UTF8.GetBytes("data").CopyTo(buffer, 36);
|
||||
BitConverter.GetBytes(len1).CopyTo(buffer, 40);
|
||||
Marshal.Copy(ptr1, buffer, 44, (int)len1);
|
|
@ -8,7 +8,7 @@ using SharpDX;
|
|||
|
||||
namespace AssetStudio
|
||||
{
|
||||
class ModelConverter : IImported
|
||||
public class ModelConverter : IImported
|
||||
{
|
||||
public List<ImportedFrame> FrameList { get; protected set; } = new List<ImportedFrame>();
|
||||
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 HashSet<ObjectReader> animationClipHashSet = new HashSet<ObjectReader>();
|
||||
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
|
||||
private Dictionary<ObjectReader, string> textureNameDictionary = new Dictionary<ObjectReader, string>();
|
||||
|
||||
public ModelConverter(GameObject m_GameObject)
|
||||
{
|
||||
|
@ -35,7 +36,7 @@ namespace AssetStudio
|
|||
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))
|
||||
{
|
||||
|
@ -44,9 +45,9 @@ namespace AssetStudio
|
|||
}
|
||||
else
|
||||
InitWithGameObject(m_GameObject);
|
||||
foreach (var assetPreloadData in animationList)
|
||||
foreach (var animationClip in animationList)
|
||||
{
|
||||
animationClipHashSet.Add(assetPreloadData.reader);
|
||||
animationClipHashSet.Add(animationClip);
|
||||
}
|
||||
ConvertAnimations();
|
||||
}
|
||||
|
@ -58,12 +59,12 @@ namespace AssetStudio
|
|||
ConvertAnimations();
|
||||
}
|
||||
|
||||
public ModelConverter(Animator m_Animator, List<AssetItem> animationList)
|
||||
public ModelConverter(Animator m_Animator, ObjectReader[] animationList)
|
||||
{
|
||||
InitWithAnimator(m_Animator);
|
||||
foreach (var assetPreloadData in animationList)
|
||||
foreach (var animationClip in animationList)
|
||||
{
|
||||
animationClipHashSet.Add(assetPreloadData.reader);
|
||||
animationClipHashSet.Add(animationClip);
|
||||
}
|
||||
ConvertAnimations();
|
||||
}
|
||||
|
@ -338,14 +339,14 @@ namespace AssetStudio
|
|||
}
|
||||
}
|
||||
//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] };
|
||||
}
|
||||
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
|
||||
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)
|
||||
{
|
||||
meshR.m_GameObject.TryGetGameObject(out var m_GameObject);
|
||||
|
@ -673,25 +674,55 @@ namespace AssetStudio
|
|||
iMat.TexScales = new Vector2[5];
|
||||
foreach (var texEnv in mat.m_TexEnvs)
|
||||
{
|
||||
Texture2D tex2D = null;
|
||||
if (texEnv.m_Texture.TryGet(out var TexturePD) && TexturePD.type == ClassIDType.Texture2D)//TODO other Texture
|
||||
Texture2D m_Texture2D = null;
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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.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);
|
|
@ -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: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AssetStudioUtility")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyProduct("AssetStudioTools")]
|
||||
[assembly: AssemblyCopyright("Copyright © Perfare 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using dnlib.DotNet;
|
||||
|
||||
namespace AssetStudio
|
||||
|
@ -11,45 +9,14 @@ namespace AssetStudio
|
|||
//TODO unfinished
|
||||
public static class ScriptHelper
|
||||
{
|
||||
public static bool moduleLoaded;
|
||||
public static Dictionary<string, ModuleDef> LoadedModuleDic = new Dictionary<string, ModuleDef>();
|
||||
|
||||
public static string GetScriptString(ObjectReader reader)
|
||||
public static string GetScriptString(ObjectReader reader, Dictionary<string, ModuleDef> moduleDic)
|
||||
{
|
||||
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 sb = CreateMonoBehaviourHeader(m_MonoBehaviour);
|
||||
if (m_MonoBehaviour.m_Script.TryGet(out var 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();
|
||||
}
|
||||
|
@ -153,7 +120,6 @@ namespace AssetStudio
|
|||
}
|
||||
var size = reader.ReadInt32();
|
||||
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}");
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
|
@ -173,7 +139,6 @@ namespace AssetStudio
|
|||
}
|
||||
var size = reader.ReadInt32();
|
||||
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}");
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
|
@ -50,7 +50,7 @@ namespace AssetStudio
|
|||
|
||||
public class ShaderProgram
|
||||
{
|
||||
public ShaderSubProgram[] m_SubPrograms;
|
||||
private ShaderSubProgram[] m_SubPrograms;
|
||||
|
||||
public ShaderProgram(BinaryReader reader)
|
||||
{
|
|
@ -1,14 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
static class SpriteHelper
|
||||
public static class SpriteHelper
|
||||
{
|
||||
public static Bitmap GetImageFromSprite(Sprite m_Sprite)
|
||||
{
|
|
@ -1,11 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
|
@ -16,7 +14,7 @@ namespace AssetStudio
|
|||
private int m_Height;
|
||||
private TextureFormat m_TextureFormat;
|
||||
private int image_data_size;
|
||||
public byte[] image_data;
|
||||
private byte[] image_data;
|
||||
private int[] version;
|
||||
|
||||
//DDS Start
|
||||
|
@ -967,9 +965,9 @@ namespace AssetStudio
|
|||
IntPtr uncompressedData;
|
||||
int uncompressedSize;
|
||||
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.ETC2_RGBA8Crunched) //2017.3 and up
|
||||
|| m_TextureFormat == TextureFormat.ETC2_RGBA8Crunched)
|
||||
{
|
||||
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