Decompiled source of ReloadAnyTime v1.0.1

BepInEx/plugins/ReloadAnyTime.dll

Decompiled a week ago
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<bool> enableCanAimWhileSliding;

	internal static ConfigEntry<bool> enableCanAimWhileReloading;

	internal static ConfigEntry<bool> 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<int, OriginalAimConstraints> originalConstraints = new Dictionary<int, OriginalAimConstraints>();

	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<bool>("General", "Can Aim While Sliding", true, "Allows aiming weapons while sliding.");
		enableCanAimWhileReloading = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Can Aim While Reloading", true, "Allows aiming weapons while reloading.");
		enableCanAimWhileSprinting = ((BaseUnityPlugin)this).Config.Bind<bool>("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<AimStateData>();
			if ((Object)(object)aimStateData == (Object)null)
			{
				aimStateData = ((Component)__instance).gameObject.AddComponent<AimStateData>();
			}
			ApplyAimConstraints(val, aimStateData);
		}
	}

	internal static void ApplyAimConstraintsToAllGuns()
	{
		try
		{
			Gun[] array = Object.FindObjectsOfType<Gun>();
			foreach (Gun val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					AimStateData aimStateData = ((Component)val).gameObject.GetComponent<AimStateData>();
					if ((Object)(object)aimStateData == (Object)null)
					{
						aimStateData = ((Component)val).gameObject.AddComponent<AimStateData>();
					}
					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<AimStateData>();
			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<AimStateData>();
			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<AimStateData>();
			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)
		{
		}
	}
}