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 Enabled; private static ConfigEntry EnableForMouseKeyboard; private static ConfigEntry GamepadAimRange; private static ConfigEntry CursorSphereRadius; private static ConfigEntry CursorFollowSpeed; private static ConfigEntry CursorBreakRadius; private static ConfigEntry FrontSphereOffsetX; private static ConfigEntry FrontSphereOffsetY; private static ConfigEntry FrontSphereOffsetZ; private static ConfigEntry FrontSphereRadius; private static ConfigEntry 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("Gatekeeper Aim Assist"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("0.3.2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" starting (Enabled="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Enabled.Value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", MouseKeyboard="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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("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)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(Bindings.ControllerType.FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".ManualUpdate(), scoped "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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("Gatekeeper Aim Assist"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" failed closed; no aim-assist patch is active: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(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("General", "Enabled", true, "Master switch. Restart the game after changing this value."); EnableForMouseKeyboard = ((BasePlugin)this).Config.Bind("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("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(0f, 10000f), Array.Empty())); CursorSphereRadius = ((BasePlugin)this).Config.Bind("Acquisition", "CursorSphereRadius", 12f, new ConfigDescription("Radius of the game's cursor ray sphere-cast.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); FrontSphereOffsetX = ((BasePlugin)this).Config.Bind("Acquisition", "FrontSphereOffsetX", 0f, new ConfigDescription("World-space X component of the game's forward-search sphere offset.", (AcceptableValueBase)(object)new AcceptableValueRange(-100f, 100f), Array.Empty())); FrontSphereOffsetY = ((BasePlugin)this).Config.Bind("Acquisition", "FrontSphereOffsetY", 0f, new ConfigDescription("World-space Y component of the game's forward-search sphere offset.", (AcceptableValueBase)(object)new AcceptableValueRange(-100f, 100f), Array.Empty())); FrontSphereOffsetZ = ((BasePlugin)this).Config.Bind("Acquisition", "FrontSphereOffsetZ", 8f, new ConfigDescription("World-space Z component of the game's forward-search sphere offset.", (AcceptableValueBase)(object)new AcceptableValueRange(-100f, 100f), Array.Empty())); FrontSphereRadius = ((BasePlugin)this).Config.Bind("Acquisition", "FrontSphereRadius", 30f, new ConfigDescription("Radius of the game's forward target-search sphere.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 200f), Array.Empty())); FrontCursorAngleThreshold = ((BasePlugin)this).Config.Bind("Acquisition", "FrontCursorAngleThreshold", 180f, new ConfigDescription("Maximum screen-space cursor angle that permits the forward-search fallback.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 180f), Array.Empty())); CursorFollowSpeed = ((BasePlugin)this).Config.Bind("Tracking", "CursorFollowSpeed", 10f, new ConfigDescription("The game's target tracking speed.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 50f), Array.Empty())); CursorBreakRadius = ((BasePlugin)this).Config.Bind("Tracking", "CursorBreakRadius", 0.98f, new ConfigDescription("Multiplier used by the game's current-target break threshold.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); } 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(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(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(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(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 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? _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()) { 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)((Component)controller).GetComponentsInChildren(true)); Transform parent = ((Component)val).transform.parent; ToggleSettingsLine val2 = Object.Instantiate(_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() : 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>((Delegate)new Action(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(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 _read; private readonly Action _writeAndSave; public bool Value => _read(); public KeyboardMouseAimAssistSetting(Func read, Action 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(IEnumerable bindings) { ArgumentNullException.ThrowIfNull(bindings, "bindings"); using IEnumerator 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(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); } } } }