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));
}
}
}