Add quick and dirty path extractor
This commit is contained in:
parent
3e77c34bd5
commit
682745177b
|
@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Texture2DDecoderWrapper", "
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio.PInvoke", "AssetStudio.PInvoke\AssetStudio.PInvoke.csproj", "{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio.PInvoke", "AssetStudio.PInvoke\AssetStudio.PInvoke.csproj", "{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PathIDExtractor", "PathIDExtractor\PathIDExtractor.csproj", "{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -131,6 +133,18 @@ Global
|
||||||
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x64.Build.0 = Release|Any CPU
|
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x86.ActiveCfg = Release|Any CPU
|
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x86.Build.0 = Release|Any CPU
|
{40C796B5-88CE-4ADC-ACD6-2F4862B7F136}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?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>{D8AE6E83-EC67-47E3-8DAD-8BA96A67B5E8}</ProjectGuid>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<RootNamespace>PathIDExtractor</RootNamespace>
|
||||||
|
<AssemblyName>PathIDExtractor</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<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' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
|
||||||
|
<Project>{7662f8c2-7bfd-442e-a948-a43b4f7eb06e}</Project>
|
||||||
|
<Name>AssetStudio</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
|
@ -0,0 +1,128 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using AssetStudio;
|
||||||
|
|
||||||
|
namespace PathIDExtractor
|
||||||
|
{
|
||||||
|
struct ParsedObject
|
||||||
|
{
|
||||||
|
public readonly long pathId;
|
||||||
|
public readonly string type;
|
||||||
|
public string name;
|
||||||
|
|
||||||
|
public ParsedObject(long pathId, string type)
|
||||||
|
{
|
||||||
|
this.pathId = pathId;
|
||||||
|
this.type = type;
|
||||||
|
name = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() => $"{pathId},{type},{(name is null ? "" : name)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
private static string pathIdsFilePath;
|
||||||
|
private static string containersFilePath;
|
||||||
|
|
||||||
|
static void ParseObjects (List<AssetStudio.Object> objects)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* As objects have no particular order and some objects hold other objects,
|
||||||
|
* and we want to keep a reference to each object's container,
|
||||||
|
* we will keep all the parsed objects and all the containers we find for those objects,
|
||||||
|
* then re-link them at the end.
|
||||||
|
*/
|
||||||
|
var parsedObjects = new Dictionary<AssetStudio.Object, ParsedObject>(objects.Count);
|
||||||
|
var containers = new List<(PPtr<AssetStudio.Object>, string)>();
|
||||||
|
|
||||||
|
foreach (var asset in objects)
|
||||||
|
{
|
||||||
|
var parsedObject = new ParsedObject(asset.m_PathID, asset.type.ToString());
|
||||||
|
// Find the name of an object depending on its type
|
||||||
|
switch (asset)
|
||||||
|
{
|
||||||
|
case Shader m_Shader:
|
||||||
|
parsedObject.name = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
|
||||||
|
break;
|
||||||
|
case Animator m_Animator:
|
||||||
|
if (m_Animator.m_GameObject.TryGet(out var gameObject)) parsedObject.name = gameObject.m_Name;
|
||||||
|
break;
|
||||||
|
case MonoBehaviour m_MonoBehaviour:
|
||||||
|
if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var m_Script)) parsedObject.name = m_Script.m_ClassName;
|
||||||
|
else parsedObject.name = m_MonoBehaviour.m_Name;
|
||||||
|
break;
|
||||||
|
case AssetBundle m_AssetBundle:
|
||||||
|
foreach (var m_Container in m_AssetBundle.m_Container)
|
||||||
|
{
|
||||||
|
var preloadIndex = m_Container.Value.preloadIndex;
|
||||||
|
var preloadSize = m_Container.Value.preloadSize;
|
||||||
|
var preloadEnd = preloadIndex + preloadSize;
|
||||||
|
for (int k = preloadIndex; k < preloadEnd; k++)
|
||||||
|
{
|
||||||
|
containers.Add((m_AssetBundle.m_PreloadTable[k], m_Container.Key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parsedObject.name = m_AssetBundle.m_Name;
|
||||||
|
break;
|
||||||
|
case ResourceManager m_ResourceManager:
|
||||||
|
foreach (var m_Container in m_ResourceManager.m_Container)
|
||||||
|
{
|
||||||
|
containers.Add((m_Container.Value, m_Container.Key));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NamedObject namedObject:
|
||||||
|
parsedObject.name = namedObject.m_Name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parsedObjects.Add(asset, parsedObject);
|
||||||
|
}
|
||||||
|
File.AppendAllText(pathIdsFilePath, String.Join("\n", parsedObjects.Values.Select(obj => obj.ToString())) + "\n");
|
||||||
|
File.AppendAllText(containersFilePath, String.Join("\n", containers.Select(tuple => tuple.Item1.TryGet(out var obj) ? $"{obj.m_PathID},{tuple.Item2}" : null).Where(output => output != null)) + "\n");
|
||||||
|
Console.WriteLine($"Parsed {parsedObjects.Count} values");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Console.Title = "Path ID Extractor";
|
||||||
|
Console.BackgroundColor = ConsoleColor.DarkRed;
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
Console.Clear();
|
||||||
|
Console.WriteLine("--- lucidiot's path ID extractor ---");
|
||||||
|
|
||||||
|
string basePath;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Console.WriteLine("Enter the base path of all Unity data files to analyze:");
|
||||||
|
basePath = Path.GetFullPath(Console.ReadLine());
|
||||||
|
} while (!Directory.Exists(basePath));
|
||||||
|
|
||||||
|
var files = Directory.GetFiles(basePath, "*.*", SearchOption.AllDirectories);
|
||||||
|
Console.WriteLine($"{files.Length} files to parse");
|
||||||
|
|
||||||
|
string baseOutputPath;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Console.WriteLine("Enter the base output path:");
|
||||||
|
baseOutputPath = Path.GetFullPath(Console.ReadLine());
|
||||||
|
} while (!Directory.Exists(baseOutputPath));
|
||||||
|
pathIdsFilePath = Path.Combine(baseOutputPath, "path_ids.csv");
|
||||||
|
containersFilePath = Path.Combine(baseOutputPath, "containers.csv");
|
||||||
|
|
||||||
|
Console.WriteLine($"Outputting to {pathIdsFilePath} and {containersFilePath}");
|
||||||
|
File.WriteAllText(pathIdsFilePath, "path_id,type,name\n");
|
||||||
|
File.WriteAllText(containersFilePath, "path_id,container\n");
|
||||||
|
|
||||||
|
var manager = new AssetsManager();
|
||||||
|
foreach (var filePath in files)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Loading {filePath.Substring(basePath.Length)}");
|
||||||
|
manager.LoadFiles(filePath);
|
||||||
|
manager.assetsFileList.ForEach(file => ParseObjects(file.Objects));
|
||||||
|
manager.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Les informations générales relatives à un assembly dépendent de
|
||||||
|
// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations
|
||||||
|
// associées à un assembly.
|
||||||
|
[assembly: AssemblyTitle("PathIDExtractor")]
|
||||||
|
[assembly: AssemblyDescription("PathID extractor from Unity asset bundles")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("PathIDExtractor")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © Lucidiot 2020")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly
|
||||||
|
// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de
|
||||||
|
// COM, affectez la valeur true à l'attribut ComVisible sur ce type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM
|
||||||
|
[assembly: Guid("d8ae6e83-ec67-47e3-8dad-8ba96a67b5e8")]
|
||||||
|
|
||||||
|
// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
|
||||||
|
//
|
||||||
|
// Version principale
|
||||||
|
// Version secondaire
|
||||||
|
// Numéro de build
|
||||||
|
// Révision
|
||||||
|
//
|
||||||
|
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
|
||||||
|
// en utilisant '*', comme indiqué ci-dessous :
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
Loading…
Reference in New Issue