BepInEx / Il2CppInterop

A tool interoperate between CoreCLR and Il2Cpp at runtime
GNU Lesser General Public License v3.0
185 stars 59 forks source link

Remember injected types and reuse in GetIl2CppTypeFullName #103

Open sir0x1 opened 11 months ago

sir0x1 commented 11 months ago

Injecting a class derived from an existing generic class with a virtual method using the generic type as parameter currently doesn't work.

I had to fix some void* handling for this sample to work as well.

Can be reprodused with this sample plugin:

using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.Injection;
using System;
using UnityEngine.InputSystem;

namespace Test;

[BepInPlugin("Test", "Test", "0.0.1")]
public class Plugin : BasePlugin
{
    internal static new ManualLogSource Log;

    public override void Load()
    {
        Log = base.Log;

        ClassInjector.RegisterTypeInIl2Cpp<Haptic>();
        ClassInjector.RegisterTypeInIl2Cpp<HapticControl>();

        Log.LogInfo($"Plugin 'Test' is loaded!");
    }

    public class Haptic : Il2CppSystem.Object
    {
        public Haptic()
            : base(ClassInjector.DerivedConstructorPointer<Haptic>()) { }

        public Haptic(IntPtr pointer)
            : base(pointer) { }

    }

    public class HapticControl : InputControl<Haptic>
    {
        public override unsafe Haptic ReadUnprocessedValueFromState(void* statePtr) => new Haptic();
        public override unsafe Il2CppSystem.Object ReadValueFromBufferAsObject(void* buffer, int bufferSize) => null;
        public override unsafe void ReadValueFromStateIntoBuffer(void* statePtr, void* bufferPtr, int bufferSize) { }
        public override unsafe Il2CppSystem.Object ReadValueFromStateAsObject(void* statePtr) => null;
        public override unsafe void WriteValueFromBufferIntoState(void* bufferPtr, int bufferSize, void* statePtr) { }
        public override unsafe void WriteValueFromObjectIntoState(Il2CppSystem.Object value, void* statePtr) { }
        public override unsafe bool CompareValue(void* firstStatePtr, void* secondStatePtr) => false;
        public override unsafe void WriteValueIntoState(Haptic value, void* statePtr) { }
    }
}

Before: grafik

After: grafik

js6pak commented 5 months ago

What was the use case for this change?

sir0x1 commented 5 months ago

I forgott to fill the description sorry. Had a small discussion about this in the discord: injecting a class derived from an existing generic class, with a virtual method using the generic type as parameter currently doesn't work because assembly.Name.Name is set to "InjectedMonoTypes" by ClassInjector. Is there an easy way to get the System.Type of an injected Type? Il2CppClassPointerStore is only viable for System.Type -> ClassPtr at the moment.

The discrod link for reference: https://discord.com/channels/623153565053222947/985596870229385256/1146049966444384336

sir0x1 commented 5 months ago

Updated the description