Skip to content

Commit 0cf9028

Browse files
committed
rewrite & restructure, additional AssetsTools and AssetRipper backends
1 parent d681dcb commit 0cf9028

24 files changed

Lines changed: 787 additions & 336 deletions

.gitmodules

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
[submodule "UnityCsReference"]
22
path = UnityCsReference
33
url = https://github.com/Unity-Technologies/UnityCsReference.git
4+
branch = master
5+
recommendShallow = true
6+
[submodule "AssetRipper"]
7+
path = AssetRipper
8+
url = https://github.com/AssetRipper/AssetRipper.git
9+
branch = master
10+
recommendShallow = true

AssetRipper

Submodule AssetRipper added at 7c98870

TypeTreeGeneratorAPI.sln

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00
44
VisualStudioVersion = 17.13.35806.99
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypeTreeGeneratorAPI", "TypeTreeGeneratorAPI\TypeTreeGeneratorAPI.csproj", "{6B2AB8BA-118B-48D8-A9F9-108BE6368169}"
7+
ProjectSection(ProjectDependencies) = postProject
8+
{A8B1A3B7-0293-4369-C3BA-354513699742} = {A8B1A3B7-0293-4369-C3BA-354513699742}
9+
EndProjectSection
710
EndProject
811
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypeTreeGeneratorCLI", "TypeTreeGeneratorCLI\TypeTreeGeneratorCLI.csproj", "{8CF671FA-5EB5-4629-875F-278497707550}"
912
EndProject
13+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetRipper.SerializationLogic", "AssetRipper\Source\AssetRipper.SerializationLogic\AssetRipper.SerializationLogic.csproj", "{A8B1A3B7-0293-4369-C3BA-354513699742}"
14+
EndProject
1015
Global
1116
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1217
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +26,10 @@ Global
2126
{8CF671FA-5EB5-4629-875F-278497707550}.Debug|Any CPU.Build.0 = Debug|Any CPU
2227
{8CF671FA-5EB5-4629-875F-278497707550}.Release|Any CPU.ActiveCfg = Release|Any CPU
2328
{8CF671FA-5EB5-4629-875F-278497707550}.Release|Any CPU.Build.0 = Release|Any CPU
29+
{A8B1A3B7-0293-4369-C3BA-354513699742}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30+
{A8B1A3B7-0293-4369-C3BA-354513699742}.Debug|Any CPU.Build.0 = Debug|Any CPU
31+
{A8B1A3B7-0293-4369-C3BA-354513699742}.Release|Any CPU.ActiveCfg = Release|Any CPU
32+
{A8B1A3B7-0293-4369-C3BA-354513699742}.Release|Any CPU.Build.0 = Release|Any CPU
2433
EndGlobalSection
2534
GlobalSection(SolutionProperties) = preSolution
2635
HideSolutionNode = FALSE

TypeTreeGeneratorAPI/AssetStudioUtility/MyAssemblyResolver.cs

Lines changed: 0 additions & 12 deletions
This file was deleted.

TypeTreeGeneratorAPI/NativeAPI.cs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
1-
using AssetStudio;
2-
using System.Runtime.InteropServices;
1+
using System.Runtime.InteropServices;
2+
using TypeTreeGeneratorAPI.TypeTreeGenerator;
33

44
namespace TypeTreeGeneratorAPI
55
{
66
public static class NativeAPI
77
{
88
[UnmanagedCallersOnly(EntryPoint = "TypeTreeGenerator_init")]
9-
public static IntPtr TypeTreeGenerator_create(IntPtr unityVersionPtr)
9+
public static IntPtr TypeTreeGenerator_create(IntPtr unityVersionPtr, IntPtr generatorName)
1010
{
1111
string? unityVersion = Marshal.PtrToStringUTF8(unityVersionPtr);
12+
string? generatorNameStr = Marshal.PtrToStringUTF8(generatorName);
1213
if (unityVersion == null)
1314
{
1415
return IntPtr.Zero;
1516
}
1617
try
1718
{
18-
var typeTreeGenerator = new TypeTreeGenerator_AssetStudio(unityVersion);
19-
return GCHandle.ToIntPtr(GCHandle.Alloc(typeTreeGenerator));
19+
var handle = new TypeTreeGeneratorHandle((generatorNameStr != null) ? generatorNameStr : "AssetStudio", unityVersion);
20+
return GCHandle.ToIntPtr(GCHandle.Alloc(handle));
2021
}
21-
catch
22+
catch (Exception ex)
2223
{
23-
return IntPtr.Zero;
24+
Console.WriteLine($"Error creating TypeTreeGenerator: {ex.Message}");
25+
// If the generator type is not recognized, we return IntPtr.Zero to indicate failure.
26+
// This should be handled by the caller to avoid further issues.
27+
Console.WriteLine("Failed to create TypeTreeGenerator instance. Ensure the generator name is correct and supported.");
28+
return IntPtr.Zero;
2429
}
2530
}
2631

@@ -33,14 +38,14 @@ unsafe public static int TypeTreeGenerator_loadDLL(IntPtr typeTreeGeneratorPtr,
3338
}
3439
try
3540
{
36-
var typeTreeGenerator = (TypeTreeGenerator_AssetStudio)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
41+
var handle = (TypeTreeGeneratorHandle)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
3742
using (var stream = new UnmanagedMemoryStream(dllPtr, dllLength, dllLength, FileAccess.ReadWrite))
3843
{
3944
if (stream == null)
4045
{
4146
return -1;
4247
}
43-
typeTreeGenerator.LoadDLL(stream);
48+
handle.Instance.LoadDll(stream);
4449
}
4550
return 0;
4651
}
@@ -61,7 +66,7 @@ unsafe public static int TypeTreeGenerator_loadIL2CPP(IntPtr typeTreeGeneratorPt
6166

6267
try
6368
{
64-
var typeTreeGenerator = (TypeTreeGenerator_AssetStudio)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
69+
var handle = (TypeTreeGeneratorHandle)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
6570
byte[] assemblyData = new byte[assemblyDataLength];
6671
byte[] metadataData = new byte[metadataDataLength];
6772

@@ -74,7 +79,7 @@ unsafe public static int TypeTreeGenerator_loadIL2CPP(IntPtr typeTreeGeneratorPt
7479
Buffer.MemoryCopy(metadataDataPtr, managedPtr, metadataDataLength, metadataDataLength);
7580
}
7681

77-
typeTreeGenerator.LoadIL2CPP(assemblyData, metadataData);
82+
handle.Instance.LoadIl2Cpp(assemblyData, metadataData);
7883
return 0;
7984
}
8085
catch
@@ -115,9 +120,9 @@ public static int TypeTreeGenerator_generateTypeTreeNodesJson(IntPtr typeTreeGen
115120
}
116121
try
117122
{
118-
var typeTreeGenerator = (TypeTreeGenerator_AssetStudio)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
123+
var handle = (TypeTreeGeneratorHandle)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
119124

120-
var typeTreeNodes = typeTreeGenerator.GenerateTreeNodes(assemblyName, fullName);
125+
var typeTreeNodes = handle.Instance.GenerateTreeNodes(assemblyName, fullName);
121126
if (typeTreeNodes == null)
122127
{
123128
return -1;
@@ -144,8 +149,8 @@ public static int TypeTreeGenerator_generateTypeTreeNodesRaw(IntPtr typeTreeGene
144149
}
145150
try
146151
{
147-
var typeTreeGenerator = (TypeTreeGenerator_AssetStudio)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
148-
var typeTreeNodes = typeTreeGenerator.GenerateTreeNodes(assemblyName, fullName);
152+
var handle = (TypeTreeGeneratorHandle)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
153+
var typeTreeNodes = handle.Instance.GenerateTreeNodes(assemblyName, fullName);
149154
if (typeTreeNodes == null)
150155
{
151156
return -1;
@@ -187,9 +192,9 @@ public static int TypeTreeGenerator_getMonoBehaviorDefinitions(IntPtr typeTreeGe
187192
}
188193
try
189194
{
190-
var typeTreeGenerator = (TypeTreeGenerator_AssetStudio)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
195+
var handle = (TypeTreeGeneratorHandle)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;
191196

192-
var typeNames = typeTreeGenerator.GetMonoBehaviourDefinitions();
197+
var typeNames = handle.Instance.GetMonoBehaviourDefinitions();
193198

194199
var arrayLength = typeNames.Count;
195200
var arrayPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf<IntPtr>() * arrayLength * 2);

TypeTreeGeneratorAPI/TypeTreeGenerator.cs

Lines changed: 0 additions & 94 deletions
This file was deleted.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using AsmResolver.DotNet;
2+
using AsmResolver.PE.File;
3+
using AssetRipper.Primitives;
4+
using AssetRipper.SerializationLogic;
5+
using Cpp2IL.Core.Extensions;
6+
7+
namespace TypeTreeGeneratorAPI.TypeTreeGenerator.AssetRipper
8+
{
9+
public class AssetRipperGenerator : TypeTreeGenerator
10+
{
11+
protected Dictionary<string, AssemblyDefinition> assemblyDefinitions => assemblyResolver.assemblyDefinitions;
12+
private Dictionary<ITypeDefOrRef, SerializableType> monoTypeCache = new();
13+
private Il2CppHandler.AssemblyResolver assemblyResolver = new();
14+
private SerializableTypeConverter typeConverter;
15+
16+
protected override bool supportsIl2Cpp => true;
17+
18+
public AssetRipperGenerator(string unityVersionString) : base(unityVersionString)
19+
{
20+
typeConverter = new SerializableTypeConverter(this.unityVersion);
21+
}
22+
23+
public override List<TypeTreeNode>? GenerateTreeNodes(string assemblyName, string fullName)
24+
{
25+
int lastDot = fullName.LastIndexOf('.');
26+
var nameSpace = lastDot == -1 ? "" : fullName.Substring(0, lastDot);
27+
var className = lastDot == -1 ? fullName : fullName.Substring(lastDot + 1);
28+
29+
30+
var type = FindType(assemblyName, nameSpace, className);
31+
var monoType = default(SerializableType?);
32+
string? failureReason = null;
33+
if (!new FieldSerializer(new UnityVersion(6000)).TryCreateSerializableType(type, monoTypeCache, out monoType, out failureReason))
34+
{
35+
throw new InvalidOperationException($"Failed to create SerializableType: {failureReason}");
36+
}
37+
38+
return typeConverter.FromSerializableType(monoType);
39+
}
40+
41+
public override List<(string, string)> GetMonoBehaviourDefinitions()
42+
{
43+
var monoBehaviourDefinitions = new List<(string, string)>();
44+
foreach (var assembly in assemblyDefinitions.Values)
45+
{
46+
foreach (var module in assembly.Modules)
47+
{
48+
foreach (var type in module.TopLevelTypes)
49+
{
50+
if (type.IsClass && type.BaseType?.FullName == "UnityEngine.MonoBehaviour")
51+
{
52+
monoBehaviourDefinitions.Add((assembly.Name, type.FullName));
53+
}
54+
}
55+
}
56+
}
57+
return monoBehaviourDefinitions;
58+
}
59+
60+
public override void LoadDll(Stream dllStream)
61+
{
62+
LoadDll(dllStream.ReadBytes());
63+
}
64+
65+
public override void LoadDll(byte[] dllData)
66+
{
67+
var pefile = PEFile.FromBytes(dllData);
68+
var assembly = AssemblyDefinition.FromFile(pefile);
69+
loadAssembly(assembly);
70+
}
71+
72+
public override void LoadIl2Cpp(byte[] assemblyData, byte[] metadataData)
73+
{
74+
base.LoadIl2Cpp(assemblyData, metadataData);
75+
foreach (var assembly in Il2CppHandler.GenerateAssemblyDefinitions().Values)
76+
{
77+
loadAssembly(assembly);
78+
}
79+
}
80+
81+
private void loadAssembly(AssemblyDefinition assembly)
82+
{
83+
assemblyResolver.assemblyDefinitions[assembly.Name] = assembly;
84+
foreach (ModuleDefinition module in assembly.Modules)
85+
{
86+
module.MetadataResolver = new DefaultMetadataResolver(assemblyResolver);
87+
}
88+
}
89+
90+
private TypeDefinition? FindType(string assembly, string @namespace, string name)
91+
{
92+
AssemblyDefinition? definition = assemblyDefinitions[assembly];
93+
if (definition == null)
94+
{
95+
return null;
96+
}
97+
98+
foreach (ModuleDefinition module in definition.Modules)
99+
{
100+
TypeDefinition? type = GetType(module, @namespace, name);
101+
if (type != null)
102+
{
103+
return type;
104+
}
105+
}
106+
return null;
107+
}
108+
109+
private static TypeDefinition? GetType(ModuleDefinition module, string @namespace, string name)
110+
{
111+
IList<TypeDefinition> types = module.TopLevelTypes;
112+
foreach (TypeDefinition type in types)
113+
{
114+
if ((type.Namespace ?? "") == @namespace && type.Name == name)
115+
{
116+
return type;
117+
}
118+
}
119+
120+
return null;
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)