using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Pigeon.Movement; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("AimAnyTime")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AimAnyTime")] [assembly: AssemblyTitle("AimAnyTime")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [HarmonyPatch] public static class CanAimPatches { private static readonly FieldInfo isAimInputHeldField = AccessTools.Field(typeof(Gun), "isAimInputHeld"); private static readonly FieldInfo lastPressedAimTimeField = AccessTools.Field(typeof(Gun), "lastPressedAimTime"); private static readonly FieldInfo lastPressedFireTimeField = AccessTools.Field(typeof(Gun), "lastPressedFireTime"); private static readonly FieldInfo gunDataField = AccessTools.Field(typeof(Gun), "gunData"); [HarmonyPatch(typeof(Gun), "CanAim")] [HarmonyPrefix] private static bool CanAimPrefix(Gun __instance, ref bool __result) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) try { Player player = __instance.Player; if ((Object)(object)player == (Object)null || isAimInputHeldField == null || gunDataField == null) { return true; } bool num = (bool)isAimInputHeldField.GetValue(__instance); FireConstraints fireConstraints = ((GunData)gunDataField.GetValue(__instance)).fireConstraints; ActionFireMode val = ((player.OverrideCanAimWhileSliding > fireConstraints.canAimWhileSliding) ? player.OverrideCanAimWhileSliding : fireConstraints.canAimWhileSliding); if (SparrohPlugin.enableCanAimWhileSliding.Value) { val = (ActionFireMode)1; } bool flag = (int)val > 0 || !player.Sliding; bool flag2 = !__instance.Reloading || fireConstraints.canAimWhileReloading || SparrohPlugin.enableCanAimWhileReloading.Value; bool flag3 = num && flag && flag2 && !player.IsFireLocked; if (flag3) { if (player.IsSprinting && !SparrohPlugin.enableCanAimWhileSprinting.Value) { float num2 = ((lastPressedAimTimeField != null) ? ((float)lastPressedAimTimeField.GetValue(__instance)) : 0f); if (player.StartSprintTime >= num2) { flag3 = false; } else { player.StopSprint(); } } } else if (__instance.IsAiming && !__instance.WantsToFire && !SparrohPlugin.enableCanAimWhileSprinting.Value) { float num3 = ((lastPressedFireTimeField != null) ? ((float)lastPressedFireTimeField.GetValue(__instance)) : 0f); if (Time.time - Mathf.Max(__instance.LastFireTime, num3) > 0.5f) { player.ResumeSprint(); } } __result = flag3; return false; } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("Error in CanAim patch: " + ex.Message)); return true; } } } [HarmonyPatch] public static class GunSetupPatches { [HarmonyPatch(typeof(Gun), "Setup", new Type[] { typeof(Player), typeof(PlayerAnimation), typeof(IGear) })] [HarmonyPostfix] private static void SetupPostfix(Gun __instance) { try { SparrohPlugin.ApplyLockSprinting(__instance); SparrohPlugin.ApplySlidingOverrideToLocalPlayer(); } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("Error in Gun.Setup patch: " + ex.Message)); } } [HarmonyPatch(typeof(Gun), "Enable")] [HarmonyPrefix] private static void EnablePrefix(Gun __instance) { try { SparrohPlugin.ApplyLockSprinting(__instance); SparrohPlugin.ApplySlidingOverrideToLocalPlayer(); } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("Error in Gun.Enable prefix: " + ex.Message)); } } } [BepInPlugin("sparroh.aimanytime", "AimAnyTime", "1.1.0")] [MycoMod(/*Could not decode attribute arguments.*/)] public class SparrohPlugin : BaseUnityPlugin { public const string PluginGUID = "sparroh.aimanytime"; public const string PluginName = "AimAnyTime"; public const string PluginVersion = "1.1.0"; internal static ManualLogSource Logger; internal static ConfigEntry enableCanAimWhileSliding; internal static ConfigEntry enableCanAimWhileReloading; internal static ConfigEntry enableCanAimWhileSprinting; internal static ConfigEntry showReloadAnimWhileAiming; private static readonly FieldInfo lockSprintingField = AccessTools.Field(typeof(Gun), "lockSprinting"); private static readonly Dictionary originalLockSprinting = new Dictionary(); private Harmony harmony; private FileSystemWatcher configWatcher; private static volatile bool pendingConstraintRefresh; private void Awake() { //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; enableCanAimWhileSliding = ((BaseUnityPlugin)this).Config.Bind("General", "Can Aim While Sliding", true, "Allows aiming weapons while sliding."); enableCanAimWhileReloading = ((BaseUnityPlugin)this).Config.Bind("General", "Can Aim While Reloading", true, "Keeps ADS active while reloading (FOV/aim state). Pair with Show Reload Anim While Aiming for visible reload feedback."); enableCanAimWhileSprinting = ((BaseUnityPlugin)this).Config.Bind("General", "Can Aim While Sprinting", true, "Allows aiming weapons while sprinting without cancelling sprint."); showReloadAnimWhileAiming = ((BaseUnityPlugin)this).Config.Bind("General", "Show Reload Anim While Aiming", true, "While ADS-reloading, temporarily hide the aim pose so the reload animation is visible. ADS state (FOV) stays active."); enableCanAimWhileSliding.SettingChanged += OnSettingChanged; enableCanAimWhileReloading.SettingChanged += OnSettingChanged; enableCanAimWhileSprinting.SettingChanged += OnSettingChanged; showReloadAnimWhileAiming.SettingChanged += OnSettingChanged; try { SetupFileWatcher(); } catch (Exception ex) { Logger.LogError((object)("Error setting up config file watcher: " + ex.Message)); } harmony = new Harmony("sparroh.aimanytime"); try { harmony.PatchAll(typeof(CanAimPatches)); harmony.PatchAll(typeof(ReloadAimAnimPatches)); harmony.PatchAll(typeof(GunSetupPatches)); Logger.LogInfo((object)"Harmony patches applied."); } catch (Exception ex2) { Logger.LogError((object)("Error applying patches: " + ex2.Message)); } Logger.LogInfo((object)"AimAnyTime v1.1.0 loaded successfully."); } private void Update() { if (pendingConstraintRefresh) { pendingConstraintRefresh = false; ApplyLockSprintingToAllGuns(); ApplySlidingOverrideToLocalPlayer(); } } private void SetupFileWatcher() { configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.aimanytime.cfg"); configWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite; configWatcher.Changed += OnConfigFileChanged; configWatcher.Created += OnConfigFileChanged; configWatcher.Renamed += OnConfigFileChanged; configWatcher.EnableRaisingEvents = true; } private void OnConfigFileChanged(object sender, FileSystemEventArgs e) { try { ((BaseUnityPlugin)this).Config.Reload(); pendingConstraintRefresh = true; Logger.LogInfo((object)"Config reloaded from disk."); } catch (Exception ex) { Logger.LogError((object)("Error reloading config: " + ex.Message)); } } private static void OnSettingChanged(object sender, EventArgs e) { pendingConstraintRefresh = true; } internal static void ApplySlidingOverrideToLocalPlayer() { try { Player localPlayer = Player.LocalPlayer; if (!((Object)(object)localPlayer == (Object)null)) { localPlayer.OverrideCanAimWhileSliding = (ActionFireMode)(enableCanAimWhileSliding.Value ? 1 : 0); } } catch (Exception ex) { Logger.LogError((object)("Error applying sliding aim override: " + ex.Message)); } } internal static void ApplyLockSprintingToAllGuns() { try { Gun[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { ApplyLockSprinting(array[i]); } } } catch (Exception ex) { Logger.LogError((object)("Error re-applying lockSprinting: " + ex.Message)); } } internal static void ApplyLockSprinting(Gun gun) { if ((Object)(object)gun == (Object)null || lockSprintingField == null) { return; } try { int instanceID = ((Object)gun).GetInstanceID(); bool flag = (bool)lockSprintingField.GetValue(gun); if (!originalLockSprinting.TryGetValue(instanceID, out var value)) { value = flag; originalLockSprinting[instanceID] = value; } bool flag2 = !enableCanAimWhileSprinting.Value && value; if (flag == flag2) { return; } lockSprintingField.SetValue(gun, flag2); if (!gun.Active) { return; } Player player = gun.Player; if ((Object)(object)player != (Object)null) { if (flag && !flag2) { player.SprintLocks = Math.Max(0, player.SprintLocks - 1); } else if (!flag && flag2) { int sprintLocks = player.SprintLocks; player.SprintLocks = sprintLocks + 1; } } } catch (Exception ex) { Logger.LogError((object)("Error applying lockSprinting: " + ex.Message)); } } private void OnDestroy() { if (enableCanAimWhileSliding != null) { enableCanAimWhileSliding.SettingChanged -= OnSettingChanged; } if (enableCanAimWhileReloading != null) { enableCanAimWhileReloading.SettingChanged -= OnSettingChanged; } if (enableCanAimWhileSprinting != null) { enableCanAimWhileSprinting.SettingChanged -= OnSettingChanged; } if (showReloadAnimWhileAiming != null) { showReloadAnimWhileAiming.SettingChanged -= OnSettingChanged; } if (configWatcher != null) { configWatcher.EnableRaisingEvents = false; configWatcher.Changed -= OnConfigFileChanged; configWatcher.Created -= OnConfigFileChanged; configWatcher.Renamed -= OnConfigFileChanged; configWatcher.Dispose(); configWatcher = null; } Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } [HarmonyPatch] public static class ReloadAimAnimPatches { private static readonly FieldInfo animatorField = AccessTools.Field(typeof(Gun), "animator"); private static readonly FieldInfo aimTransitionDurationField = AccessTools.Field(typeof(Gun), "aimTransitionDuration"); private static readonly PropertyInfo enableAimAnimationsProperty = AccessTools.Property(typeof(Gun), "EnableAimAnimations"); private static bool ShouldShowReloadOverAim(Gun gun) { if (SparrohPlugin.enableCanAimWhileReloading != null && SparrohPlugin.enableCanAimWhileReloading.Value && SparrohPlugin.showReloadAnimWhileAiming != null && SparrohPlugin.showReloadAnimWhileAiming.Value && (Object)(object)gun != (Object)null && gun.Reloading) { return gun.IsAiming; } return false; } private static void HideAimLayerForReload(Gun gun, bool instant) { if (animatorField == null) { return; } object? value = animatorField.GetValue(gun); PlayerAnimation val = (PlayerAnimation)((value is PlayerAnimation) ? value : null); if (!((Object)(object)val == (Object)null)) { float num = 0f; if (!instant && aimTransitionDurationField != null) { num = (float)aimTransitionDurationField.GetValue(gun); } val.DisableAimLayer(num); } } [HarmonyPatch(typeof(Gun), "HandleAim")] [HarmonyPostfix] private static void HandleAimPostfix(Gun __instance) { try { if (!ShouldShowReloadOverAim(__instance)) { return; } if (enableAimAnimationsProperty != null) { object value = enableAimAnimationsProperty.GetValue(__instance); if (value is bool && !(bool)value) { return; } } HideAimLayerForReload(__instance, instant: true); } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("Error in HandleAim reload-anim patch: " + ex.Message)); } } [HarmonyPatch(typeof(Gun), "StartReloadAnimation")] [HarmonyPostfix] private static void StartReloadAnimationPostfix(Gun __instance) { try { if (SparrohPlugin.enableCanAimWhileReloading != null && SparrohPlugin.enableCanAimWhileReloading.Value && SparrohPlugin.showReloadAnimWhileAiming != null && SparrohPlugin.showReloadAnimWhileAiming.Value && !((Object)(object)__instance == (Object)null) && __instance.IsAiming) { HideAimLayerForReload(__instance, instant: true); } } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("Error in StartReloadAnimation patch: " + ex.Message)); } } } namespace AimAnyTime { public static class MyPluginInfo { public const string PLUGIN_GUID = "AimAnyTime"; public const string PLUGIN_NAME = "AimAnyTime"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }