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("ReloadAnyTime")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ReloadAnyTime")] [assembly: AssemblyTitle("ReloadAnyTime")] [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; } } } [BepInPlugin("sparroh.reloadanytime", "ReloadAnyTime", "1.0.1")] [MycoMod(/*Could not decode attribute arguments.*/)] public class SparrohPlugin : BaseUnityPlugin { private struct OriginalAimConstraints { public ActionFireMode CanAimWhileSliding; public bool CanAimWhileReloading; public bool LockSprinting; } public const string PluginGUID = "sparroh.reloadanytime"; public const string PluginName = "ReloadAnyTime"; public const string PluginVersion = "1.0.1"; internal static ManualLogSource Logger; internal static ConfigEntry enableCanAimWhileSliding; internal static ConfigEntry enableCanAimWhileReloading; internal static ConfigEntry enableCanAimWhileSprinting; private static readonly FieldInfo lockSprintingField = AccessTools.Field(typeof(Gun), "lockSprinting"); private static readonly FieldInfo gunDataField = AccessTools.Field(typeof(Gun), "gunData"); private static readonly Dictionary originalConstraints = new Dictionary(); private Harmony harmony; private FileSystemWatcher configWatcher; private static volatile bool pendingConstraintRefresh; private void Awake() { //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Expected O, but got Unknown //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0274: 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, "Allows aiming weapons while reloading."); enableCanAimWhileSprinting = ((BaseUnityPlugin)this).Config.Bind("General", "Can Aim While Sprinting", true, "Allows aiming weapons while sprinting."); enableCanAimWhileSliding.SettingChanged += OnAimConstraintSettingChanged; enableCanAimWhileReloading.SettingChanged += OnAimConstraintSettingChanged; enableCanAimWhileSprinting.SettingChanged += OnAimConstraintSettingChanged; try { SetupFileWatcher(); } catch (Exception ex) { Logger.LogError((object)("Error setting up config file watcher: " + ex.Message)); } harmony = new Harmony("sparroh.reloadanytime"); try { MethodInfo methodInfo = AccessTools.Method(typeof(Gun), "Setup", new Type[3] { typeof(Player), typeof(PlayerAnimation), typeof(IGear) }, (Type[])null); if (methodInfo == null) { Logger.LogError((object)"Could not find Gun.Setup method for patching."); } else { HarmonyMethod val = new HarmonyMethod(typeof(SparrohPlugin), "ModifyWeaponPrefix", (Type[])null); harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception ex2) { Logger.LogError((object)("Error patching Gun.Setup: " + ex2.Message)); } try { MethodInfo methodInfo2 = AccessTools.Method(typeof(Gun), "OnStartAim", (Type[])null, (Type[])null); if (methodInfo2 == null) { Logger.LogError((object)"Could not find Gun.OnStartAim method!"); } else { HarmonyMethod val2 = new HarmonyMethod(typeof(SparrohPlugin), "OnStartAimPrefix", (Type[])null); HarmonyMethod val3 = new HarmonyMethod(typeof(SparrohPlugin), "OnStartAimPostfix", (Type[])null); harmony.Patch((MethodBase)methodInfo2, val2, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo3 = AccessTools.Method(typeof(Gun), "CanAim", (Type[])null, (Type[])null); if (methodInfo3 == null) { Logger.LogError((object)"Could not find Gun.CanAim method!"); } else { HarmonyMethod val4 = new HarmonyMethod(typeof(SparrohPlugin), "CanAimPrefix", (Type[])null); harmony.Patch((MethodBase)methodInfo3, val4, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception ex3) { Logger.LogError((object)("Error setting up aiming patches: " + ex3.Message)); } Logger.LogInfo((object)"ReloadAnyTime v1.0.1 loaded successfully."); } private void Update() { if (pendingConstraintRefresh) { pendingConstraintRefresh = false; ApplyAimConstraintsToAllGuns(); } } private void SetupFileWatcher() { configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.reloadanytime.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 OnAimConstraintSettingChanged(object sender, EventArgs e) { pendingConstraintRefresh = true; } public static void ModifyWeaponPrefix(Gun __instance, IGear prefab) { Gun val = (Gun)(object)((prefab is Gun) ? prefab : null); if (val != null) { AimStateData aimStateData = ((Component)__instance).gameObject.GetComponent(); if ((Object)(object)aimStateData == (Object)null) { aimStateData = ((Component)__instance).gameObject.AddComponent(); } ApplyAimConstraints(val, aimStateData); } } internal static void ApplyAimConstraintsToAllGuns() { try { Gun[] array = Object.FindObjectsOfType(); foreach (Gun val in array) { if (!((Object)(object)val == (Object)null)) { AimStateData aimStateData = ((Component)val).gameObject.GetComponent(); if ((Object)(object)aimStateData == (Object)null) { aimStateData = ((Component)val).gameObject.AddComponent(); } ApplyAimConstraints(val, aimStateData); } } Logger.LogInfo((object)$"Re-applied aim constraints to {array.Length} gun(s)."); } catch (Exception ex) { Logger.LogError((object)("Error re-applying aim constraints: " + ex.Message)); } } internal static void ApplyAimConstraints(Gun gun, AimStateData aimData) { if ((Object)(object)gun == (Object)null) { return; } try { object obj = gunDataField?.GetValue(gun); if (obj != null) { ApplyAimConstraintsToGunDataObject(gun, obj, aimData); } else { ApplyAimConstraintsToGunData(gun, ref gun.GunData, aimData); } } catch (Exception ex) { Logger.LogError((object)("Error applying aim constraints: " + ex.Message)); } } private static OriginalAimConstraints GetOrCaptureOriginals(Gun gun, ActionFireMode canAimWhileSliding, bool canAimWhileReloading, bool lockSprinting) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)gun).GetInstanceID(); if (!originalConstraints.TryGetValue(instanceID, out var value)) { value = new OriginalAimConstraints { CanAimWhileSliding = canAimWhileSliding, CanAimWhileReloading = canAimWhileReloading, LockSprinting = lockSprinting }; originalConstraints[instanceID] = value; } return value; } private static void ApplyAimConstraintsToGunData(Gun gun, ref GunData gunData, AimStateData aimData) { //IL_0028: 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_005a: Unknown result type (might be due to invalid IL or missing references) bool lockSprinting = lockSprintingField != null && (bool)lockSprintingField.GetValue(gun); OriginalAimConstraints orCaptureOriginals = GetOrCaptureOriginals(gun, gunData.fireConstraints.canAimWhileSliding, gunData.fireConstraints.canAimWhileReloading, lockSprinting); gunData.fireConstraints.canAimWhileSliding = (ActionFireMode)(enableCanAimWhileSliding.Value ? 1 : ((int)orCaptureOriginals.CanAimWhileSliding)); gunData.fireConstraints.canAimWhileReloading = enableCanAimWhileReloading.Value || orCaptureOriginals.CanAimWhileReloading; if ((Object)(object)aimData != (Object)null) { aimData.CanAimWhileSprinting = enableCanAimWhileSprinting.Value; } if (lockSprintingField != null) { bool flag = !enableCanAimWhileSprinting.Value && orCaptureOriginals.LockSprinting; lockSprintingField.SetValue(gun, flag); } } private static void ApplyAimConstraintsToGunDataObject(Gun gun, object gunDataObj, AimStateData aimData) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) FieldInfo field = gunDataObj.GetType().GetField("fireConstraints"); if (field == null) { return; } object value = field.GetValue(gunDataObj); if (value == null) { return; } Type type = value.GetType(); FieldInfo field2 = type.GetField("canAimWhileSliding"); FieldInfo field3 = type.GetField("canAimWhileReloading"); if (!(field2 == null) && !(field3 == null)) { bool lockSprinting = lockSprintingField != null && (bool)lockSprintingField.GetValue(gun); OriginalAimConstraints orCaptureOriginals = GetOrCaptureOriginals(gun, (ActionFireMode)field2.GetValue(value), (bool)field3.GetValue(value), lockSprinting); object value2 = (object)(ActionFireMode)(enableCanAimWhileSliding.Value ? 1 : ((int)orCaptureOriginals.CanAimWhileSliding)); object value3 = enableCanAimWhileReloading.Value || orCaptureOriginals.CanAimWhileReloading; field2.SetValue(value, value2); field3.SetValue(value, value3); field.SetValue(gunDataObj, value); if (gunDataField != null && gunDataField.FieldType.IsValueType) { gunDataField.SetValue(gun, gunDataObj); } if ((Object)(object)aimData != (Object)null) { aimData.CanAimWhileSprinting = enableCanAimWhileSprinting.Value; } if (lockSprintingField != null) { bool flag = !enableCanAimWhileSprinting.Value && orCaptureOriginals.LockSprinting; lockSprintingField.SetValue(gun, flag); } } } public static bool OnStartAimPrefix(Gun __instance) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown try { AimStateData component = ((Component)__instance).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && component.CanAimWhileSprinting) { FieldInfo fieldInfo = AccessTools.Field(typeof(Gun), "player"); if (fieldInfo != null) { Player val = (Player)fieldInfo.GetValue(__instance); if ((Object)(object)val != (Object)null) { PropertyInfo propertyInfo = AccessTools.Property(typeof(Player), "IsSprinting"); if (propertyInfo != null) { component.WasSprinting = (bool)propertyInfo.GetValue(val); } } } } } catch (Exception ex) { Logger.LogError((object)("Error in OnStartAimPrefix: " + ex.Message)); } return true; } public static void OnStartAimPostfix(Gun __instance) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown try { AimStateData component = ((Component)__instance).gameObject.GetComponent(); if (!((Object)(object)component != (Object)null) || !component.CanAimWhileSprinting || !component.WasSprinting) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(Gun), "player"); if (fieldInfo != null) { Player val = (Player)fieldInfo.GetValue(__instance); if ((Object)(object)val != (Object)null) { MethodInfo methodInfo = AccessTools.Method(typeof(Player), "ResumeSprint", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(val, null); } } } component.WasSprinting = false; } catch (Exception ex) { Logger.LogError((object)("Error in OnStartAimPostfix: " + ex.Message)); } } public static bool CanAimPrefix(Gun __instance, ref bool __result) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown try { AimStateData component = ((Component)__instance).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && component.CanAimWhileSprinting) { FieldInfo fieldInfo = AccessTools.Field(typeof(Gun), "player"); if (fieldInfo != null) { Player val = (Player)fieldInfo.GetValue(__instance); if ((Object)(object)val != (Object)null) { PropertyInfo propertyInfo = AccessTools.Property(typeof(Player), "IsSprinting"); if (propertyInfo != null && (bool)propertyInfo.GetValue(val)) { FieldInfo fieldInfo2 = AccessTools.Field(typeof(Gun), "isAimInputHeld"); if (fieldInfo2 != null && (bool)fieldInfo2.GetValue(__instance)) { __result = true; return false; } } } } } } catch (Exception ex) { Logger.LogError((object)("Error in CanAimPrefix: " + ex.Message)); } return true; } private void OnDestroy() { if (enableCanAimWhileSliding != null) { enableCanAimWhileSliding.SettingChanged -= OnAimConstraintSettingChanged; } if (enableCanAimWhileReloading != null) { enableCanAimWhileReloading.SettingChanged -= OnAimConstraintSettingChanged; } if (enableCanAimWhileSprinting != null) { enableCanAimWhileSprinting.SettingChanged -= OnAimConstraintSettingChanged; } 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(); } } } public class AimStateData : MonoBehaviour { public bool CanAimWhileSprinting { get; set; } public bool WasSprinting { get; set; } } namespace ReloadAnyTime { public static class MyPluginInfo { public const string PLUGIN_GUID = "ReloadAnyTime"; public const string PLUGIN_NAME = "ReloadAnyTime"; 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) { } } }