Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HandgunEnhancementMod v1.3.0
Handgun Mod.dll
Decompiled 10 months agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Handgun Mod")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Handgun Mod")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("5dca9d7d-cc77-4ee6-9aec-237cd43472c9")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("com.Dileppy.repomods.HandgunEnhancementMod", "Handgun Enhancement Mod", "1.3.0")] public class HandgunRateMod : BaseUnityPlugin { [HarmonyPatch] private static class Patch_StateReloading { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("ItemGun"); if (type == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { type = assembly.GetType("ItemGun"); if (type != null) { break; } } } if (type == null) { Debug.LogError((object)"[HandgunRateMod] Could not find ItemGun type."); return null; } return AccessTools.Method(type, "StateReloading", new Type[1] { typeof(bool) }, (Type[])null); } private static void Postfix(object __instance) { try { if (!IsRuntimeEnabled() || __instance == null) { return; } Type type = __instance.GetType(); FieldInfo field = type.GetField("shootCooldown", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = type.GetField("stateTimeMax", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null) && !(field2 == null)) { float num = Convert.ToSingle(field.GetValue(__instance)); float num2 = Math.Max(0f, CooldownMultiplier.Value); float num3 = num * num2; bool value = AllowFullAuto.Value; float value2 = MinAllowedCooldown.Value; float num4 = num3; if (!value && num4 < value2) { num4 = value2; } field2.SetValue(__instance, num4); if (Time.frameCount % 300 == 0) { Debug.Log((object)$"[HandgunRateMod] Applied cooldown multiplier {num2} (shootCooldown={num}) => stateTimeMax={num4} (allowFull={value})"); } } } catch (Exception arg) { Debug.LogError((object)$"[HandgunRateMod] StateReloading.Postfix error: {arg}"); } } } [HarmonyPatch] private static class Patch_ItemGun_Start { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("ItemGun"); if (type == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { type = assembly.GetType("ItemGun"); if (type != null) { break; } } } if (type == null) { return null; } return AccessTools.Method(type, "Start", Type.EmptyTypes, (Type[])null); } private static void Postfix(object __instance) { try { if (IsRuntimeEnabled() && __instance != null) { Type type = __instance.GetType(); FieldInfo field = type.GetField("batteryDrain", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { float num = Convert.ToSingle(field.GetValue(__instance)); float num2 = num * BatteryDrainMultiplier.Value; field.SetValue(__instance, num2); } FieldInfo field2 = type.GetField("numberOfBullets", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null) { field2.SetValue(__instance, BulletCountOverride.Value); } FieldInfo field3 = type.GetField("gunRecoilForce", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field4 = type.GetField("cameraShakeMultiplier", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field5 = type.GetField("torqueMultiplier", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (ZeroRecoil.Value) { field3?.SetValue(__instance, 0f); field4?.SetValue(__instance, 0f); field5?.SetValue(__instance, 0f); } FieldInfo field6 = type.GetField("gunRandomSpread", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (PerfectAccuracy.Value && field6 != null) { field6.SetValue(__instance, 0f); } } } catch (Exception arg) { Debug.LogError((object)$"[HandgunRateMod] ItemGun.Start postfix error: {arg}"); } } } [HarmonyPatch] private static class Patch_ItemGunBullet_ActivateAll { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("ItemGunBullet"); if (type == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { type = assembly.GetType("ItemGunBullet"); if (type != null) { break; } } } if (type == null) { Debug.LogWarning((object)"[HandgunRateMod] ItemGunBullet type not found; bullet modifications disabled."); return null; } MethodInfo methodInfo = AccessTools.Method(type, "ActivateAll", Type.EmptyTypes, (Type[])null); if (methodInfo == null) { Debug.LogWarning((object)"[HandgunRateMod] ItemGunBullet.ActivateAll not found; bullet modifications disabled."); } return methodInfo; } private static void Postfix(object __instance) { try { if (!IsRuntimeEnabled() || __instance == null) { return; } Type type = __instance.GetType(); string[] array = new string[5] { "speed", "bulletSpeed", "velocity", "bulletVelocity", "moveSpeed" }; string[] array2 = array; foreach (string name in array2) { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && (field.FieldType == typeof(float) || field.FieldType == typeof(double))) { float num = Convert.ToSingle(field.GetValue(__instance)); float value = num * BulletSpeedMultiplier.Value; field.SetValue(__instance, ConvertFieldValue(field.FieldType, value)); break; } } string[] array3 = new string[4] { "damage", "hitDamage", "damageAmount", "hurtAmount" }; string[] array4 = array3; foreach (string name2 in array4) { FieldInfo field2 = type.GetField(name2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null && (field2.FieldType == typeof(float) || field2.FieldType == typeof(double) || field2.FieldType == typeof(int))) { float num2 = Convert.ToSingle(field2.GetValue(__instance)); float value2 = num2 * BulletDamageMultiplier.Value; field2.SetValue(__instance, ConvertFieldValue(field2.FieldType, value2)); break; } } if (ExplosiveBullets.Value) { string[] array5 = new string[3] { "explosive", "isExplosive", "explodeOnHit" }; string[] array6 = array5; foreach (string name3 in array6) { FieldInfo field3 = type.GetField(name3, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field3 != null && field3.FieldType == typeof(bool)) { field3.SetValue(__instance, true); break; } } } if (!PenetrationEnabled.Value) { return; } string[] array7 = new string[5] { "penetrationCount", "penetration", "maxPenetrations", "pierceCount", "pierce" }; string[] array8 = array7; foreach (string name4 in array8) { FieldInfo field4 = type.GetField(name4, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field4 != null) { if (field4.FieldType == typeof(int)) { field4.SetValue(__instance, PenetrationCount.Value); } else { field4.SetValue(__instance, ConvertFieldValue(field4.FieldType, PenetrationCount.Value)); } break; } } } catch (Exception arg) { Debug.LogError((object)$"[HandgunRateMod] ItemGunBullet.ActivateAll postfix error: {arg}"); } } private static object ConvertFieldValue(Type fieldType, float value) { if (fieldType == typeof(float)) { return value; } if (fieldType == typeof(double)) { return (double)value; } if (fieldType == typeof(int)) { return (int)Math.Round(value); } return value; } } public static ConfigEntry<float> CooldownMultiplier; public static ConfigEntry<float> BatteryDrainMultiplier; public static ConfigEntry<int> BulletCountOverride; public static ConfigEntry<bool> ZeroRecoil; public static ConfigEntry<bool> PerfectAccuracy; public static ConfigEntry<float> BulletSpeedMultiplier; public static ConfigEntry<float> BulletDamageMultiplier; public static ConfigEntry<bool> ExplosiveBullets; public static ConfigEntry<float> ExplosionRadius; public static ConfigEntry<bool> PenetrationEnabled; public static ConfigEntry<int> PenetrationCount; public static ConfigEntry<KeyCode> ToggleKey; public static ConfigEntry<bool> AllowFullAuto; public static ConfigEntry<float> MinAllowedCooldown; private Harmony _harmony; private bool _enabled = true; private void Awake() { //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Expected O, but got Unknown CooldownMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CooldownMultiplier", 0.25f, "Multiply shootCooldown (1=normal, 0.25=4x faster, 0=instant/full-auto if AllowFullAuto=true)"); BatteryDrainMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "BatteryDrainMultiplier", 0.1f, "Multiply battery drain (0=infinite)"); BulletCountOverride = ((BaseUnityPlugin)this).Config.Bind<int>("General", "BulletMultiplier", 2, "Override numberOfBullets"); ZeroRecoil = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ZeroRecoil", true, "Removes recoil force and camera shake"); PerfectAccuracy = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PerfectAccuracy", false, "Removes spread / randomness and may also crash game"); BulletSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Bullet", "BulletSpeedMultiplier", 1.5f, "Multiply instantiated bullet speed (1=unchanged)"); BulletDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Bullet", "BulletDamageMultiplier", 1.5f, "Multiply bullet damage (1=unchanged)"); ExplosiveBullets = ((BaseUnityPlugin)this).Config.Bind<bool>("Bullet", "ExplosiveBullets", false, "If true, try to mark bullets explosive / create explosion on hit"); ExplosionRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Bullet", "ExplosionRadius", 2.5f, "Explosion radius if explosives are supported"); PenetrationEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Bullet", "EnablePenetration", false, "Allow bullets to penetrate targets if supported"); PenetrationCount = ((BaseUnityPlugin)this).Config.Bind<int>("Bullet", "PenetrationCount", 2, "How many objects a penetrating bullet can pass through"); ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)288, "Toggle the mod ON/OFF with this key"); AllowFullAuto = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "AllowFullAuto", false, "Allow zero cooldown (danger: may cause infinite bullet loops). Default false."); MinAllowedCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "MinAllowedCooldown", 0.02f, "Minimum allowed effective cooldown (seconds) unless AllowFullAuto=true."); _harmony = new Harmony("com.Dileppy.repomods.HandgunEnhancementMod"); try { _harmony.PatchAll(); Debug.Log((object)$"[HandgunRateMod] Patched. CooldownMultiplier={CooldownMultiplier.Value}, BulletSpeed x{BulletSpeedMultiplier.Value}"); } catch (Exception arg) { Debug.LogError((object)$"[HandgunRateMod] PatchAll failed: {arg}"); } } private void OnDestroy() { try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(ToggleKey.Value)) { _enabled = !_enabled; Debug.Log((object)$"[HandgunRateMod] Toggled enabled => {_enabled}"); } } private static bool IsRuntimeEnabled() { try { HandgunRateMod handgunRateMod = Object.FindObjectOfType<HandgunRateMod>(); if ((Object)(object)handgunRateMod == (Object)null) { return true; } FieldInfo field = typeof(HandgunRateMod).GetField("_enabled", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { return Convert.ToBoolean(field.GetValue(handgunRateMod)); } return true; } catch { return true; } } }