Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,14 @@ For this .net9 with AoT gets used in combination with a dedicated translation la

- Il2CPPInspector-Redux as additional backend for il2cpp
- using TPK dumps instead of Unity's reference (especially due to this usage of the reference most likely violating the license)

## Test Locally
```bash
dotnet restore
# Change your runtime identifier if needed (e.g. linux-x64, osx-x64, win-x64, etc.)
dotnet publish -c Release -r win-x64
# Build Python bindings
cd bindings\python
# Install
pip install .
```
10 changes: 5 additions & 5 deletions TypeTreeGeneratorAPI/NativeAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ public static int TypeTreeGenerator_freeTreeNodesRaw(IntPtr arrAddr, int arrLeng
return 0;
}

[UnmanagedCallersOnly(EntryPoint = "TypeTreeGenerator_getMonoBehaviorDefinitions")]
public static int TypeTreeGenerator_getMonoBehaviorDefinitions(IntPtr typeTreeGeneratorPtr, IntPtr arrAddrPtr, IntPtr arrLengthPtr)
[UnmanagedCallersOnly(EntryPoint = "TypeTreeGenerator_getClassDefinitions")]
public static int TypeTreeGenerator_getClassDefinitions(IntPtr typeTreeGeneratorPtr, IntPtr arrAddrPtr, IntPtr arrLengthPtr)
{
if (typeTreeGeneratorPtr == IntPtr.Zero)
{
Expand All @@ -219,7 +219,7 @@ public static int TypeTreeGenerator_getMonoBehaviorDefinitions(IntPtr typeTreeGe
{
var handle = (TypeTreeGeneratorHandle)GCHandle.FromIntPtr(typeTreeGeneratorPtr).Target!;

var typeNames = handle.Instance.GetMonoBehaviourDefinitions();
var typeNames = handle.Instance.GetClassDefinitions();

var arrayLength = typeNames.Count;
var arrayPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf<IntPtr>() * arrayLength * 2);
Expand All @@ -244,8 +244,8 @@ public static int TypeTreeGenerator_getMonoBehaviorDefinitions(IntPtr typeTreeGe
}


[UnmanagedCallersOnly(EntryPoint = "TypeTreeGenerator_freeMonoBehaviorDefinitions")]
public static int TypeTreeGenerator_freeMonoBehaviorDefinitions(IntPtr arrAddr, int arrLength)
[UnmanagedCallersOnly(EntryPoint = "TypeTreeGenerator_freeClassDefinitions")]
public static int TypeTreeGenerator_freeClassDefinitions(IntPtr arrAddr, int arrLength)
{
if (arrAddr == IntPtr.Zero)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ public AssetRipperGenerator(string unityVersionString) : base(unityVersionString
return typeConverter.FromSerializableType(monoType);
}

public override List<(string, string)> GetMonoBehaviourDefinitions()
public override List<(string, string)> GetClassDefinitions()
{
var monoBehaviourDefinitions = new List<(string, string)>();
var typedefs = new List<(string, string)>();
foreach (var assembly in assemblyDefinitions.Values)
{
if (assembly.Name is null)
Expand All @@ -53,14 +53,14 @@ public AssetRipperGenerator(string unityVersionString) : base(unityVersionString
{
foreach (var type in module.TopLevelTypes)
{
if (type.IsClass && type.BaseType?.FullName == "UnityEngine.MonoBehaviour")
if (type.IsClass)
{
monoBehaviourDefinitions.Add((assembly.Name, type.FullName));
typedefs.Add((assembly.Name, type.FullName));
}
}
}
}
return monoBehaviourDefinitions;
return typedefs;
}

public override void LoadDll(Stream dllStream)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,17 @@ public override void LoadDll(Stream dllStream)
moduleDic.Add(assembly.MainModule.Name, assembly.MainModule);
}

public override List<(string, string)> GetMonoBehaviourDefinitions()
public override List<(string, string)> GetClassDefinitions()
{
var monoBehaviourDefs = new List<(string, string)>();
var typedefs = new List<(string, string)>();
foreach (var (moduleName, module) in moduleDic)
{
foreach (var type in module.Types)
{
if (IsMonoBehaviour(type))
{
monoBehaviourDefs.Add((moduleName, type.FullName));
}
typedefs.Add((moduleName, type.FullName));
}
}
return monoBehaviourDefs;
return typedefs;
}

public override List<TypeTreeNode>? GenerateTreeNodes(string assemblyName, string fullName)
Expand All @@ -58,28 +55,6 @@ public override void LoadDll(Stream dllStream)
return null;
}

private static bool IsMonoBehaviour(TypeDefinition type)
{
while (type != null)
{
if (type.BaseType == null)
return false;
if (type.BaseType.FullName == "UnityEngine.MonoBehaviour")
return true;
try
{
// Resolve the base type to continue up the hierarchy
type = type.BaseType.Resolve();
}
catch
{
// If we can't resolve, break out
break;
}
}
return false;
}

private List<TypeTreeNode> GenerateTreeNodes(TypeDefinition typeDef)
{
var converter = new TypeDefinitionConverter(typeDef, serializedTypeHelper, 1);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License

using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Unity.CecilTools.Extensions;

namespace Unity.CecilTools
{
public static class CecilUtils
{
public static MethodDefinition FindInTypeExplicitImplementationFor(MethodDefinition interfaceMethod, TypeDefinition typeDefinition)
{
return typeDefinition.Methods.SingleOrDefault(m => m.Overrides.Any(o => o.CheckedResolve().SameAs(interfaceMethod)));
}

public static IEnumerable<TypeDefinition> AllInterfacesImplementedBy(TypeDefinition typeDefinition)
{
return TypeAndBaseTypesOf(typeDefinition).SelectMany(t => t.Interfaces).Select(i => i.InterfaceType.CheckedResolve()).Distinct();
}

public static IEnumerable<TypeDefinition> TypeAndBaseTypesOf(TypeReference typeReference)
{
while (typeReference != null)
{
var typeDefinition = typeReference.CheckedResolve();
yield return typeDefinition;
typeReference = typeDefinition.BaseType;
}
}

public static IEnumerable<TypeDefinition> BaseTypesOf(TypeReference typeReference)
{
return TypeAndBaseTypesOf(typeReference).Skip(1);
}

public static bool IsGenericList(TypeReference type)
{
return type.Name == "List`1" && type.SafeNamespace() == "System.Collections.Generic";
}

public static bool IsGenericDictionary(TypeReference type)
{
if (type is GenericInstanceType)
type = ((GenericInstanceType)type).ElementType;

return type.Name == "Dictionary`2" && type.SafeNamespace() == "System.Collections.Generic";
}

public static TypeReference ElementTypeOfCollection(TypeReference type)
{
var at = type as ArrayType;
if (at != null)
return at.ElementType;

if (IsGenericList(type))
return ((GenericInstanceType)type).GenericArguments.Single();

throw new ArgumentException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License

using System;
using Mono.Cecil;

namespace Unity.CecilTools
{
static public class ElementType
{
public static TypeReference For(TypeReference byRefType)
{
var refType = byRefType as TypeSpecification;
if (refType != null)
return refType.ElementType;

throw new ArgumentException(string.Format("TypeReference isn't a TypeSpecification {0} ", byRefType));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License

using Mono.Cecil;

namespace Unity.CecilTools.Extensions
{
static class MethodDefinitionExtensions
{
public static bool SameAs(this MethodDefinition self, MethodDefinition other)
{
// FIXME: should be able to compare MethodDefinition references directly
return self.FullName == other.FullName;
}

public static string PropertyName(this MethodDefinition self)
{
return self.Name.Substring(4);
}

public static bool IsConversionOperator(this MethodDefinition method)
{
if (!method.IsSpecialName)
return false;

return method.Name == "op_Implicit" || method.Name == "op_Explicit";
}

public static bool IsSimpleSetter(this MethodDefinition original)
{
return original.IsSetter && original.Parameters.Count == 1;
}

public static bool IsSimpleGetter(this MethodDefinition original)
{
return original.IsGetter && original.Parameters.Count == 0;
}

public static bool IsSimplePropertyAccessor(this MethodDefinition method)
{
return method.IsSimpleGetter() || method.IsSimpleSetter();
}

public static bool IsDefaultConstructor(MethodDefinition m)
{
return m.IsConstructor && !m.IsStatic && m.Parameters.Count == 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License

using System;
using Mono.Cecil;

namespace Unity.CecilTools.Extensions
{
public static class ResolutionExtensions
{
public static TypeDefinition CheckedResolve(this TypeReference type)
{
return Resolve(type, reference => reference.Resolve());
}

public static MethodDefinition CheckedResolve(this MethodReference method)
{
return Resolve(method, reference => reference.Resolve());
}

private static TDefinition Resolve<TReference, TDefinition>(TReference reference, Func<TReference, TDefinition> resolve)
where TReference : MemberReference
where TDefinition : class, IMemberDefinition
{
if (reference.Module == null)
throw new ResolutionException(reference);

var definition = resolve(reference);
if (definition == null)
throw new ResolutionException(reference);

return definition;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.Cecil;

namespace Unity.CecilTools.Extensions
{
public static class TypeDefinitionExtensions
{
public static bool IsSubclassOf(this TypeDefinition type, string baseTypeName)
{
var baseType = type.BaseType;
if (baseType == null)
return false;
if (baseType.FullName == baseTypeName)
return true;

var baseTypeDef = baseType.Resolve();
if (baseTypeDef == null)
return false;

return IsSubclassOf(baseTypeDef, baseTypeName);
}

public static bool IsSubclassOf(this TypeDefinition type, params string[] baseTypeNames)
{
var baseType = type.BaseType;
if (baseType == null)
return false;

for (int i = 0; i < baseTypeNames.Length; i++)
if (baseType.FullName == baseTypeNames[i])
return true;

var baseTypeDef = baseType.Resolve();
if (baseTypeDef == null)
return false;

return IsSubclassOf(baseTypeDef, baseTypeNames);
}
}
}
Loading