diff --git a/AmongUs.props b/AmongUs.props
index 2cf081b..55b3d8e 100644
--- a/AmongUs.props
+++ b/AmongUs.props
@@ -14,7 +14,7 @@
-
+
diff --git a/Reactor.Debugger/DebuggerPlugin.cs b/Reactor.Debugger/DebuggerPlugin.cs
index b88bafd..d0e6fa6 100644
--- a/Reactor.Debugger/DebuggerPlugin.cs
+++ b/Reactor.Debugger/DebuggerPlugin.cs
@@ -24,8 +24,6 @@ namespace Reactor.Debugger
public override void Load()
{
- RegisterInIl2CppAttribute.Register();
-
var gameObject = new GameObject(nameof(DebuggerPlugin)).DontDestroy();
Component = gameObject.AddComponent();
diff --git a/Reactor.Example/ExamplePlugin.cs b/Reactor.Example/ExamplePlugin.cs
index 72ef050..2ffa382 100644
--- a/Reactor.Example/ExamplePlugin.cs
+++ b/Reactor.Example/ExamplePlugin.cs
@@ -17,9 +17,6 @@ namespace Reactor.Example
public override void Load()
{
- RegisterInIl2CppAttribute.Register();
- RegisterCustomRpcAttribute.Register(this);
-
var gameObject = new GameObject(nameof(ReactorPlugin)).DontDestroy();
gameObject.AddComponent().Plugin = this;
}
diff --git a/Reactor/ChainloaderHooks.cs b/Reactor/ChainloaderHooks.cs
new file mode 100644
index 0000000..2eb6b5c
--- /dev/null
+++ b/Reactor/ChainloaderHooks.cs
@@ -0,0 +1,34 @@
+using System.Collections.Generic;
+using System.Reflection.Emit;
+using BepInEx.IL2CPP;
+using HarmonyLib;
+
+namespace Reactor
+{
+ public static class ChainloaderHooks
+ {
+ public delegate void PluginLoadHandler(BasePlugin plugin);
+
+ public static event PluginLoadHandler PluginLoad;
+
+ internal static void OnPluginLoad(BasePlugin plugin)
+ {
+ PluginLoad?.Invoke(plugin);
+ }
+
+ [HarmonyPatch(typeof(IL2CPPChainloader), nameof(IL2CPPChainloader.LoadPlugin))]
+ private static class LoadPluginPatch
+ {
+ public static IEnumerable Transpiler(IEnumerable instructions)
+ {
+ return new CodeMatcher(instructions)
+ .MatchForward(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(BasePlugin), nameof(BasePlugin.Load))))
+ .Insert(
+ new CodeInstruction(OpCodes.Dup),
+ new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ChainloaderHooks), nameof(OnPluginLoad)))
+ )
+ .InstructionEnumeration();
+ }
+ }
+ }
+}
diff --git a/Reactor/PluginSingleton.cs b/Reactor/PluginSingleton.cs
index 5a93640..a051367 100644
--- a/Reactor/PluginSingleton.cs
+++ b/Reactor/PluginSingleton.cs
@@ -1,5 +1,5 @@
-using System;
using System.Linq;
+using System.Reflection;
using BepInEx.IL2CPP;
namespace Reactor
@@ -8,19 +8,16 @@ namespace Reactor
{
private static T _instance;
- public static T Instance
+ public static T Instance => _instance ??= IL2CPPChainloader.Instance.Plugins.Values.Select(x => x.Instance).OfType().Single();
+
+ internal static void Initialize()
{
- get => _instance ??= IL2CPPChainloader.Instance.Plugins.Values.Select(x => x.Instance).OfType().Single();
-
- set
+ ChainloaderHooks.PluginLoad += plugin =>
{
- if (_instance != null)
- {
- throw new Exception($"Instance for {typeof(T).FullName} is already set");
- }
-
- _instance = value;
- }
+ typeof(PluginSingleton<>).MakeGenericType(plugin.GetType())!
+ .GetField(nameof(_instance), BindingFlags.Static | BindingFlags.NonPublic)!
+ .SetValue(null, plugin);
+ };
}
}
}
diff --git a/Reactor/ReactorPlugin.cs b/Reactor/ReactorPlugin.cs
index a17f6b9..75fe6e3 100644
--- a/Reactor/ReactorPlugin.cs
+++ b/Reactor/ReactorPlugin.cs
@@ -27,17 +27,25 @@ namespace Reactor
private GameObject _gameObject;
private RegionInfoWatcher RegionInfoWatcher { get; } = new RegionInfoWatcher();
+ public ReactorPlugin()
+ {
+ PluginSingleton.Initialize();
+ RegisterInIl2CppAttribute.Initialize();
+ RegisterCustomRpcAttribute.Initialize();
+
+ ChainloaderHooks.OnPluginLoad(this);
+ }
+
public override void Load()
{
- RegisterInIl2CppAttribute.Register();
-
AllowVanillaServers = Config.Bind("Features", "Allow vanilla servers", false, "Whether reactor should ignore servers not responding to modded handshake. This config is ignored if any plugin uses custom rpcs!");
+ Harmony.PatchAll();
+
_gameObject = new GameObject(nameof(ReactorPlugin)).DontDestroy();
_gameObject.AddComponent().Plugin = this;
_gameObject.AddComponent();
- Harmony.PatchAll();
ReactorVersionShower.Initialize();
SplashSkip.Initialize();
DefaultBundle.Load();
@@ -62,6 +70,11 @@ namespace Reactor
{
}
+ private void OnRenderImage(RenderTexture src, RenderTexture dest)
+ {
+ Plugin.Log.LogWarning(src.GetInstanceID());
+ }
+
private void Update()
{
if (Plugin.RegionInfoWatcher.Reload)
diff --git a/Reactor/RegisterCustomRpcAttribute.cs b/Reactor/RegisterCustomRpcAttribute.cs
index 09f144a..c32f00a 100644
--- a/Reactor/RegisterCustomRpcAttribute.cs
+++ b/Reactor/RegisterCustomRpcAttribute.cs
@@ -19,9 +19,9 @@ namespace Reactor
Id = id;
}
+ [Obsolete("You don't need to call this anymore", true)]
public static void Register(BasePlugin plugin)
{
- Register(Assembly.GetCallingAssembly(), plugin);
}
public static void Register(Assembly assembly, BasePlugin plugin)
@@ -42,5 +42,10 @@ namespace Reactor
}
}
}
+
+ internal static void Initialize()
+ {
+ ChainloaderHooks.PluginLoad += plugin => Register(plugin.GetType().Assembly, plugin);
+ }
}
}
diff --git a/Reactor/RegisterInIl2CppAttribute.cs b/Reactor/RegisterInIl2CppAttribute.cs
index 43842ed..1a7b5b5 100644
--- a/Reactor/RegisterInIl2CppAttribute.cs
+++ b/Reactor/RegisterInIl2CppAttribute.cs
@@ -7,14 +7,14 @@ using UnhollowerRuntimeLib;
namespace Reactor
{
///
- /// Utility attribute for automatically calling
+ /// Utility attribute for automatically calling
///
[AttributeUsage(AttributeTargets.Class)]
public class RegisterInIl2CppAttribute : Attribute
{
+ [Obsolete("You don't need to call this anymore", true)]
public static void Register()
{
- Register(Assembly.GetCallingAssembly());
}
private static readonly AccessTools.FieldRef