Decompiled source of SnatcherBugFix v0.2.1

SnatcherBugFix.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Agents;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using Enemies;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using SnatcherBugFix.Module;
using SnatcherBugFix.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SnatcherBugFix")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SnatcherBugFix")]
[assembly: AssemblyTitle("SnatcherBugFix")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
		}
	}
}
namespace SnatcherBugFix
{
	[BepInPlugin("Amor.SnatcherBugFix", "SnatcherBugFix", "0.2.1")]
	internal class EntryPoint : BasePlugin
	{
		public override void Load()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ClassInjector.RegisterTypeInIl2Cpp<StomachHandler>();
			new Harmony("Amor.SnatcherBugFix").PatchAll();
			Logger.Info("SnatcherBugFix is now loaded!");
		}
	}
	internal static class Logger
	{
		private static readonly ManualLogSource _Logger;

		static Logger()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_Logger = new ManualLogSource("SnatcherBugFix");
			Logger.Sources.Add((ILogSource)(object)_Logger);
		}

		private static string Format(object msg)
		{
			return msg.ToString();
		}

		public static void Info(BepInExInfoLogInterpolatedStringHandler handler)
		{
			_Logger.LogInfo(handler);
		}

		public static void Info(string str)
		{
			_Logger.LogMessage((object)str);
		}

		public static void Info(object data)
		{
			_Logger.LogMessage((object)Format(data));
		}

		public static void Debug(BepInExDebugLogInterpolatedStringHandler handler)
		{
			_Logger.LogDebug(handler);
		}

		public static void Debug(string str)
		{
			_Logger.LogDebug((object)str);
		}

		public static void Debug(object data)
		{
			_Logger.LogDebug((object)Format(data));
		}

		public static void Error(BepInExErrorLogInterpolatedStringHandler handler)
		{
			_Logger.LogError(handler);
		}

		public static void Error(string str)
		{
			_Logger.LogError((object)str);
		}

		public static void Error(object data)
		{
			_Logger.LogError((object)Format(data));
		}

		public static void Warn(BepInExWarningLogInterpolatedStringHandler handler)
		{
			_Logger.LogWarning(handler);
		}

		public static void Warn(string str)
		{
			_Logger.LogWarning((object)str);
		}

		public static void Warn(object data)
		{
			_Logger.LogWarning((object)Format(data));
		}
	}
}
namespace SnatcherBugFix.Utils
{
	public sealed class DelayedCallback
	{
		private readonly Func<float> _getDelay;

		private readonly Action? _onStart;

		private readonly Action? _onRefresh;

		private readonly Action? _onEnd;

		private float _endTime;

		private Coroutine? _routine;

		public DelayedCallback(Func<float> getDelay, Action? onEnd)
		{
			_getDelay = getDelay;
			_onEnd = onEnd;
		}

		public DelayedCallback(Func<float> getDelay, Action? onStart, Action? onEnd)
		{
			_getDelay = getDelay;
			_onStart = onStart;
			_onEnd = onEnd;
		}

		public DelayedCallback(Func<float> getDelay, Action? onStart, Action? onRefresh, Action? onEnd)
		{
			_getDelay = getDelay;
			_onStart = onStart;
			_onRefresh = onRefresh;
			_onEnd = onEnd;
		}

		public void Start()
		{
			_endTime = Clock.Time + _getDelay();
			_onRefresh?.Invoke();
			if (_routine == null)
			{
				_routine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Update()), (Action)null);
			}
		}

		public IEnumerator Update()
		{
			_onStart?.Invoke();
			while (_endTime > Clock.Time)
			{
				yield return (object)new WaitForSeconds(_endTime - Clock.Time);
			}
			_routine = null;
			_onEnd?.Invoke();
		}

		public void Stop()
		{
			if (_routine != null)
			{
				CoroutineManager.StopCoroutine(_routine);
				_routine = null;
				_onEnd?.Invoke();
			}
		}

		public void Cancel()
		{
			if (_routine != null)
			{
				CoroutineManager.StopCoroutine(_routine);
				_routine = null;
			}
		}
	}
	internal static class EnemyAgentExtensions
	{
		public static void AddOnDeadOnce(this EnemyAgent agent, Action onDead)
		{
			Action onDead2 = onDead;
			bool called = false;
			agent.OnDeadCallback += Action.op_Implicit((Action)delegate
			{
				if (!called)
				{
					onDead2?.Invoke();
					called = true;
				}
			});
		}
	}
	internal static class GameObjectExtensions
	{
		public static bool TryAndGetComponent<T>(this GameObject go, out T component)
		{
			component = go.GetComponent<T>();
			return component != null;
		}

		public static T AddOrGetComponent<T>(this GameObject go) where T : Component
		{
			if (!go.TryAndGetComponent<T>(out var component))
			{
				return go.AddComponent<T>();
			}
			return component;
		}
	}
}
namespace SnatcherBugFix.Module
{
	[HarmonyPatch]
	internal static class Patch_SnatcherFixes
	{
		[HarmonyPatch(typeof(EnemyAgent), "Setup")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void Post_EnemySpawned(EnemyAgent __instance)
		{
			if (__instance.IsSetup && __instance.IsArenaDimensionEnemy)
			{
				((Component)__instance).gameObject.AddOrGetComponent<StomachHandler>();
			}
		}

		[HarmonyPatch(typeof(PouncerBehaviour), "RequestConsume")]
		[HarmonyPatch(typeof(PouncerBehaviour), "OnConsumeRequestReceived")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void Post_Consume(PouncerBehaviour __instance)
		{
			((Component)__instance).GetComponentInParent<StomachHandler>().OnConsume();
		}

		[HarmonyPatch(typeof(PouncerScreenFX), "SetCovered", new Type[] { typeof(bool) })]
		[HarmonyPrefix]
		private static void Pre_CoverScreen()
		{
			FocusStateManager.ChangeState((eFocusState)4, true);
		}
	}
	public class StomachHandler : MonoBehaviour
	{
		private DelayedCallback? UnstuckCallback;

		private EnemyAgent? Pouncer;

		private PlayerAgent? Target;

		private Vector3 LastEnemyPosition;

		private eDimensionIndex DimensionIndex;

		private eDimensionIndex? LocalArenaDim;

		public void Awake()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			Pouncer = ((Component)this).GetComponent<EnemyAgent>();
			DimensionIndex = ((Agent)Pouncer).DimensionIndex;
			Dimension val = default(Dimension);
			Pouncer.GetLocalArenaDimension(ref val);
			LocalArenaDim = ((val != null) ? new eDimensionIndex?(val.DimensionIndex) : null);
			if (!LocalArenaDim.HasValue)
			{
				Logger.Error("No arena dimension present in level!");
				((Behaviour)this).enabled = false;
				return;
			}
			UnstuckCallback = new DelayedCallback(() => 6.5f, delegate
			{
				DoPouncerFix();
			});
			Pouncer.AddOnDeadOnce(delegate
			{
				UnstuckCallback.Stop();
			});
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val2 = new BepInExDebugLogInterpolatedStringHandler(27, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((GameDataBlockBase<EnemyDataBlock>)(object)Pouncer.EnemyData).name);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(((Object)Pouncer).GetInstanceID());
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s StomachHandler is setup");
			}
			Logger.Debug(val2);
		}

		public void FixedUpdate()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Pouncer == (Object)null) && ((Agent)Pouncer).Alive && (int)((AgentAI)Pouncer.AI).Mode == 1 && ((AgentAI)Pouncer.AI).Target != null)
			{
				LastEnemyPosition = Pouncer.Position;
				Target = ((Il2CppObjectBase)((AgentAI)Pouncer.AI).Target.m_agent).Cast<PlayerAgent>();
			}
		}

		public void OnConsume()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if ((Object)(object)Target != (Object)null && ((Agent)Target).IsLocallyOwned)
			{
				bool flag = default(bool);
				BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Target.Owner.NickName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" got consumed, starting delayed callback");
				}
				Logger.Debug(val);
				UnstuckCallback?.Start();
			}
		}

		public void OnDestroy()
		{
			UnstuckCallback?.Stop();
		}

		public void DoPouncerFix()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Logger.Debug("Stopped delayed callback, running DoPouncerFix");
			if ((eDimensionIndex?)((Agent)Target).DimensionIndex == LocalArenaDim)
			{
				Target.RequestWarpToSync(DimensionIndex, LastEnemyPosition, Target.FPSCamera.CameraRayDir, (WarpOptions)0);
				Logger.Warn("Force teleporting local player out from pouncer arena dimension");
			}
			if (Target.FPSCamera.PouncerScreenFX.covered)
			{
				Target.FPSCamera.PouncerScreenFX.SetCovered(false);
				Logger.Warn("Force uncovering local player's PouncerScreenFX");
			}
		}
	}
}