Skip to content

Commit

Permalink
Implemented a RegisterTypeInIl2CppWithInterfaces attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
HerpDerpinstine committed Sep 30, 2024
1 parent 89b28f5 commit 1a33c45
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 2 deletions.
3 changes: 2 additions & 1 deletion Dependencies/SupportModules/Il2Cpp/InteropInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.Runtime;
using System;
using System.Reflection;

Expand All @@ -28,6 +27,8 @@ public FieldInfo MethodBaseToIl2CppFieldInfo(MethodBase method)

public void RegisterTypeInIl2CppDomain(Type type, bool logSuccess)
=> ClassInjector.RegisterTypeInIl2Cpp(type, new() { LogSuccess = logSuccess });
public void RegisterTypeInIl2CppDomainWithInterfaces(Type type, Type[] interfaces, bool logSuccess)
=> ClassInjector.RegisterTypeInIl2Cpp(type, new() { LogSuccess = logSuccess, Interfaces = interfaces });

public bool IsInheritedFromIl2CppObjectBase(Type type)
=> (type != null) && type.IsSubclassOf(typeof(Il2CppObjectBase));
Expand Down
87 changes: 87 additions & 0 deletions MelonLoader/Attributes/RegisterTypeInIl2CppWithInterfaces.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace MelonLoader
{
[AttributeUsage(AttributeTargets.Class)]
public class RegisterTypeInIl2CppWithInterfaces : Attribute //Naming violation?
{
internal static List<Assembly> registrationQueue = new List<Assembly>();
internal static bool ready;
internal bool LogSuccess = true;
internal Type[] Interfaces;
internal bool GetInterfacesFromType;

public RegisterTypeInIl2CppWithInterfaces()
{
GetInterfacesFromType = true;
}

public RegisterTypeInIl2CppWithInterfaces(bool logSuccess)
{
LogSuccess = logSuccess;
GetInterfacesFromType = true;
}

public RegisterTypeInIl2CppWithInterfaces(params Type[] interfaces)
{
Interfaces = interfaces;
}

public RegisterTypeInIl2CppWithInterfaces(bool logSuccess, params Type[] interfaces)
{
LogSuccess = logSuccess;
Interfaces = interfaces;
}

public static void RegisterAssembly(Assembly asm)
{
if (!MelonUtils.IsGameIl2Cpp())
return;

if (!ready)
{
registrationQueue.Add(asm);
return;
}

IEnumerable<Type> typeTbl = asm.GetValidTypes();
if ((typeTbl == null) || (typeTbl.Count() <= 0))
return;

foreach (Type type in typeTbl)
{
object[] attTbl = type.GetCustomAttributes(typeof(RegisterTypeInIl2CppWithInterfaces), false);
if ((attTbl == null) || (attTbl.Length <= 0))
continue;

RegisterTypeInIl2CppWithInterfaces att = (RegisterTypeInIl2CppWithInterfaces)attTbl[0];
if (att == null)
continue;

Type[] interfaceArr = att.GetInterfacesFromType
? type.GetInterfaces()
: att.Interfaces;

InteropSupport.RegisterTypeInIl2CppDomainWithInterfaces(type,
interfaceArr,
att.LogSuccess);
}
}

internal static void SetReady()
{
ready = true;

if (registrationQueue == null)
return;

foreach (var asm in registrationQueue)
RegisterAssembly(asm);

registrationQueue = null;
}
}
}
1 change: 1 addition & 0 deletions MelonLoader/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ internal static int Start()

AddUnityDebugLog();
RegisterTypeInIl2Cpp.SetReady();
RegisterTypeInIl2CppWithInterfaces.SetReady();

MelonEvents.MelonHarmonyInit.Invoke();
MelonEvents.OnApplicationStart.Invoke();
Expand Down
1 change: 1 addition & 0 deletions MelonLoader/Melons/MelonAssembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ public void LoadMelons()
}

RegisterTypeInIl2Cpp.RegisterAssembly(Assembly);
RegisterTypeInIl2CppWithInterfaces.RegisterAssembly(Assembly);

if (rottenMelons.Count != 0)
{
Expand Down
20 changes: 19 additions & 1 deletion MelonLoader/Utils/InteropSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public interface Interface
FieldInfo MethodBaseToIl2CppFieldInfo(MethodBase method);
int? GetIl2CppMethodCallerCount(MethodBase method);
void RegisterTypeInIl2CppDomain(Type type, bool logSuccess);
void RegisterTypeInIl2CppDomainWithInterfaces(Type type, Type[] interfaces, bool logSuccess);
IntPtr CopyMethodInfoStruct(IntPtr ptr);
}
internal static Interface SMInterface;
Expand Down Expand Up @@ -89,7 +90,9 @@ public static T Il2CppObjectPtrToIl2CppObject<T>(IntPtr ptr)
return SMInterface.GetIl2CppMethodCallerCount(method);
}

public static void RegisterTypeInIl2CppDomain(Type type) => RegisterTypeInIl2CppDomain(type, true);
public static void RegisterTypeInIl2CppDomain(Type type)
=> RegisterTypeInIl2CppDomain(type, true);

public static void RegisterTypeInIl2CppDomain(Type type, bool logSuccess)
{
ValidateInterface();
Expand All @@ -98,6 +101,21 @@ public static void RegisterTypeInIl2CppDomain(Type type, bool logSuccess)
SMInterface.RegisterTypeInIl2CppDomain(type, logSuccess);
}

public static void RegisterTypeInIl2CppDomainWithInterfaces(Type type, Type[] interfaces)
=> RegisterTypeInIl2CppDomainWithInterfaces(type, interfaces, true);

public static void RegisterTypeInIl2CppDomainWithInterfaces(Type type, Type[] interfaces, bool logSuccess)
{
ValidateInterface();
if (type == null)
throw new NullReferenceException("The type cannot be null.");
if (interfaces == null)
throw new NullReferenceException("The interfaces cannot be null.");
if (interfaces.Length <= 0)
throw new NullReferenceException("The interfaces cannot be empty.");
SMInterface.RegisterTypeInIl2CppDomainWithInterfaces(type, interfaces, logSuccess);
}

public static IntPtr CopyMethodInfoStruct(IntPtr ptr)
{
ValidateInterface();
Expand Down

0 comments on commit 1a33c45

Please sign in to comment.