Decompiled source of SnatcherBugFix v0.4.1

SnatcherBugFix.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Agents;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using Enemies;
using GTFO.API;
using GTFO.API.Extensions;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppSystem;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
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+4cdfaf61d209dfb7ef13a0ddab8af560f28b7e1d")]
[assembly: AssemblyProduct("SnatcherBugFix")]
[assembly: AssemblyTitle("SnatcherBugFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
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.4.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class EntryPoint : BasePlugin
	{
		public override void Load()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ClassInjector.RegisterTypeInIl2Cpp<SnatcherHandler>();
			new Harmony("Amor.SnatcherBugFix").PatchAll();
			RuntimeHelpers.RunClassConstructor(typeof(SnatcherPatches).TypeHandle);
			Logger.Info("SnatcherBugFix is done loading!");
		}
	}
	internal static class Logger
	{
		private static readonly ManualLogSource MLS;

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

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

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

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

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

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

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

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

		public static void Warn(string str)
		{
			MLS.LogWarning((object)str);
		}
	}
	public class SnatcherHandler : MonoBehaviour
	{
		public PlayerAgent Player = null;

		public EnemyAgent? Captor;

		public DelayedCallback? UncoverCallback;

		public DelayedCallback? UnwarpCallback;

		public eDimensionIndex LastDimension;

		public Vector3 LastPosition;

		private bool _warpFlag;

		public eDimensionIndex GoodDimension
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				EnemyAgent? captor = Captor;
				return (captor != null) ? ((Agent)captor).DimensionIndex : LastDimension;
			}
		}

		public Vector3 GoodPosition
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				EnemyAgent? captor = Captor;
				return (captor != null) ? captor.Position : LastPosition;
			}
		}

		public bool IsInArenaDim
		{
			get
			{
				PlayerAgent player = Player;
				bool? obj;
				if (player == null)
				{
					obj = null;
				}
				else
				{
					Dimension dimension = ((Agent)player).Dimension;
					obj = ((dimension != null) ? new bool?(dimension.IsArenaDimension) : null);
				}
				bool? flag = obj;
				return flag.GetValueOrDefault();
			}
		}

		public void Awake()
		{
			Player = ((Component)this).GetComponent<PlayerAgent>();
			UncoverCallback = new DelayedCallback(() => 2.5f, delegate
			{
				UncoverScreen();
			});
			UnwarpCallback = new DelayedCallback(() => 8f, delegate
			{
				ArenaUnwarp();
			});
			if (!ListExtensions.ToManaged<Dimension>(Builder.CurrentFloor.m_dimensions).Any((Dimension dim) => dim.IsArenaDimension))
			{
				Logger.Error("No arena dimension present in level!!");
				((Behaviour)this).enabled = false;
			}
			else
			{
				Logger.Debug("SnatcherHandler is setup and enabled");
			}
		}

		public void FixedUpdate()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player == (Object)null)
			{
				return;
			}
			if (IsInArenaDim)
			{
				if (!_warpFlag)
				{
					_warpFlag = true;
					UnwarpCallback?.Start();
				}
			}
			else
			{
				LastDimension = ((Agent)Player).DimensionIndex;
				LastPosition = ((Agent)Player).Position;
				_warpFlag = false;
			}
		}

		public void OnDestroy()
		{
			UncoverCallback?.Cancel();
			UnwarpCallback?.Cancel();
		}

		public void OnConsumed(EnemyAgent pouncer)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(34, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("SnatcherHandler OnConsumed, Enemy ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((Object)pouncer).GetInstanceID());
			}
			Logger.Debug(val);
			Captor = pouncer;
			UncoverCallback?.Start();
			UnwarpCallback?.Start();
		}

		public void OnSpitOut(EnemyAgent pouncer)
		{
			if (!((Object)(object)Captor == (Object)null) && ((Object)Captor).GetInstanceID() == ((Object)pouncer).GetInstanceID())
			{
				Logger.Debug("SnatcherHandler OnSpitOut (dead)");
				UncoverCallback?.Stop();
				UnwarpCallback?.Stop();
				Captor = null;
			}
		}

		public void UncoverScreen()
		{
			if (Player.FPSCamera.PouncerScreenFX.covered)
			{
				if (!IsInArenaDim)
				{
					Player.FPSCamera.PouncerScreenFX.SetCovered(false);
					Logger.Warn("Force uncovering local player's screen");
				}
				else
				{
					UncoverCallback?.Start();
				}
			}
		}

		public void ArenaUnwarp()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (!IsInArenaDim)
			{
				_warpFlag = false;
				return;
			}
			Player.RequestWarpToSync(GoodDimension, GoodPosition, Player.FPSCamera.CameraRayDir, (WarpOptions)0);
			Logger.Warn("Force teleporting local player out from arena dimension");
		}

		public void DelayedCallbackDebug(float uncoverTime, float unwarpTime)
		{
			UncoverCallback = new DelayedCallback(() => uncoverTime, delegate
			{
				UncoverScreen();
			});
			UnwarpCallback = new DelayedCallback(() => unwarpTime, delegate
			{
				ArenaUnwarp();
			});
			Logger.Warn("Changed delayed callbacks");
		}
	}
	[HarmonyPatch]
	internal static class SnatcherPatches
	{
		[CompilerGenerated]
		private sealed class <DespawnFromArena>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public EnemyAgent enemy;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DespawnFromArena>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					((Agent)enemy).m_replicator.Despawn();
					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();
			}
		}

		private static SnatcherHandler? _handler;

		static SnatcherPatches()
		{
			LevelAPI.OnEnterLevel += OnEnterLevel;
		}

		private static void OnEnterLevel()
		{
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			_handler = ((Component)localPlayerAgent).gameObject.AddOrGetComponent<SnatcherHandler>();
			if (!((Behaviour)_handler).enabled)
			{
				_handler = null;
			}
		}

		[HarmonyPatch(typeof(EnemyAgent), "Setup")]
		[HarmonyPrefix]
		[HarmonyPriority(600)]
		private static void Pre_EnemySetup(EnemyAgent __instance)
		{
			EnemyAgent __instance2 = __instance;
			if (!__instance2.IsSetup)
			{
				return;
			}
			if (__instance2.IsArenaDimensionEnemy)
			{
				__instance2.AddOnDeadOnce(delegate
				{
					_handler?.OnSpitOut(__instance2);
				});
			}
			if (SNet.IsMaster && ((Agent)__instance2).Dimension.IsArenaDimension)
			{
				MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)__instance2, DespawnFromArena(__instance2));
			}
		}

		[IteratorStateMachine(typeof(<DespawnFromArena>d__4))]
		private static IEnumerator DespawnFromArena(EnemyAgent enemy)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DespawnFromArena>d__4(0)
			{
				enemy = enemy
			};
		}

		[HarmonyPatch(typeof(PouncerBehaviour), "RequestConsume")]
		[HarmonyPatch(typeof(PouncerBehaviour), "OnConsumeRequestReceived")]
		[HarmonyPostfix]
		private static void Post_Consume(PouncerBehaviour __instance)
		{
			_handler?.OnConsumed(((Component)__instance).GetComponentInParent<EnemyAgent>());
		}

		[HarmonyPatch(typeof(PouncerScreenFX), "SetCovered", new Type[] { typeof(bool) })]
		[HarmonyPrefix]
		private static void Pre_CoverScreen()
		{
			FocusStateManager.ChangeState((eFocusState)4, true);
		}

		[HarmonyPatch(typeof(PouncerScreenFX), "SetCovered", new Type[] { typeof(bool) })]
		[HarmonyPostfix]
		private static void Post_CoverScreen(bool value)
		{
			if (value)
			{
				_handler?.UncoverCallback?.Start();
			}
		}
	}
}
namespace SnatcherBugFix.Utils
{
	public sealed class DelayedCallback
	{
		[CompilerGenerated]
		private sealed class <Update>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public DelayedCallback <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Update>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<>4__this._endTime > Clock.Time)
				{
					<>2__current = (object)new WaitForSeconds(<>4__this._endTime - Clock.Time);
					<>1__state = 1;
					return true;
				}
				<>4__this._routine = null;
				<>4__this._onEnd?.Invoke();
				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();
			}
		}

		private readonly Func<float> _getDelay;

		private readonly Action? _onEnd;

		private float _endTime;

		private Coroutine? _routine;

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

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

		[IteratorStateMachine(typeof(<Update>d__6))]
		public IEnumerator Update()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Update>d__6(0)
			{
				<>4__this = this
			};
		}

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