Please disclose if your mod was created primarily 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 SlipperyShotgun v1.3.0
SlipperyShotgun.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CSync.Extensions; using CSync.Lib; using HarmonyLib; using Microsoft.CodeAnalysis; using PiggyVarietyMod.Patches; using SlipperyShotgun.Configuration; using SlipperyShotgun.Logic; using SlipperyShotgun.Patches; using StaticNetcodeLib; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SlipperyShotgun")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0+e9c0fd92835bc3333fb3a9c468d9d02a6b2d1c6e")] [assembly: AssemblyProduct("SlipperyShotgun")] [assembly: AssemblyTitle("SlipperyShotgun")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } namespace SlipperyShotgun { public static class AssetBundleManager { private static AssetBundle? _bundle; public static AssetBundle? LoadEmbeddedAssetBundle() { if ((Object)(object)_bundle != (Object)null) { return _bundle; } Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string name) => name.EndsWith("slippery")); if (text == null) { SlipperyShotgun.Logger.LogError((object)"Failed to find embedded resource ending with 'slippery'"); return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { SlipperyShotgun.Logger.LogError((object)("Failed to load embedded resource: " + text)); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); _bundle = AssetBundle.LoadFromMemory(array); if ((Object)(object)_bundle == (Object)null) { SlipperyShotgun.Logger.LogError((object)"Failed to load AssetBundle from memory!"); return null; } return _bundle; } } [BepInPlugin("com.itekso.SlipperyShotgun", "SlipperyShotgun", "1.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency("com.sigurd.csync", "5.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SlipperyShotgun : BaseUnityPlugin { internal const string modGUID = "com.itekso.SlipperyShotgun"; private const string modName = "SlipperyShotgun"; private const string modVersion = "1.3.0"; public static SlipperyShotgun Instance { get; private set; } public static ManualLogSource Logger { get; private set; } private static Harmony Harmony { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; SlipperyOptions.Initialize(((BaseUnityPlugin)this).Config); PatchShotgun(); if (SlipperyOptions.LogLevelConfig.Value != 0) { Logger.LogInfo((object)"SlipperyShotgun v1.3.0 has loaded!"); } if (Chainloader.PluginInfos.Keys.Any((string k) => k == "Piggy.PiggyVarietyMod")) { Logger.LogInfo((object)"Piggy's Variety Mod found. Applying patches for RevolverItem and M4Item."); Harmony.PatchAll(typeof(RevolverItemPatch)); Harmony.PatchAll(typeof(M4ItemPatch)); } else { Logger.LogInfo((object)"Piggy's Variety Mod not found. RevolverItem and M4Item patches skipped."); } } private static void PatchShotgun() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("com.itekso.SlipperyShotgun"); } if (SlipperyOptions.LogLevelConfig.Value == SlipperyOptions.LogLevel.Debug) { Logger.LogDebug((object)"Patching ShotgunItem..."); } Harmony.PatchAll(typeof(ShotgunItemPatch)); if (SlipperyOptions.LogLevelConfig.Value == SlipperyOptions.LogLevel.Debug) { Logger.LogDebug((object)"Finished patching ShotgunItem!"); } } internal static void Unpatch() { if (SlipperyOptions.LogLevelConfig.Value == SlipperyOptions.LogLevel.Debug) { Logger.LogDebug((object)"Unpatching..."); } Harmony.UnpatchSelf(); if (SlipperyOptions.LogLevelConfig.Value == SlipperyOptions.LogLevel.Debug) { Logger.LogDebug((object)"Finished unpatching!"); } } public static GameObject? FindPrefabByName(string prefabName) { string prefabName2 = prefabName; GameObject val = ((IEnumerable<GameObject>)Resources.FindObjectsOfTypeAll<GameObject>()).FirstOrDefault((Func<GameObject, bool>)((GameObject obj) => ((Object)obj).name == prefabName2)); if ((Object)(object)val == (Object)null) { Logger.LogError((object)("Prefab '" + prefabName2 + "' not found.")); } return val; } public static AudioClip? LoadSoundEffect(string soundName) { AssetBundle val = AssetBundleManager.LoadEmbeddedAssetBundle(); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Failed to load asset bundle."); return null; } AudioClip val2 = val.LoadAsset<AudioClip>(soundName); if ((Object)(object)val2 == (Object)null) { Logger.LogError((object)("Failed to load sound effect: " + soundName)); } return val2; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "SlipperyShotgun"; public const string PLUGIN_NAME = "SlipperyShotgun"; public const string PLUGIN_VERSION = "1.2.0"; } } namespace SlipperyShotgun.Patches { [HarmonyPatch(typeof(M4Item))] public static class M4ItemPatch { [HarmonyPatch("Start")] [HarmonyPostfix] public static void PostfixStart(M4Item __instance) { SlipperyBehaviour slipperyBehaviour = ((Component)__instance).gameObject.GetComponent<SlipperyBehaviour>() ?? ((Component)__instance).gameObject.AddComponent<SlipperyBehaviour>(); slipperyBehaviour.RandomSeed = ((GrabbableObject)__instance).itemProperties.itemId + StartOfRound.Instance.currentLevelID + StartOfRound.Instance.randomMapSeed; } [HarmonyPatch("ShootGunAndSync")] [HarmonyPrefix] public static bool PrefixShootGunAndSync(M4Item __instance, bool heldByPlayer) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (!heldByPlayer) { return true; } if (SlipperyOptions.LogLevelConfig.Value == SlipperyOptions.LogLevel.Debug) { SlipperyShotgun.Logger.LogDebug((object)$"Configured drop chance: {SlipperyOptions.RifleDropChance.Value}"); } SlipperyBehaviour component = ((Component)__instance).gameObject.GetComponent<SlipperyBehaviour>(); if (!component.ShouldDropItem(SlipperyOptions.RifleDropChance.Value)) { return true; } __instance.isFiring = false; __instance.isReloading = false; __instance.cantFire = false; __instance.isInspecting = false; ((MonoBehaviour)((GrabbableObject)__instance).playerHeldBy).StartCoroutine(((GrabbableObject)__instance).playerHeldBy.waitToEndOfFrameToDiscard()); SlipperyManager.PlaySillyExtrasServerRpc(NetworkObjectReference.op_Implicit(((Component)component).gameObject)); SlipperyManager.PlaySoundEffectServerRpc(NetworkObjectReference.op_Implicit(((Component)component).gameObject)); if (SlipperyOptions.LogLevelConfig.Value != 0) { SlipperyShotgun.Logger.LogInfo((object)"You call yourself a Scavenger?!"); } return !SlipperyOptions.RifleDropPreventsFiring.Value; } } [HarmonyPatch(typeof(RevolverItem))] public static class RevolverItemPatch { [HarmonyPatch("Start")] [HarmonyPostfix] public static void PostfixStart(RevolverItem __instance) { SlipperyBehaviour slipperyBehaviour = ((Component)__instance).gameObject.GetComponent<SlipperyBehaviour>() ?? ((Component)__instance).gameObject.AddComponent<SlipperyBehaviour>(); slipperyBehaviour.RandomSeed = ((GrabbableObject)__instance).itemProperties.itemId + StartOfRound.Instance.currentLevelID + StartOfRound.Instance.randomMapSeed; } [HarmonyPatch("ShootGunAndSync")] [HarmonyPrefix] public static bool PrefixShootGunAndSync(RevolverItem __instance, bool heldByPlayer) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if (!heldByPlayer) { return true; } if (SlipperyOptions.LogLevelConfig.Value == SlipperyOptions.LogLevel.Debug) { SlipperyShotgun.Logger.LogDebug((object)$"Configured drop chance: {SlipperyOptions.RevolverDropChance.Value}"); } SlipperyBehaviour component = ((Component)__instance).gameObject.GetComponent<SlipperyBehaviour>(); if (!component.ShouldDropItem(SlipperyOptions.RevolverDropChance.Value)) { return true; } __instance.isReloading = false; __instance.cantFire = false; __instance.isCylinderMoving = false; ((MonoBehaviour)((GrabbableObject)__instance).playerHeldBy).StartCoroutine(((GrabbableObject)__instance).playerHeldBy.waitToEndOfFrameToDiscard()); SlipperyManager.PlaySillyExtrasServerRpc(NetworkObjectReference.op_Implicit(((Component)component).gameObject)); SlipperyManager.PlaySoundEffectServerRpc(NetworkObjectReference.op_Implicit(((Component)component).gameObject)); if (SlipperyOptions.LogLevelConfig.Value != 0) { SlipperyShotgun.Logger.LogInfo((object)"This town ain't big enough for the two of us!"); } return !SlipperyOptions.RevolverDropPreventsFiring.Value; } } [HarmonyPatch(typeof(ShotgunItem))] public static class ShotgunItemPatch { [HarmonyPatch("Start")] [HarmonyPostfix] public static void PostfixStart(ShotgunItem __instance) { SlipperyBehaviour slipperyBehaviour = ((Component)__instance).gameObject.GetComponent<SlipperyBehaviour>() ?? ((Component)__instance).gameObject.AddComponent<SlipperyBehaviour>(); slipperyBehaviour.RandomSeed = ((GrabbableObject)__instance).itemProperties.itemId + StartOfRound.Instance.currentLevelID + StartOfRound.Instance.randomMapSeed; } [HarmonyPatch("ShootGunAndSync")] [HarmonyPrefix] public static bool PrefixShootGunAndSync(ShotgunItem __instance, bool heldByPlayer) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (!heldByPlayer) { return true; } if (SlipperyOptions.LogLevelConfig.Value == SlipperyOptions.LogLevel.Debug) { SlipperyShotgun.Logger.LogDebug((object)$"Configured drop chance: {SlipperyOptions.ShotgunDropChance.Value}"); } SlipperyBehaviour component = ((Component)__instance).gameObject.GetComponent<SlipperyBehaviour>(); if (!component.ShouldDropItem(SlipperyOptions.ShotgunDropChance.Value)) { return true; } ((MonoBehaviour)((GrabbableObject)__instance).playerHeldBy).StartCoroutine(((GrabbableObject)__instance).playerHeldBy.waitToEndOfFrameToDiscard()); SlipperyManager.PlaySillyExtrasServerRpc(NetworkObjectReference.op_Implicit(((Component)component).gameObject)); SlipperyManager.PlaySoundEffectServerRpc(NetworkObjectReference.op_Implicit(((Component)component).gameObject)); if (SlipperyOptions.LogLevelConfig.Value != 0) { SlipperyShotgun.Logger.LogInfo((object)"Try putting more stats in to handling!"); } return !SlipperyOptions.ShotgunDropPreventsFiring.Value; } } } namespace SlipperyShotgun.Logic { public class SlipperyBehaviour : MonoBehaviour { public int RandomSeed = 0; private int LocalRolls = 0; private int NetworkedRolls = 0; private int RollRandomAndSync() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) int result = new Random(RandomSeed + NetworkedRolls + LocalRolls).Next(0, 100); LocalRolls++; SlipperyManager.IncrementRollsServerRpc(NetworkObjectReference.op_Implicit(((Component)this).gameObject)); return result; } public void IncrementRolls() { NetworkedRolls++; if (LocalRolls > 0) { LocalRolls--; } } public bool ShouldDropItem(int dropChance) { int num = RollRandomAndSync(); if (SlipperyOptions.LogLevelConfig.Value == SlipperyOptions.LogLevel.Debug) { SlipperyShotgun.Logger.LogDebug((object)$"Generated random number: {num}"); } return num < dropChance; } public void PlaySillyExtras(SlipperyOptions.SillyExtrasOption sillyExtrasOption) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (1 == 0) { } string text = sillyExtrasOption switch { SlipperyOptions.SillyExtrasOption.Confetti => "EasterEggExplosionParticle", SlipperyOptions.SillyExtrasOption.Explosion => "ExplosionEffect", SlipperyOptions.SillyExtrasOption.CarBomb => "VehicleExplosionEffect", _ => null, }; if (1 == 0) { } string text2 = text; if (text2 != null) { GameObject val = SlipperyShotgun.FindPrefabByName(text2); if (!((Object)(object)val == (Object)null)) { Object.Instantiate<GameObject>(val, ((Component)this).transform.position, Quaternion.identity); } } } public void PlaySoundEffect(SlipperyOptions.SoundEffectOption soundEffectOption) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (1 == 0) { } string text = soundEffectOption switch { SlipperyOptions.SoundEffectOption.Bonk => "Bonk", SlipperyOptions.SoundEffectOption.Boo => "Boo", SlipperyOptions.SoundEffectOption.Slip => "Slip", _ => null, }; if (1 == 0) { } string text2 = text; if (text2 != null) { AudioClip val = SlipperyShotgun.LoadSoundEffect(text2); if (!((Object)(object)val == (Object)null)) { AudioSource.PlayClipAtPoint(val, ((Component)this).transform.position); } } } } [StaticNetcode] public static class SlipperyManager { [ServerRpc] public static void IncrementRollsServerRpc(NetworkObjectReference slipperyNGO) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) IncrementRollsClientRpc(slipperyNGO); } [ClientRpc] private static void IncrementRollsClientRpc(NetworkObjectReference slipperyNGO) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) GameObject obj = NetworkObjectReference.op_Implicit(slipperyNGO); SlipperyBehaviour slipperyBehaviour = ((obj != null) ? obj.GetComponent<SlipperyBehaviour>() : null); if (!((Object)(object)slipperyBehaviour == (Object)null)) { slipperyBehaviour.IncrementRolls(); } } [ServerRpc] public static void PlaySillyExtrasServerRpc(NetworkObjectReference slipperyNGO) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PlaySillyExtrasClientRpc(slipperyNGO, SlipperyOptions.SillyExtras.Value); } [ClientRpc] private static void PlaySillyExtrasClientRpc(NetworkObjectReference slipperyNGO, SlipperyOptions.SillyExtrasOption sillyExtrasOption) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) GameObject obj = NetworkObjectReference.op_Implicit(slipperyNGO); SlipperyBehaviour slipperyBehaviour = ((obj != null) ? obj.GetComponent<SlipperyBehaviour>() : null); if (!((Object)(object)slipperyBehaviour == (Object)null)) { slipperyBehaviour.PlaySillyExtras(sillyExtrasOption); } } [ServerRpc] public static void PlaySoundEffectServerRpc(NetworkObjectReference slipperyNGO) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PlaySoundEffectClientRpc(slipperyNGO, SlipperyOptions.SoundEffect.Value); } [ClientRpc] private static void PlaySoundEffectClientRpc(NetworkObjectReference slipperyNGO, SlipperyOptions.SoundEffectOption soundEffectOption) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) GameObject obj = NetworkObjectReference.op_Implicit(slipperyNGO); SlipperyBehaviour slipperyBehaviour = ((obj != null) ? obj.GetComponent<SlipperyBehaviour>() : null); if (!((Object)(object)slipperyBehaviour == (Object)null)) { slipperyBehaviour.PlaySoundEffect(soundEffectOption); } } } } namespace SlipperyShotgun.Configuration { public class SlipperyOptions : SyncedConfig2<SlipperyOptions> { public enum LogLevel { None, Info, Debug } public enum SillyExtrasOption { None, Confetti, Explosion, CarBomb } public enum SoundEffectOption { None, Bonk, Boo, Slip } private static SlipperyOptions Instance { get; set; } [field: SyncedEntryField] public static SyncedEntry<int> ShotgunDropChance { get; private set; } [field: SyncedEntryField] public static SyncedEntry<int> RifleDropChance { get; private set; } [field: SyncedEntryField] public static SyncedEntry<int> RevolverDropChance { get; private set; } [field: SyncedEntryField] public static SyncedEntry<bool> ShotgunDropPreventsFiring { get; private set; } [field: SyncedEntryField] public static SyncedEntry<bool> RifleDropPreventsFiring { get; private set; } [field: SyncedEntryField] public static SyncedEntry<bool> RevolverDropPreventsFiring { get; private set; } public static ConfigEntry<SillyExtrasOption> SillyExtras { get; private set; } public static ConfigEntry<SoundEffectOption> SoundEffect { get; private set; } public static ConfigEntry<LogLevel> LogLevelConfig { get; private set; } public static void Initialize(ConfigFile config) { if (Instance == null) { Instance = new SlipperyOptions(config); } } private SlipperyOptions(ConfigFile config) : base("com.itekso.SlipperyShotgun") { ShotgunDropChance = SyncedBindingExtensions.BindSyncedEntry<int>(config, "General", "ShotgunDropChance", 45, "Percent chance to drop the shotgun (0-100)"); RifleDropChance = SyncedBindingExtensions.BindSyncedEntry<int>(config, "General", "RifleDropChance", 25, "Percent chance to drop the Rifle (0-100)"); RevolverDropChance = SyncedBindingExtensions.BindSyncedEntry<int>(config, "General", "RevolverDropChance", 35, "Percent chance to drop the Revolver (0-100)"); ShotgunDropPreventsFiring = SyncedBindingExtensions.BindSyncedEntry<bool>(config, "General", "ShotgunDropPreventsFiring", false, "Whether dropping the shotgun should prevent it from firing"); RifleDropPreventsFiring = SyncedBindingExtensions.BindSyncedEntry<bool>(config, "General", "RifleDropPreventsFiring", false, "Whether dropping the Rifle should prevent it from firing"); RevolverDropPreventsFiring = SyncedBindingExtensions.BindSyncedEntry<bool>(config, "General", "RevolverDropPreventsFiring", false, "Whether dropping the Revolver should prevent it from firing"); SillyExtras = config.Bind<SillyExtrasOption>("General", "SillyExtras", SillyExtrasOption.None, "Enable silly extras (None, Confetti, Explosion, CarBomb)"); SoundEffect = config.Bind<SoundEffectOption>("General", "SoundEffect", SoundEffectOption.None, "Sound effect to play (None, Bonk, Boo, Slip)"); LogLevelConfig = config.Bind<LogLevel>("General", "LogLevel", LogLevel.Info, "Log level (None, Info, Debug)"); ConfigManager.Register<SlipperyOptions>((SyncedConfig2<SlipperyOptions>)(object)this); } } }