Decompiled source of NuclearLibrary v1.0.7

BepInEx/plugins/NuclearLib.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using NuclearLib.ModContent;
using NuclearLib.Patches;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("NuclearLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NuclearLib")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0034b6e9-e4ca-48f1-8cf2-5f898fdd0ce1")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace NuclearLib
{
	[BepInPlugin("niceh.NuclearLib", "NuclearLib", "1.0.7")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "niceh.NuclearLib";

		public const string Name = "NuclearLib";

		private static Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static Dictionary<Type, List<Type>> ModBehaviours { get; private set; } = new Dictionary<Type, List<Type>>();


		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("niceh.NuclearLib");
			_harmony.PatchAll(typeof(Patch_EnemyAI));
			_harmony.PatchAll(typeof(Patch_GrabbableObject));
			_harmony.PatchAll(typeof(Patch_PlayerControllerB));
		}

		public static void RegisterModBehaviour<T>(Type behaviourType) where T : ModBehaviour
		{
			if (ModBehaviours.TryGetValue(behaviourType, out var value))
			{
				value.Add(typeof(T));
			}
			else
			{
				ModBehaviours.Add(behaviourType, new List<Type> { typeof(T) });
			}
			Log.LogInfo((object)("Registered ModBehaviour [" + typeof(T).FullName + "]"));
			ApplyPatch(behaviourType);
		}

		private static void ApplyPatch(Type type)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_007d: Expected O, but got Unknown
			MethodInfo nextMethod = GetNextMethod(type, "Start");
			if (nextMethod == null)
			{
				Log.LogWarning((object)$"Failed to patch {type}.");
			}
			else if (!IsMethodPatched(nextMethod))
			{
				_harmony.Patch((MethodBase)nextMethod, new HarmonyMethod(typeof(Patch_NetworkBehaviour), "PreStart", new Type[1] { type }), new HarmonyMethod(typeof(Patch_NetworkBehaviour), "PostStart", new Type[1] { type }), (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static MethodInfo GetNextMethod(Type type, string methodName)
		{
			while (type != null && type != typeof(object))
			{
				MethodInfo method = type.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
				if (method != null)
				{
					return method;
				}
				type = type.BaseType;
			}
			return null;
		}

		private static bool IsMethodPatched(MethodInfo method)
		{
			Patches patchInfo = Harmony.GetPatchInfo((MethodBase)method);
			if (patchInfo == null)
			{
				return false;
			}
			if (!patchInfo.Prefixes.Any((Patch p) => p.owner == _harmony.Id))
			{
				return patchInfo.Postfixes.Any((Patch p) => p.owner == _harmony.Id);
			}
			return true;
		}
	}
}
namespace NuclearLib.Patches
{
	internal static class Patch_EnemyAI
	{
		[HarmonyPatch(typeof(EnemyAI), "DoAIInterval")]
		[HarmonyPrefix]
		private static void PreDoAIInterval(EnemyAI __instance)
		{
			ModAI[] components = ((Component)__instance).gameObject.GetComponents<ModAI>();
			for (int i = 0; i < components.Length; i++)
			{
				components[i].PreAI();
			}
		}

		[HarmonyPatch(typeof(EnemyAI), "DoAIInterval")]
		[HarmonyPostfix]
		private static void PostDoAIInterval(EnemyAI __instance)
		{
			ModAI[] components = ((Component)__instance).gameObject.GetComponents<ModAI>();
			for (int i = 0; i < components.Length; i++)
			{
				components[i].PostAI();
			}
		}

		[HarmonyPatch(typeof(EnemyAI), "KillEnemy")]
		[HarmonyPrefix]
		private static bool PreKillEnemy(EnemyAI __instance, bool destroy)
		{
			bool flag = true;
			ModAI[] components = ((Component)__instance).gameObject.GetComponents<ModAI>();
			foreach (ModAI modAI in components)
			{
				flag = flag && modAI.PreKillEnemy(destroy);
			}
			return flag;
		}

		[HarmonyPatch(typeof(EnemyAI), "KillEnemy")]
		[HarmonyPostfix]
		private static void PostKillEnemy(EnemyAI __instance, bool destroy)
		{
			ModAI[] components = ((Component)__instance).gameObject.GetComponents<ModAI>();
			for (int i = 0; i < components.Length; i++)
			{
				components[i].PostKillEnemy(destroy);
			}
		}
	}
	internal static class Patch_GrabbableObject
	{
		[HarmonyPatch(typeof(GrabbableObject), "ItemActivate")]
		[HarmonyPrefix]
		private static bool PreItemActivate(ExtensionLadderItem __instance, bool used, bool buttonDown)
		{
			bool flag = true;
			ModItem[] components = ((Component)__instance).gameObject.GetComponents<ModItem>();
			foreach (ModItem modItem in components)
			{
				flag = flag && modItem.PreItemActivate(used, buttonDown);
			}
			return flag;
		}

		[HarmonyPatch(typeof(GrabbableObject), "ItemActivate")]
		[HarmonyPostfix]
		private static void PostItemActivate(ExtensionLadderItem __instance, bool used, bool buttonDown)
		{
			ModItem[] components = ((Component)__instance).gameObject.GetComponents<ModItem>();
			for (int i = 0; i < components.Length; i++)
			{
				components[i].PreItemActivate(used, buttonDown);
			}
		}
	}
	internal static class Patch_NetworkBehaviour
	{
		private static void PreStart(NetworkBehaviour __instance)
		{
			foreach (KeyValuePair<Type, List<Type>> modBehaviour in Plugin.ModBehaviours)
			{
				if (!modBehaviour.Key.IsAssignableFrom(((object)__instance).GetType()))
				{
					continue;
				}
				foreach (Type item in modBehaviour.Value)
				{
					ModBehaviour obj = (ModBehaviour)(object)((Component)__instance).gameObject.AddComponent(item);
					obj.Original = __instance;
					obj.PreStart();
				}
			}
		}

		private static void PostStart(NetworkBehaviour __instance)
		{
			ModBehaviour[] components = ((Component)__instance).gameObject.GetComponents<ModBehaviour>();
			for (int i = 0; i < components.Length; i++)
			{
				components[i].PostStart();
			}
		}
	}
	public static class Patch_PlayerControllerB
	{
	}
}
namespace NuclearLib.ModContent
{
	public class ModAI : ModBehaviour
	{
		public virtual void PreAI()
		{
		}

		public virtual void PostAI()
		{
		}

		public virtual bool PreKillEnemy(bool destroy = false)
		{
			return true;
		}

		public virtual void PostKillEnemy(bool destroy = false)
		{
		}
	}
	public class ModBehaviour : NetworkBehaviour
	{
		public NetworkBehaviour Original { get; set; }

		public virtual void PreStart()
		{
		}

		public virtual void PostStart()
		{
		}
	}
	public class ModItem : ModBehaviour
	{
		public virtual bool PreItemActivate(bool used, bool buttonDown)
		{
			return true;
		}

		public virtual void PostItemActivate(bool used, bool buttonDown)
		{
		}
	}
	public class ModPlayer : ModBehaviour
	{
	}
}