Decompiled source of Expanded Aim Assist v0.3.2

plugins/GatekeeperAimAssist.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Doozy.Runtime.UIManager.Components;
using Gatekeeper.MainMenuScripts.MainMenu.SettingsPanel;
using Gatekeeper.MainMenuScripts.MainMenu.SettingsPanel.KeyBindingSettings;
using Gatekeeper.MainMenuScripts.MainMenu.SettingsPanel.Lines;
using GatekeeperAimAssist.Core;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GatekeeperAimAssist")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.2.0")]
[assembly: AssemblyInformationalVersion("0.3.2")]
[assembly: AssemblyProduct("GatekeeperAimAssist")]
[assembly: AssemblyTitle("GatekeeperAimAssist")]
[assembly: AssemblyVersion("0.3.2.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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 GatekeeperAimAssist
{
	[BepInPlugin("com.prom.gatekeeper.aimassist", "Gatekeeper Aim Assist", "0.3.2")]
	[BepInProcess("Gatekeeper.exe")]
	public sealed class Plugin : BasePlugin
	{
		public const string PluginGuid = "com.prom.gatekeeper.aimassist";

		public const string PluginName = "Gatekeeper Aim Assist";

		public const string PluginVersion = "0.3.2";

		private static ManualLogSource PluginLog;

		private static GatekeeperRuntimeBindings Bindings;

		private static ConfigEntry<bool> Enabled;

		private static ConfigEntry<bool> EnableForMouseKeyboard;

		private static ConfigEntry<float> GamepadAimRange;

		private static ConfigEntry<float> CursorSphereRadius;

		private static ConfigEntry<float> CursorFollowSpeed;

		private static ConfigEntry<float> CursorBreakRadius;

		private static ConfigEntry<float> FrontSphereOffsetX;

		private static ConfigEntry<float> FrontSphereOffsetY;

		private static ConfigEntry<float> FrontSphereOffsetZ;

		private static ConfigEntry<float> FrontSphereRadius;

		private static ConfigEntry<float> FrontCursorAngleThreshold;

		private static KeyboardMouseAimAssistSetting KeyboardMouseSetting;

		private static int KbmOverrideLogged;

		public override void Load()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			//IL_01d8: Expected O, but got Unknown
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Expected O, but got Unknown
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Expected O, but got Unknown
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Expected O, but got Unknown
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Expected O, but got Unknown
			PluginLog = ((BasePlugin)this).Log;
			BindConfiguration();
			KeyboardMouseSetting = new KeyboardMouseAimAssistSetting(() => EnableForMouseKeyboard.Value, delegate(bool value)
			{
				EnableForMouseKeyboard.Value = value;
				((BasePlugin)this).Config.Save();
			});
			KeyboardMouseSettingsMenu.Initialize(KeyboardMouseSetting, ((BasePlugin)this).Log);
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(38, 4, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Gatekeeper Aim Assist");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.3.2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" starting (Enabled=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(Enabled.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", MouseKeyboard=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EnableForMouseKeyboard.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
			}
			log.LogInfo(val);
			if (!Enabled.Value)
			{
				ManualLogSource log2 = ((BasePlugin)this).Log;
				val = new BepInExInfoLogInterpolatedStringHandler(48, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Gatekeeper Aim Assist");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is disabled by configuration; no patch applied.");
				}
				log2.LogInfo(val);
				return;
			}
			Harmony val2 = null;
			try
			{
				Bindings = GatekeeperRuntimeBindings.Resolve((Func<string, Type?>)AccessTools.TypeByName);
				MethodInfo methodInfo = RequireUniqueManualUpdate(Bindings.ControllerType);
				MethodInfo methodInfo2 = RequireStaticBooleanGetter(Bindings.InputManagerType, "CurrentDeviceIsJoystick");
				Type declaringType = RequireType("Gatekeeper.MainMenuScripts.MainMenu.SettingsPanel.KeyBindingSettings.GamepadSettingsController");
				Type declaringType2 = RequireType("Gatekeeper.MainMenuScripts.MainMenu.SettingsPanel.KeyBindingSettings.KeyboardSettingsController");
				val2 = new Harmony("com.prom.gatekeeper.aimassist");
				val2.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "CurrentDeviceIsJoystickPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val2.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "ManualUpdatePrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "ManualUpdateFinalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null);
				val2.Patch((MethodBase)RequireInstanceMethod(declaringType, "Awake"), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "GamepadSettingsAwakePostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val2.Patch((MethodBase)RequireInstanceMethod(declaringType2, "OnEnable"), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "KeyboardSettingsOnEnablePostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val2.Patch((MethodBase)RequireInstanceMethod(declaringType2, "KeyboardResetToDefault"), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "KeyboardResetToDefaultPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				ManualLogSource log3 = ((BasePlugin)this).Log;
				val = new BepInExInfoLogInterpolatedStringHandler(183, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Patched ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Bindings.ControllerType.FullName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".ManualUpdate(), scoped ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Bindings.InputManagerType.FullName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".CurrentDeviceIsJoystick, and attached the keyboard/mouse settings toggle. Existing target validity, LOS, exclusions and selection order are preserved.");
				}
				log3.LogInfo(val);
			}
			catch (Exception ex)
			{
				if (val2 != null)
				{
					val2.UnpatchSelf();
				}
				ManualLogSource log4 = ((BasePlugin)this).Log;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(47, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>("Gatekeeper Aim Assist");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" failed closed; no aim-assist patch is active: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				log4.LogError(val3);
			}
		}

		private void BindConfiguration()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Expected O, but got Unknown
			Enabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. Restart the game after changing this value.");
			EnableForMouseKeyboard = ((BasePlugin)this).Config.Bind<bool>("General", "EnableForMouseKeyboard", true, "Temporarily opens the game's own aim-assist gate while mouse or keyboard is the current input device.");
			GamepadAimRange = ((BasePlugin)this).Config.Bind<float>("Acquisition", "GamepadAimRange", 2200f, new ConfigDescription("Screen-space cursor acquisition diameter. The game internally uses half this value as its pixel radius.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10000f), Array.Empty<object>()));
			CursorSphereRadius = ((BasePlugin)this).Config.Bind<float>("Acquisition", "CursorSphereRadius", 12f, new ConfigDescription("Radius of the game's cursor ray sphere-cast.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			FrontSphereOffsetX = ((BasePlugin)this).Config.Bind<float>("Acquisition", "FrontSphereOffsetX", 0f, new ConfigDescription("World-space X component of the game's forward-search sphere offset.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
			FrontSphereOffsetY = ((BasePlugin)this).Config.Bind<float>("Acquisition", "FrontSphereOffsetY", 0f, new ConfigDescription("World-space Y component of the game's forward-search sphere offset.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
			FrontSphereOffsetZ = ((BasePlugin)this).Config.Bind<float>("Acquisition", "FrontSphereOffsetZ", 8f, new ConfigDescription("World-space Z component of the game's forward-search sphere offset.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 100f), Array.Empty<object>()));
			FrontSphereRadius = ((BasePlugin)this).Config.Bind<float>("Acquisition", "FrontSphereRadius", 30f, new ConfigDescription("Radius of the game's forward target-search sphere.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			FrontCursorAngleThreshold = ((BasePlugin)this).Config.Bind<float>("Acquisition", "FrontCursorAngleThreshold", 180f, new ConfigDescription("Maximum screen-space cursor angle that permits the forward-search fallback.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 180f), Array.Empty<object>()));
			CursorFollowSpeed = ((BasePlugin)this).Config.Bind<float>("Tracking", "CursorFollowSpeed", 10f, new ConfigDescription("The game's target tracking speed.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
			CursorBreakRadius = ((BasePlugin)this).Config.Bind<float>("Tracking", "CursorBreakRadius", 0.98f, new ConfigDescription("Multiplier used by the game's current-target break threshold.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		}

		private static MethodInfo RequireUniqueManualUpdate(Type controllerType)
		{
			MethodInfo methodInfo = null;
			MethodInfo[] methods = controllerType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (!(methodInfo2.Name != "ManualUpdate") && methodInfo2.GetParameters().Length == 0)
				{
					if ((object)methodInfo != null)
					{
						throw new AmbiguousMatchException("More than one parameterless ManualUpdate method was found.");
					}
					methodInfo = methodInfo2;
				}
			}
			return methodInfo ?? throw new MissingMethodException(controllerType.FullName, "ManualUpdate()");
		}

		private static MethodInfo RequireStaticBooleanGetter(Type declaringType, string propertyName)
		{
			MethodInfo methodInfo = (declaringType.GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new MissingMemberException(declaringType.FullName, propertyName)).GetGetMethod(nonPublic: true) ?? throw new MissingMethodException(declaringType.FullName, "get_" + propertyName + "()");
			if (methodInfo.ReturnType != typeof(bool) || methodInfo.GetParameters().Length != 0)
			{
				throw new InvalidOperationException(declaringType.FullName + "." + propertyName + " is not a parameterless boolean getter.");
			}
			return methodInfo;
		}

		private static Type RequireType(string typeName)
		{
			return AccessTools.TypeByName(typeName) ?? throw new TypeLoadException(typeName);
		}

		private static MethodInfo RequireInstanceMethod(Type declaringType, string methodName)
		{
			return AccessTools.Method(declaringType, methodName, Type.EmptyTypes, (Type[])null) ?? throw new MissingMethodException(declaringType.FullName, methodName + "()");
		}

		private static void GamepadSettingsAwakePostfix(GamepadSettingsController __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			try
			{
				KeyboardMouseSettingsMenu.CaptureTemplate(__instance);
			}
			catch (Exception ex)
			{
				ManualLogSource pluginLog = PluginLog;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(57, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not capture the native Aim Assist toggle template: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				pluginLog.LogWarning(val);
			}
		}

		private static void KeyboardSettingsOnEnablePostfix(KeyboardSettingsController __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			try
			{
				KeyboardMouseSettingsMenu.Attach(__instance);
			}
			catch (Exception ex)
			{
				ManualLogSource pluginLog = PluginLog;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(82, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not add the keyboard/mouse Aim Assist toggle; other settings are unchanged: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				pluginLog.LogWarning(val);
			}
		}

		private static void KeyboardResetToDefaultPostfix()
		{
			KeyboardMouseSettingsMenu.ResetToDefault();
		}

		private static void ManualUpdatePrefix(object __instance, out AimAssistRuntimeScope? __state)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			__state = null;
			try
			{
				if (Enabled.Value)
				{
					GatekeeperRuntimeState state = Bindings.CreateState(__instance);
					__state = AimAssistRuntimeScope.Begin(state, EnableForMouseKeyboard.Value, Bindings.CurrentInputKind, ConfiguredTuning());
				}
			}
			catch (Exception ex)
			{
				ManualLogSource pluginLog = PluginLog;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(74, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not apply the temporary aim-assist scope; this update is unchanged: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				pluginLog.LogError(val);
			}
		}

		private static Exception? ManualUpdateFinalizer(Exception? __exception, AimAssistRuntimeScope? __state)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			try
			{
				__state?.Dispose();
			}
			catch (Exception ex)
			{
				ManualLogSource pluginLog = PluginLog;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(47, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not restore temporary aim-assist values: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				pluginLog.LogError(val);
			}
			return __exception;
		}

		private static void CurrentDeviceIsJoystickPostfix(ref bool __result)
		{
			if (AimAssistRuntimeScope.ForceJoystickGateForCurrentThread)
			{
				__result = true;
				if (Interlocked.Exchange(ref KbmOverrideLogged, 1) == 0)
				{
					PluginLog.LogInfo((object)"Keyboard/mouse aim-assist path activated: the joystick-only guard is overridden only inside AimAssistController.ManualUpdate().");
				}
			}
		}

		private static AimAssistTuning ConfiguredTuning()
		{
			return new AimAssistTuning(GamepadAimRange.Value, CursorSphereRadius.Value, CursorFollowSpeed.Value, CursorBreakRadius.Value, FrontSphereOffsetX.Value, FrontSphereOffsetY.Value, FrontSphereOffsetZ.Value, FrontSphereRadius.Value, FrontCursorAngleThreshold.Value);
		}
	}
	internal sealed class GatekeeperRuntimeBindings
	{
		private const string ControllerTypeName = "Gatekeeper.CameraScripts.HUD.Aim.AimAssistController";

		private const string SaveManagerTypeName = "Gatekeeper.General.SaveLoad.SaveLoadManager";

		private const string InputManagerTypeName = "Gatekeeper.General.InputSystem.GameplayInputManager";

		private readonly ReflectionMemberAccessor _controllerInfo;

		private readonly ReflectionMemberAccessor _dataSave;

		private readonly ReflectionMemberAccessor _currentInputDevice;

		public Type ControllerType { get; }

		public Type InputManagerType { get; }

		public InputKind CurrentInputKind => InputKindMapper.FromGameValue(Convert.ToInt32(_currentInputDevice.Get(null)));

		public GatekeeperRuntimeBindings(Type controllerType, Type saveManagerType, Type inputManagerType)
		{
			ControllerType = controllerType;
			InputManagerType = inputManagerType;
			_controllerInfo = ReflectionMemberAccessor.Required(controllerType, "info", "Info");
			_dataSave = ReflectionMemberAccessor.Required(saveManagerType, "DataSave");
			_currentInputDevice = ReflectionMemberAccessor.Required(inputManagerType, "CurrentInputDeviceType");
		}

		public static GatekeeperRuntimeBindings Resolve(Func<string, Type?> typeResolver)
		{
			return new GatekeeperRuntimeBindings(typeResolver("Gatekeeper.CameraScripts.HUD.Aim.AimAssistController") ?? throw new TypeLoadException("Gatekeeper.CameraScripts.HUD.Aim.AimAssistController"), typeResolver("Gatekeeper.General.SaveLoad.SaveLoadManager") ?? throw new TypeLoadException("Gatekeeper.General.SaveLoad.SaveLoadManager"), typeResolver("Gatekeeper.General.InputSystem.GameplayInputManager") ?? throw new TypeLoadException("Gatekeeper.General.InputSystem.GameplayInputManager"));
		}

		public GatekeeperRuntimeState CreateState(object controller)
		{
			object? dataSave = _dataSave.Get(null) ?? throw new InvalidOperationException("SaveLoadManager.DataSave is null.");
			object info = _controllerInfo.Get(controller) ?? throw new InvalidOperationException("AimAssistController.info is null.");
			return new GatekeeperRuntimeState(dataSave, info);
		}
	}
	internal sealed class GatekeeperRuntimeState : IAimAssistRuntimeState
	{
		private sealed class VectorMembers
		{
			private readonly ReflectionMemberAccessor _x;

			private readonly ReflectionMemberAccessor _y;

			private readonly ReflectionMemberAccessor _z;

			public VectorMembers(Type vectorType)
			{
				_x = ReflectionMemberAccessor.Required(vectorType, "x");
				_y = ReflectionMemberAccessor.Required(vectorType, "y");
				_z = ReflectionMemberAccessor.Required(vectorType, "z");
			}

			public float ReadX(object vector)
			{
				return Convert.ToSingle(_x.Get(vector));
			}

			public float ReadY(object vector)
			{
				return Convert.ToSingle(_y.Get(vector));
			}

			public float ReadZ(object vector)
			{
				return Convert.ToSingle(_z.Get(vector));
			}

			public void Write(object vector, float x, float y, float z)
			{
				_x.Set(vector, x);
				_y.Set(vector, y);
				_z.Set(vector, z);
			}
		}

		private readonly object _dataSave;

		private readonly object _info;

		private readonly ReflectionMemberAccessor _aimAssistEnabled;

		private readonly ReflectionMemberAccessor _gamepadAimRange;

		private readonly ReflectionMemberAccessor _cursorSphereRadius;

		private readonly ReflectionMemberAccessor _cursorFollowSpeed;

		private readonly ReflectionMemberAccessor _cursorBreakRadius;

		private readonly ReflectionMemberAccessor _frontSphereOffset;

		private readonly ReflectionMemberAccessor _frontSphereRadius;

		private readonly ReflectionMemberAccessor _frontCursorAngleThreshold;

		public bool AimAssistEnabled
		{
			get
			{
				return Convert.ToBoolean(_aimAssistEnabled.Get(_dataSave));
			}
			set
			{
				_aimAssistEnabled.Set(_dataSave, value);
			}
		}

		public AimAssistTuning Tuning
		{
			get
			{
				object obj = _frontSphereOffset.Get(_info) ?? throw new InvalidOperationException("AimAssistInfo.FrontSphereOffset is null.");
				VectorMembers vectorMembers = new VectorMembers(obj.GetType());
				return new AimAssistTuning(ReadFloat(_gamepadAimRange, _dataSave), ReadFloat(_cursorSphereRadius, _info), ReadFloat(_cursorFollowSpeed, _info), ReadFloat(_cursorBreakRadius, _info), vectorMembers.ReadX(obj), vectorMembers.ReadY(obj), vectorMembers.ReadZ(obj), ReadFloat(_frontSphereRadius, _info), ReadFloat(_frontCursorAngleThreshold, _info));
			}
			set
			{
				_gamepadAimRange.Set(_dataSave, value.GamepadAimRange);
				_cursorSphereRadius.Set(_info, value.CursorSphereRadius);
				_cursorFollowSpeed.Set(_info, value.CursorFollowSpeed);
				_cursorBreakRadius.Set(_info, value.CursorBreakRadius);
				object obj = _frontSphereOffset.Get(_info) ?? throw new InvalidOperationException("AimAssistInfo.FrontSphereOffset is null.");
				new VectorMembers(obj.GetType()).Write(obj, value.FrontSphereOffsetX, value.FrontSphereOffsetY, value.FrontSphereOffsetZ);
				_frontSphereOffset.Set(_info, obj);
				_frontSphereRadius.Set(_info, value.FrontSphereRadius);
				_frontCursorAngleThreshold.Set(_info, value.FrontCursorAngleThreshold);
			}
		}

		public GatekeeperRuntimeState(object dataSave, object info)
		{
			_dataSave = dataSave;
			_info = info;
			_aimAssistEnabled = ReflectionMemberAccessor.Required(dataSave.GetType(), "IsGamepadAimAssistOn");
			_gamepadAimRange = ReflectionMemberAccessor.Required(dataSave.GetType(), "GamepadAimRange");
			_cursorSphereRadius = InfoMember("CursorSphereRadius");
			_cursorFollowSpeed = InfoMember("CursorFollowSpeed");
			_cursorBreakRadius = InfoMember("CursorBreakRadius");
			_frontSphereOffset = InfoMember("FrontSphereOffset");
			_frontSphereRadius = InfoMember("FrontSphereRadius");
			_frontCursorAngleThreshold = InfoMember("FrontCursorAngleThreshold");
		}

		private ReflectionMemberAccessor InfoMember(string propertyName)
		{
			return ReflectionMemberAccessor.Required(_info.GetType(), propertyName, "<" + propertyName + ">k__BackingField");
		}

		private static float ReadFloat(ReflectionMemberAccessor member, object instance)
		{
			return Convert.ToSingle(member.Get(instance));
		}
	}
	internal static class KeyboardMouseSettingsMenu
	{
		private const string CloneName = "GatekeeperAimAssist.KeyboardMouseToggle";

		private static ToggleSettingsLine? _template;

		private static ToggleSettingsLine? _toggleLine;

		private static Action<bool>? _toggleChanged;

		private static KeyboardMouseAimAssistSetting? _setting;

		private static ManualLogSource? _log;

		public static void Initialize(KeyboardMouseAimAssistSetting setting, ManualLogSource log)
		{
			_setting = setting;
			_log = log;
		}

		public static void CaptureTemplate(GamepadSettingsController controller)
		{
			if (!Object.op_Implicit((Object)(object)_template))
			{
				_template = controller.aimAssistToggle;
			}
		}

		public static void Attach(KeyboardSettingsController controller)
		{
			if (Object.op_Implicit((Object)(object)_toggleLine))
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)_template))
			{
				foreach (GamepadSettingsController item in Resources.FindObjectsOfTypeAll<GamepadSettingsController>())
				{
					CaptureTemplate(item);
					if (Object.op_Implicit((Object)(object)_template))
					{
						break;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)_template))
			{
				throw new InvalidOperationException("The controller Aim Assist toggle template is not available yet.");
			}
			if (_setting == null)
			{
				throw new InvalidOperationException("The keyboard/mouse setting is not initialized.");
			}
			BaseSettingsLine val = KeyboardMouseMenuPlacement.FirstBinding((IEnumerable<BaseSettingsLine>)((Component)controller).GetComponentsInChildren<BaseSettingsLine>(true));
			Transform parent = ((Component)val).transform.parent;
			ToggleSettingsLine val2 = Object.Instantiate<ToggleSettingsLine>(_template, parent, false);
			((Object)((Component)val2).gameObject).name = "GatekeeperAimAssist.KeyboardMouseToggle";
			((Component)val2).transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex());
			Transform val3 = ((Component)val2).transform.Find("Text (TMP)");
			TMP_Text obj = (Object.op_Implicit((Object)(object)val3) ? ((Component)val3).GetComponent<TMP_Text>() : null);
			if (!Object.op_Implicit((Object)(object)obj))
			{
				Object.Destroy((Object)(object)((Component)val2).gameObject);
				throw new InvalidOperationException("The cloned Aim Assist row has no Text (TMP) caption.");
			}
			obj.text = "AIM ASSIST";
			((UISelectable)val2.Toggle).isOn = _setting.Value;
			_toggleChanged = DelegateSupport.ConvertDelegate<Action<bool>>((Delegate)new Action<bool>(OnToggleChanged));
			val2.OnToggleValueChanged += _toggleChanged;
			_toggleLine = val2;
			ManualLogSource? log = _log;
			if (log != null)
			{
				log.LogInfo((object)"Added a labelled Aim Assist row before the first keyboard binding.");
			}
		}

		public static void ResetToDefault()
		{
			if (_setting == null)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)_toggleLine))
			{
				ToggleSettingsLine toggleLine = _toggleLine;
				if (!((UISelectable)toggleLine.Toggle).isOn)
				{
					((UISelectable)toggleLine.Toggle).isOn = true;
				}
				else
				{
					_setting.ResetToDefault();
				}
			}
			else
			{
				_setting.ResetToDefault();
			}
		}

		private static void OnToggleChanged(bool value)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			_setting?.Change(value);
			ManualLogSource log = _log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(61, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Keyboard/mouse aim assist changed to ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(value ? "On" : "Off");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" from the settings menu.");
				}
				log.LogInfo(val);
			}
		}
	}
}
namespace GatekeeperAimAssist.Core
{
	public enum InputKind
	{
		None,
		Mouse,
		Keyboard,
		Joystick,
		Custom
	}
	public static class InputKindMapper
	{
		public static InputKind FromGameValue(int value)
		{
			return value switch
			{
				1 => InputKind.Mouse, 
				2 => InputKind.Keyboard, 
				3 => InputKind.Joystick, 
				4 => InputKind.Custom, 
				_ => InputKind.None, 
			};
		}
	}
	public readonly record struct AimAssistTuning(float GamepadAimRange, float CursorSphereRadius, float CursorFollowSpeed, float CursorBreakRadius, float FrontSphereOffsetX, float FrontSphereOffsetY, float FrontSphereOffsetZ, float FrontSphereRadius, float FrontCursorAngleThreshold);
	public interface IAimAssistRuntimeState
	{
		bool AimAssistEnabled { get; set; }

		AimAssistTuning Tuning { get; set; }
	}
	public sealed class AimAssistRuntimeScope : IDisposable
	{
		[ThreadStatic]
		private static int _joystickGateOverrideDepth;

		private IAimAssistRuntimeState? _state;

		private readonly bool _savedAimAssistEnabled;

		private readonly AimAssistTuning _savedTuning;

		private readonly bool _forcesJoystickGate;

		private bool _joystickGateOverrideEntered;

		public static bool ForceJoystickGateForCurrentThread => _joystickGateOverrideDepth > 0;

		private AimAssistRuntimeScope(IAimAssistRuntimeState state, bool savedAimAssistEnabled, AimAssistTuning savedTuning, bool forcesJoystickGate)
		{
			_state = state;
			_savedAimAssistEnabled = savedAimAssistEnabled;
			_savedTuning = savedTuning;
			_forcesJoystickGate = forcesJoystickGate;
		}

		public static AimAssistRuntimeScope Begin(IAimAssistRuntimeState state, bool enableForMouseKeyboard, InputKind inputKind, AimAssistTuning tuning)
		{
			ArgumentNullException.ThrowIfNull(state, "state");
			bool aimAssistEnabled = state.AimAssistEnabled;
			AimAssistTuning tuning2 = state.Tuning;
			bool flag = enableForMouseKeyboard;
			if (flag)
			{
				bool flag2 = (uint)(inputKind - 1) <= 1u;
				flag = flag2;
			}
			bool flag3 = flag;
			AimAssistRuntimeScope aimAssistRuntimeScope = new AimAssistRuntimeScope(state, aimAssistEnabled, tuning2, flag3);
			try
			{
				if (flag3)
				{
					state.AimAssistEnabled = true;
				}
				state.Tuning = tuning;
				if (flag3)
				{
					_joystickGateOverrideDepth++;
					aimAssistRuntimeScope._joystickGateOverrideEntered = true;
				}
				return aimAssistRuntimeScope;
			}
			catch
			{
				aimAssistRuntimeScope.Dispose();
				throw;
			}
		}

		public void Dispose()
		{
			IAimAssistRuntimeState aimAssistRuntimeState = Interlocked.Exchange(ref _state, null);
			if (aimAssistRuntimeState == null)
			{
				return;
			}
			try
			{
				aimAssistRuntimeState.Tuning = _savedTuning;
				aimAssistRuntimeState.AimAssistEnabled = _savedAimAssistEnabled;
			}
			finally
			{
				if (_forcesJoystickGate && _joystickGateOverrideEntered)
				{
					_joystickGateOverrideDepth--;
				}
			}
		}
	}
	public sealed class KeyboardMouseAimAssistSetting
	{
		private readonly Func<bool> _read;

		private readonly Action<bool> _writeAndSave;

		public bool Value => _read();

		public KeyboardMouseAimAssistSetting(Func<bool> read, Action<bool> writeAndSave)
		{
			ArgumentNullException.ThrowIfNull(read, "read");
			ArgumentNullException.ThrowIfNull(writeAndSave, "writeAndSave");
			_read = read;
			_writeAndSave = writeAndSave;
		}

		public void Change(bool value)
		{
			_writeAndSave(value);
		}

		public void ResetToDefault()
		{
			Change(value: true);
		}
	}
	public static class KeyboardMouseMenuPlacement
	{
		public static T FirstBinding<T>(IEnumerable<T> bindings)
		{
			ArgumentNullException.ThrowIfNull(bindings, "bindings");
			using IEnumerator<T> enumerator = bindings.GetEnumerator();
			if (!enumerator.MoveNext())
			{
				throw new InvalidOperationException("The keyboard settings panel has no binding rows.");
			}
			return enumerator.Current;
		}
	}
	public sealed class ReflectionMemberAccessor
	{
		private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private readonly FieldInfo? _field;

		private readonly PropertyInfo? _property;

		public Type ValueType => _field?.FieldType ?? _property.PropertyType;

		private string DisplayName => _field?.Name ?? _property.Name;

		private ReflectionMemberAccessor(FieldInfo field)
		{
			_field = field;
		}

		private ReflectionMemberAccessor(PropertyInfo property)
		{
			_property = property;
		}

		public static ReflectionMemberAccessor Required(Type declaringType, params string[] names)
		{
			ArgumentNullException.ThrowIfNull(declaringType, "declaringType");
			foreach (string name in names)
			{
				FieldInfo field = declaringType.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if ((object)field != null)
				{
					return new ReflectionMemberAccessor(field);
				}
				PropertyInfo property = declaringType.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if ((object)property != null)
				{
					return new ReflectionMemberAccessor(property);
				}
			}
			throw new MissingMemberException(declaringType.FullName, string.Join(" or ", names));
		}

		public object? Get(object? instance)
		{
			if ((object)_field == null)
			{
				return _property.GetValue(instance);
			}
			return _field.GetValue(instance);
		}

		public T Get<T>(object? instance)
		{
			return (T)(Get(instance) ?? throw new InvalidOperationException(DisplayName + " returned null."));
		}

		public void Set(object? instance, object? value)
		{
			if ((object)_field != null)
			{
				_field.SetValue(instance, value);
			}
			else
			{
				_property.SetValue(instance, value);
			}
		}
	}
}