Decompiled source of AutoReload v1.0.1

AutoReload.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ComputerysModdingUtilities;
using FishNet.Object;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: StraftatMod(true)]
[assembly: AssemblyCompany("1ntrospective")]
[assembly: AssemblyCopyright("Copyright (c) 1ntrospective")]
[assembly: AssemblyTitle("AutoReload")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace AutoReload;

[BepInPlugin("1ntrospective.straftat.autoreload", "AutoReload", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<bool> ReloadAfterEveryShot;

	internal static ConfigEntry<float> Delay;

	private void Awake()
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Expected O, but got Unknown
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Automatically reload (shotgun, revolvers, etc.) so you don't have to press the reload key.");
		ReloadAfterEveryShot = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ReloadAfterEveryShot", false, "false = reload only when the magazine is empty. true = reload after every shot (like pressing reload each time).");
		Delay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Delay", 0.1f, new ConfigDescription("Seconds to wait after the weapon needs a reload before reloading.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
		try
		{
			AutoReloadPatch.Apply(new Harmony("1ntrospective.straftat.autoreload"));
			Log.LogInfo((object)"AutoReload by 1ntrospective ready.");
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Could not hook the weapons, mod disabled: " + ex));
		}
	}
}
internal static class AutoReloadPatch
{
	private static readonly Dictionary<Type, MethodInfo> reloadMethods = new Dictionary<Type, MethodInfo>();

	private static readonly Dictionary<Type, FieldInfo> fireTimers = new Dictionary<Type, FieldInfo>();

	private static readonly Dictionary<int, float> emptySince = new Dictionary<int, float>();

	private const BindingFlags Any = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	internal static void Apply(Harmony h)
	{
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Expected O, but got Unknown
		Type[] array = new Type[4]
		{
			typeof(Gun),
			typeof(Shotgun),
			typeof(LargeRaycastGun),
			typeof(RepulsiveGun)
		};
		foreach (Type type in array)
		{
			MethodInfo method = type.GetMethod("Update", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo method2 = type.GetMethod("Reload", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method == null || method2 == null)
			{
				Plugin.Log.LogWarning((object)("Skipped " + type.Name + " (Update/Reload not found)."));
				continue;
			}
			reloadMethods[type] = method2;
			fireTimers[type] = type.GetField("fireTimer", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			h.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(AutoReloadPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		Plugin.Log.LogInfo((object)("Hooked " + reloadMethods.Count + " weapon types."));
	}

	public static void Postfix(Weapon __instance)
	{
		try
		{
			if (!Plugin.Enabled.Value)
			{
				return;
			}
			if (!((NetworkBehaviour)__instance).IsOwner || (!__instance.inRightHand && !__instance.inLeftHand) || ((Component)__instance).gameObject.layer == 7 || ((Object)(object)PauseManager.Instance != (Object)null && PauseManager.Instance.pause) || !__instance.reloadWeapon || __instance.isReloading || __instance.sync___get_value_currentAmmo() <= 0)
			{
				return;
			}
			bool num = (Plugin.ReloadAfterEveryShot.Value ? (__instance.chargedBullets != (float)__instance.ammoCharge) : (__instance.chargedBullets <= 0f));
			int instanceID = ((Object)__instance).GetInstanceID();
			if (!num)
			{
				emptySince.Remove(instanceID);
				return;
			}
			Type type = ((object)__instance).GetType();
			if (fireTimers.TryGetValue(type, out var value) && value != null)
			{
				object value2 = value.GetValue(__instance);
				if (value2 is float && (float)value2 > 0f)
				{
					return;
				}
			}
			float time = Time.time;
			MethodInfo value4;
			if (!emptySince.TryGetValue(instanceID, out var value3))
			{
				emptySince[instanceID] = time;
			}
			else if (!(time - value3 < Plugin.Delay.Value) && reloadMethods.TryGetValue(type, out value4) && !(value4 == null))
			{
				emptySince.Remove(instanceID);
				((MonoBehaviour)__instance).StartCoroutine((IEnumerator)value4.Invoke(__instance, null));
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Error: " + ex));
		}
	}
}