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
{
}
}