Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MonitorEnemies v1.5.0
NoteBoxz.MonitorEnemies.dll
Decompiled 10 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using LCMoniterEnemies.Patches; using Microsoft.CodeAnalysis; using OpenBodyCams; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("NoteBoxz.MonitorEnemies")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.5.0.0")] [assembly: AssemblyInformationalVersion("1.5.0+bf869a25a81b73caebcd5c45ef1dd44933c6e202")] [assembly: AssemblyProduct("LCMoniterEnemies")] [assembly: AssemblyTitle("NoteBoxz.MonitorEnemies")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LCMoniterEnemies { public class EnemyPos : MonoBehaviour { public EnemyAI Root = null; public TransformAndName TnN = null; public Transform? BodyCamPoint = null; public static Dictionary<EnemyType, Transform> BodyCamPoints = new Dictionary<EnemyType, Transform>(); public void OnDestroy() { ManualCameraRendererPatch.RemoveEnemyFromRadarTargets(this); } public void LateUpdate() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.localPosition = new Vector3(LCMoniterEnemies.TargetXoffset.Value, LCMoniterEnemies.TargetYoffset.Value, LCMoniterEnemies.TargetZoffset.Value); } public void Update() { if (Root.isEnemyDead && LCMoniterEnemies.AutoSwitchOnEnemyDeath.Value) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Start() { if (LCMoniterEnemies.CreateBodyCam.Value) { if (BodyCamPoints.ContainsKey(Root.enemyType)) { BodyCamPoint = BodyCamPoints[Root.enemyType]; } else if ((Object)(object)((Component)this).transform.parent != (Object)null) { BodyCamPoint = GetOrCreateBodyCamPoint(((Component)((Component)this).transform.parent).gameObject); } } } public static Transform? GetOrCreateBodyCamPoint(GameObject obj) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) Transform[] componentsInChildren = obj.GetComponentsInChildren<Transform>(false); NavMeshAgent componentInChildren = obj.GetComponentInChildren<NavMeshAgent>(); Transform[] array = componentsInChildren; foreach (Transform val in array) { if (!((Component)val).gameObject.activeSelf) { continue; } string text = ((Object)((Component)val).gameObject).name.ToLower(); if (text.Contains("head") || text.Contains("h_j000") || text.Contains("f_j001")) { GameObject val2 = new GameObject("BodyCamPoint"); val2.transform.SetParent(val); if ((Object)(object)componentInChildren != (Object)null) { val2.transform.rotation = Quaternion.LookRotation(((Component)componentInChildren).transform.forward); Vector3 localPosition = ((Component)componentInChildren).transform.forward * componentInChildren.radius * 0.1f; localPosition.y = ((Component)val).transform.localPosition.y; val2.transform.localPosition = localPosition; } ManualLogSource logger = LCMoniterEnemies.Logger; string name = ((Object)obj).name; object arg = val2.transform.localPosition; Quaternion localRotation = val2.transform.localRotation; logger.LogDebug((object)$"Created BodyCamPoint for {name} at {arg}, {((Quaternion)(ref localRotation)).eulerAngles}"); return val2.transform; } } return null; } } [BepInPlugin("NoteBoxz.MonitorEnemies", "LCMoniterEnemies", "1.5.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LCMoniterEnemies : BaseUnityPlugin { public static List<EnemyType> EnemyTypes = (from e in Resources.FindObjectsOfTypeAll<EnemyType>() where (Object)(object)e.enemyPrefab != (Object)null group e by e.enemyPrefab into g select g.First()).ToList(); public static LCMoniterEnemies Instance { get; private set; } = null; internal static ManualLogSource Logger { get; private set; } = null; internal static Harmony? Harmony { get; set; } internal static ConfigEntry<string> BlackList { get; set; } = null; internal static ConfigEntry<float> TargetYoffset { get; set; } = null; internal static ConfigEntry<float> TargetXoffset { get; set; } = null; internal static ConfigEntry<float> TargetZoffset { get; set; } = null; internal static ConfigEntry<bool> AutoSwitchOnEnemyDeath { get; set; } = null; internal static ConfigEntry<bool> CreateBodyCam { get; set; } = null; internal static ConfigEntry<bool> TryTelewarp { get; set; } = null; public static List<string> GetParsedAttackBlacklist() { if (string.IsNullOrEmpty(BlackList.Value)) { return new List<string>(); } return BlackList.Value.Split(',').ToList(); } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; Patch(); BlackList = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "Enemy Blacklist", "", "The list of enemy names that wont be monitored (separated by commas, no spaces in between) (item1,item2,item3...)"); TargetYoffset = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Camera Target Y Offset", 0f, "The Y (Vertical) Offset of the Enemy's target."); TargetXoffset = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Camera Target X Offset", 0f, "The X (Horizontal) Offset of the Enemy's target."); TargetZoffset = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Camera Target Z Offset", 0f, "The Z (Depth) Offset of the Enemy's target."); AutoSwitchOnEnemyDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Auto Switch on Enemy Death", false, "Automatically switch to the next enemy when the current one dies."); CreateBodyCam = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Create BodyCam", true, "Create a BodyCam for each enemy. If false, the enemy will spesfic point for a bodycam."); TryTelewarp = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Allow Telepor", true, "Try to teleport enemies to the ship when they are targeted by the teleporter. (Could break some enemies AI)"); Logger.LogInfo((object)"NoteBoxz.MonitorEnemies v1.5.0 has loaded!"); } internal static void Patch() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("NoteBoxz.MonitorEnemies"); } Logger.LogDebug((object)"Patching..."); try { Type[] typesWithErrorHandling = GetTypesWithErrorHandling(); Type[] array = typesWithErrorHandling; foreach (Type type in array) { try { Harmony.PatchAll(type); } catch (Exception ex) { Logger.LogError((object)("Error patching type " + type.FullName + ": " + ex.Message)); if (ex.InnerException != null) { Logger.LogError((object)("Inner exception: " + ex.InnerException.Message)); } } } } catch (Exception ex2) { Logger.LogError((object)("Error during patching process: " + ex2.Message)); if (ex2.InnerException != null) { Logger.LogError((object)("Inner exception: " + ex2.InnerException.Message)); } } Logger.LogDebug((object)"Finished patching!"); } internal static Type[] GetTypesWithErrorHandling() { try { return Assembly.GetExecutingAssembly().GetTypes(); } catch (ReflectionTypeLoadException ex) { Logger.LogWarning((object)"ReflectionTypeLoadException caught while getting types. Some types will be skipped."); Exception[] loaderExceptions = ex.LoaderExceptions; foreach (Exception ex2 in loaderExceptions) { Logger.LogWarning((object)("Loader Exception: " + ex2.Message)); if (ex2 is FileNotFoundException ex3) { Logger.LogWarning((object)("Could not load file: " + ex3.FileName)); } } return ex.Types.Where((Type t) => t != null).ToArray(); } catch (Exception ex4) { Logger.LogError((object)("Unexpected error while getting types: " + ex4.Message)); return new Type[0]; } } internal static void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"MoniterEnemies unpatched! Harmony unloaded."); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "NoteBoxz.MonitorEnemies"; public const string PLUGIN_NAME = "LCMoniterEnemies"; public const string PLUGIN_VERSION = "1.5.0"; } } namespace LCMoniterEnemies.Patches { [HarmonyPatch(typeof(BodyCamComponent))] internal class BodyCamComponetPatch { [HarmonyPatch("SetTargetToTransform")] [HarmonyPrefix] public static bool SetTargetToTransformPrefix(ref Transform transform) { EnemyPos enemyPos = default(EnemyPos); if ((Object)(object)transform != (Object)null && ((Component)transform).gameObject.TryGetComponent<EnemyPos>(ref enemyPos) && (Object)(object)enemyPos.BodyCamPoint != (Object)null) { transform = enemyPos.BodyCamPoint; LCMoniterEnemies.Logger.LogDebug((object)("BodyCamComponent.SetTargetToTransform: Setting target to " + ((Object)enemyPos.BodyCamPoint).name + " for enemy " + ((Object)((Component)enemyPos.Root).gameObject).name)); } else { LCMoniterEnemies.Logger.LogDebug((object)"BodyCamComponent.SetTargetToTransform: No valid EnemyPos or BodyCamPoint found, using original transform."); } return true; } } [HarmonyPatch(typeof(EnemyAI))] internal class EnemyAIPatch { [HarmonyPatch("Start")] [HarmonyPostfix] public static void StarPostFix(EnemyAI __instance) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown EnemyAI __instance2 = __instance; if (!LCMoniterEnemies.GetParsedAttackBlacklist().Contains(__instance2.enemyType.enemyName) && (Object)(object)((Component)__instance2).GetComponentInChildren<EnemyPos>() == (Object)null) { int num = Object.FindObjectOfType<ManualCameraRenderer>().radarTargets.Count((TransformAndName target) => target.name.StartsWith(__instance2.enemyType.enemyName)); string text = "???"; text = ((num <= 0) ? (__instance2.enemyType.enemyName ?? "") : $"{__instance2.enemyType.enemyName} #{num}"); GameObject val = new GameObject(text); Transform transform = ((Component)__instance2).transform; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0f, LCMoniterEnemies.TargetYoffset.Value, 0f); val.transform.position = transform.position + val2; val.transform.rotation = transform.rotation; val.transform.SetParent(transform, true); EnemyPos enemyPos = val.AddComponent<EnemyPos>(); enemyPos.Root = __instance2; TransformAndName tnN = new TransformAndName(((Component)enemyPos).transform, text, true); enemyPos.TnN = tnN; ManualCameraRendererPatch.AddEnemyToRadarTargets(enemyPos); } } } [HarmonyPatch(typeof(ManualCameraRenderer))] internal class ManualCameraRendererPatch { public static EnemyAI? EnemyTargeting; [HarmonyPatch("updateMapTarget")] [HarmonyPostfix] public static void updateMapTargetPostfix(ManualCameraRenderer __instance, int setRadarTargetIndex, bool calledFromRPC = true) { EnemyPos component = ((Component)__instance.radarTargets[setRadarTargetIndex].transform).gameObject.GetComponent<EnemyPos>(); if ((Object)(object)component != (Object)null) { EnemyTargeting = component.Root; } } public static void RemoveEnemyFromRadarTargets(EnemyPos enemyTransform) { if (enemyTransform.TnN == null) { LCMoniterEnemies.Logger.LogWarning((object)"EnemyPos's tranform and name was null when removing"); return; } ManualCameraRenderer[] array = Object.FindObjectsOfType<ManualCameraRenderer>(); ManualCameraRenderer[] array2 = array; foreach (ManualCameraRenderer val in array2) { if (val.targetTransformIndex + 1 < val.radarTargets.Count && val.radarTargets.Contains(enemyTransform.TnN) && LCMoniterEnemies.AutoSwitchOnEnemyDeath.Value && val.targetTransformIndex == val.radarTargets.IndexOf(enemyTransform.TnN) && ((NetworkBehaviour)val).IsServer) { val.SwitchRadarTargetAndSync(val.targetTransformIndex + 1); } if (val.targetTransformIndex + 1 >= val.radarTargets.Count && ((NetworkBehaviour)val).IsServer) { LCMoniterEnemies.Logger.LogWarning((object)$"{((Object)val).name} Predicted CameraViewIndex will be out of bounds when clearing, setting to {val.radarTargets.Count - 1}"); val.SwitchRadarTargetAndSync(val.radarTargets.Count - 1); } if (val.radarTargets.Contains(enemyTransform.TnN)) { val.radarTargets.Remove(enemyTransform.TnN); } } } public static void AddEnemyToRadarTargets(EnemyPos enemyTransform) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown if (enemyTransform.TnN == null) { LCMoniterEnemies.Logger.LogWarning((object)"EnemyPos's tranform and name was null when adding"); return; } ManualCameraRenderer[] array = Object.FindObjectsOfType<ManualCameraRenderer>(); ManualCameraRenderer[] array2 = array; foreach (ManualCameraRenderer val in array2) { if (enemyTransform.TnN == null) { LCMoniterEnemies.Logger.LogWarning((object)"EnemyPos's tranform and name was null when adding. Generateing new one..."); TransformAndName tnN = new TransformAndName(((Component)enemyTransform).transform, ((Object)enemyTransform).name, true); enemyTransform.TnN = tnN; } if (!val.radarTargets.Contains(enemyTransform.TnN)) { val.radarTargets.Add(enemyTransform.TnN); } } } } [HarmonyPatch(typeof(ShipTeleporter))] internal class ShipTeleporterPatch { [CompilerGenerated] private sealed class <beamUpEnemy>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ShipTeleporter __instance; private EnemyAI <enemyToBeamUp>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <beamUpEnemy>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <enemyToBeamUp>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <enemyToBeamUp>5__1 = ManualCameraRendererPatch.EnemyTargeting; if ((Object)(object)<enemyToBeamUp>5__1 == (Object)null) { LCMoniterEnemies.Logger.LogInfo((object)"Targeted enemy is null"); return false; } LCMoniterEnemies.Logger.LogInfo((object)("Attemping to teleport enemy '" + ((Object)((Component)<enemyToBeamUp>5__1).gameObject).name + "'")); if (StartOfRound.Instance.shipIsLeaving) { LCMoniterEnemies.Logger.LogInfo((object)("Ship could not teleport enemy '" + ((Object)((Component)<enemyToBeamUp>5__1).gameObject).name + "' because the ship is leaving the nav mesh.")); return false; } <enemyToBeamUp>5__1.ShipTeleportEnemy(); <enemyToBeamUp>5__1.creatureSFX.PlayOneShot(__instance.beamUpPlayerBodySFX); <>2__current = (object)new WaitForSeconds(3f); <>1__state = 1; return true; case 1: <>1__state = -1; if (StartOfRound.Instance.shipIsLeaving) { LCMoniterEnemies.Logger.LogInfo((object)("Ship could not teleport enemy '" + ((Object)((Component)<enemyToBeamUp>5__1).gameObject).name + "' because the ship is leaving the nav mesh.")); return false; } <enemyToBeamUp>5__1.SetEnemyOutside(true); if (((NetworkBehaviour)<enemyToBeamUp>5__1).IsOwner) { ((Behaviour)<enemyToBeamUp>5__1.agent).enabled = false; ((Component)<enemyToBeamUp>5__1).transform.position = __instance.teleporterPosition.position; ((Behaviour)<enemyToBeamUp>5__1.agent).enabled = true; } <enemyToBeamUp>5__1.serverPosition = __instance.teleporterPosition.position; __instance.shipTeleporterAudio.PlayOneShot(__instance.teleporterBeamUpSFX); if (GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom) { HUDManager.Instance.ShakeCamera((ScreenShakeType)1); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPatch("beamUpPlayer")] [HarmonyPrefix] public static void beamUpPlayerPostfix(ShipTeleporter __instance) { if (!LCMoniterEnemies.TryTelewarp.Value) { LCMoniterEnemies.Logger.LogInfo((object)"Telewarp is disabled, skipping beam up."); } else { ((MonoBehaviour)__instance).StartCoroutine(beamUpEnemy(__instance)); } } [IteratorStateMachine(typeof(<beamUpEnemy>d__1))] private static IEnumerator beamUpEnemy(ShipTeleporter __instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <beamUpEnemy>d__1(0) { __instance = __instance }; } } [HarmonyPatch(typeof(StartOfRound))] internal class StartOfRoundPatch { [HarmonyPatch("Start")] [HarmonyPrefix] public static void StartPrefix() { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if (!LCMoniterEnemies.CreateBodyCam.Value) { return; } foreach (EnemyType enemyType in LCMoniterEnemies.EnemyTypes) { try { if ((Object)(object)enemyType == (Object)null || (Object)(object)enemyType.enemyPrefab == (Object)null) { LCMoniterEnemies.Logger.LogWarning((object)"EnemyType or its prefab is null, skipping..."); continue; } Transform orCreateBodyCamPoint = EnemyPos.GetOrCreateBodyCamPoint(enemyType.enemyPrefab.gameObject); if ((Object)(object)orCreateBodyCamPoint != (Object)null) { EnemyPos.BodyCamPoints[enemyType] = orCreateBodyCamPoint; LCMoniterEnemies.Logger.LogDebug((object)$"BodyCamPoint for {((Object)enemyType).name} set to {((Object)orCreateBodyCamPoint).name} at {orCreateBodyCamPoint.position},{orCreateBodyCamPoint.rotation} ({orCreateBodyCamPoint.localPosition})"); } } catch (Exception ex) { LCMoniterEnemies.Logger.LogError((object)("Error while processing EnemyType: " + ex.Message)); } } } } }