using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FreddyDiag")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("FreddyDiag")] [assembly: AssemblyTitle("FreddyDiag")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 FreddyDiag { [BepInPlugin("themorningstar.freddydiag", "Freddy Diag", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "themorningstar.freddydiag"; internal static ManualLogSource Log; internal static FieldInfo StateField; private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Harmony val = new Harmony("themorningstar.freddydiag"); try { Type type = AccessTools.TypeByName("FreddyEnemy.AI.EnemyFreddy"); if (type != null) { StateField = AccessTools.Field(type, "_state"); val.Patch((MethodBase)AccessTools.Method(type, "UpdateState", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches).GetMethod("StatePost")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.Method(type, "Update", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches).GetMethod("UpdateFinalizer")), (HarmonyMethod)null); Log.LogInfo((object)"FreddyDiag: armed (tracing Freddy state + Update exceptions)."); } else { Log.LogWarning((object)"FreddyDiag: EnemyFreddy type not found; is FreddyEnemy installed?"); } } catch (Exception ex) { Log.LogError((object)("FreddyDiag: Freddy setup failed: " + ex)); } try { Type type2 = AccessTools.TypeByName("EnemyRobe"); MethodInfo methodInfo = ((type2 != null) ? AccessTools.Method(type2, "Update", (Type[])null, (Type[])null) : null); if (methodInfo != null) { RobePatches.Init(type2); val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(RobePatches).GetMethod("UpdateFinalizer")), (HarmonyMethod)null); Log.LogInfo((object)"FreddyDiag: armed Rolling Giant (EnemyRobe) tracer."); } else { Log.LogWarning((object)"FreddyDiag: EnemyRobe.Update not found; Rolling Giant tracer disabled."); } } catch (Exception ex2) { Log.LogError((object)("FreddyDiag: Robe setup failed: " + ex2)); } } } internal static class Patches { private static object _lastState; private static readonly HashSet _seenExceptions = new HashSet(); private static float _nextHeartbeat; public static void StatePost(object __instance) { try { object obj = Plugin.StateField?.GetValue(__instance); if (obj != null && !obj.Equals(_lastState)) { _lastState = obj; Plugin.Log.LogInfo((object)$"[FreddyDiag] state -> {obj}"); } } catch { } } public static void UpdateFinalizer(object __instance, Exception __exception) { if (__exception != null) { string text = __exception.GetType().Name + ":" + __exception.Message; if (_seenExceptions.Add(text)) { object arg = null; try { arg = Plugin.StateField?.GetValue(__instance); } catch { } Plugin.Log.LogError((object)$"[FreddyDiag] Update threw (state {arg}): {text}"); } } else if (Time.time >= _nextHeartbeat) { _nextHeartbeat = Time.time + 2f; object arg2 = null; try { arg2 = Plugin.StateField?.GetValue(__instance); } catch { } Plugin.Log.LogInfo((object)$"[FreddyDiag] heartbeat: Update running, state={arg2}"); } } } internal static class RobePatches { private static FieldInfo _stateField; private static readonly Dictionary _lastState = new Dictionary(); private static readonly HashSet _seenEx = new HashSet(); private static float _nextHeartbeat; public static void Init(Type robeType) { _stateField = AccessTools.Field(robeType, "currentState"); } private static bool IsRollingGiant(object inst) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) try { GameObject gameObject = ((Component)((Component)inst).transform.root).gameObject; return ((Object)gameObject).name.IndexOf("Rolling Giant", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)gameObject).name.IndexOf("RollingGiant", StringComparison.OrdinalIgnoreCase) >= 0; } catch { return false; } } private static string State(object inst) { try { return _stateField?.GetValue(inst)?.ToString(); } catch { return null; } } public static void UpdateFinalizer(object __instance, Exception __exception) { try { if (!IsRollingGiant(__instance)) { return; } if (__exception != null) { string text = __exception.GetType().Name + ":" + __exception.Message; if (_seenEx.Add(text)) { Plugin.Log.LogError((object)("[RollingGiantDiag] Update threw (state " + State(__instance) + "): " + text)); } return; } string text2 = State(__instance); int hashCode = __instance.GetHashCode(); if (!_lastState.TryGetValue(hashCode, out var value) || value != text2) { _lastState[hashCode] = text2; Plugin.Log.LogInfo((object)("[RollingGiantDiag] state -> " + text2)); } if (Time.time >= _nextHeartbeat) { _nextHeartbeat = Time.time + 3f; Plugin.Log.LogInfo((object)("[RollingGiantDiag] heartbeat: Update running, state=" + text2)); } } catch { } } } }