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 WrongLever v1.0.0
WrongLever.dll
Decompiled a day agousing System; 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 System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using WrongLever.Services; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("Vippy")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("WrongLever")] [assembly: AssemblyTitle("WrongLever")] [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.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] [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] [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 WrongLever { internal static class BuildInfo { public const string Version = "1.0.0"; } internal static class LeverConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<int> Volume; public static ConfigEntry<float> WrongLeverDelay; public static ConfigEntry<int> WrongLeverChance; public static ConfigEntry<bool> HearItAnywhere; public static void Init(ConfigFile config) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown Enabled = config.Bind<bool>("Lever", "Enabled", true, "Turn the whole bit off without uninstalling."); Volume = config.Bind<int>("Lever", "Volume", 80, new ConfigDescription("How loud the clips are. The game's sound volume applies on top.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); WrongLeverDelay = config.Bind<float>("Lever", "Wrong lever delay", 0.6f, new ConfigDescription("Seconds between the lever click and the wrong lever line.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); WrongLeverChance = config.Bind<int>("Lever", "Wrong lever chance", 100, new ConfigDescription("Percent chance Kronk pulls the wrong lever. 100 is every time.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); HearItAnywhere = config.Bind<bool>("Lever", "Hear it anywhere", false, "Off plays the clips from the extraction point, so they fade with distance like the game's own sounds. On plays them flat in your ears wherever you are in the level."); } } [BepInPlugin("Vippy.WrongLever", "WrongLever", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class WrongLeverPlugin : BaseUnityPlugin { internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; LeverConfig.Init(((BaseUnityPlugin)this).Config); Clips.Load(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location)); new Harmony("Vippy.WrongLever").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("WrongLever v{0} loaded, clips: {1}/3", "1.0.0", Clips.Loaded)); } } } namespace WrongLever.Services { internal static class Clips { public static AudioClip? Kronk { get; private set; } public static AudioClip? Click { get; private set; } public static AudioClip? Wrong { get; private set; } public static int Loaded { get; private set; } public static void Load(string pluginDir) { Kronk = Read(pluginDir, "pull_the_lever_kronk.wav"); Click = Read(pluginDir, "lever_click.wav"); Wrong = Read(pluginDir, "wrong_lever.wav"); } private static AudioClip? Read(string pluginDir, string fileName) { string[] files = Directory.GetFiles(pluginDir, fileName, SearchOption.AllDirectories); if (files.Length == 0) { WrongLeverPlugin.Log.LogWarning((object)("[Clips] " + fileName + " is missing, that part of the bit stays silent")); return null; } try { WavFile.Pcm pcm = WavFile.Parse(File.ReadAllBytes(files[0])); AudioClip obj = AudioClip.Create(Path.GetFileNameWithoutExtension(fileName), pcm.Frames, pcm.Channels, pcm.Rate, false); obj.SetData(pcm.Samples, 0); Loaded++; return obj; } catch (FormatException ex) { WrongLeverPlugin.Log.LogWarning((object)("[Clips] " + fileName + ": " + ex.Message)); return null; } } } internal sealed class LeverBit : MonoBehaviour { private const float GiveUpAfter = 90f; private ExtractionPoint point; private AudioSource voice; private AudioSource lever; private bool armed; private float armedAt; private bool slammed; private float wrongAt = -1f; private void Awake() { point = ((Component)this).GetComponent<ExtractionPoint>(); voice = NewSource(); lever = NewSource(); } private AudioSource NewSource() { AudioSource val = ((Component)this).gameObject.AddComponent<AudioSource>(); val.playOnAwake = false; val.rolloffMode = (AudioRolloffMode)0; val.minDistance = 3f; val.maxDistance = 40f; val.dopplerLevel = 0f; if (Object.op_Implicit((Object)(object)AudioManager.instance)) { val.outputAudioMixerGroup = AudioManager.instance.SoundMasterGroup; } return val; } internal void Confirmed() { if (LeverConfig.Enabled.Value && !((Object)(object)Clips.Kronk == (Object)null) && (!voice.isPlaying || !((Object)(object)voice.clip == (Object)(object)Clips.Kronk))) { Play(voice, Clips.Kronk); armed = true; armedAt = Time.time; slammed = false; wrongAt = -1f; } } private void Update() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 if (!armed) { return; } State currentState = point.currentState; if ((int)currentState == 1 || (int)currentState == 5 || Time.time - armedAt > 90f) { armed = false; wrongAt = -1f; return; } if (!slammed && (int)currentState == 6 && point.tubeHit) { slammed = true; Play(lever, Clips.Click); if (Random.Range(0, 100) < LeverConfig.WrongLeverChance.Value) { wrongAt = Time.time + LeverConfig.WrongLeverDelay.Value; } else { armed = false; } } if (wrongAt >= 0f && Time.time >= wrongAt) { wrongAt = -1f; armed = false; Play(voice, Clips.Wrong); } } private static void Play(AudioSource source, AudioClip? clip) { if (!((Object)(object)clip == (Object)null)) { source.spatialBlend = (LeverConfig.HearItAnywhere.Value ? 0f : 1f); source.volume = (float)LeverConfig.Volume.Value / 100f; source.clip = clip; source.Play(); } } } internal static class WavFile { public readonly struct Pcm { public readonly float[] Samples; public readonly int Channels; public readonly int Rate; public int Frames => Samples.Length / Channels; public Pcm(float[] samples, int channels, int rate) { Samples = samples; Channels = channels; Rate = rate; } } public static Pcm Parse(byte[] bytes) { if (bytes.Length < 12 || Tag(bytes, 0) != "RIFF" || Tag(bytes, 8) != "WAVE") { throw new FormatException("not a RIFF wave file"); } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 12; while (num5 + 8 <= bytes.Length) { string text = Tag(bytes, num5); int num6 = BitConverter.ToInt32(bytes, num5 + 4); int num7 = num5 + 8; if (text == "fmt ") { num4 = BitConverter.ToInt16(bytes, num7); num = BitConverter.ToInt16(bytes, num7 + 2); num2 = BitConverter.ToInt32(bytes, num7 + 4); num3 = BitConverter.ToInt16(bytes, num7 + 14); } else if (text == "data") { if (num4 != 1 || num3 != 16) { throw new FormatException($"unsupported wave format {num4} at {num3} bits, need 16-bit PCM"); } if (num < 1 || num2 < 1) { throw new FormatException("data chunk before fmt chunk"); } int num8 = Math.Min(num6, bytes.Length - num7) / 2; float[] array = new float[num8]; for (int i = 0; i < num8; i++) { array[i] = (float)BitConverter.ToInt16(bytes, num7 + i * 2) / 32768f; } return new Pcm(array, num, num2); } num5 = num7 + num6 + (num6 & 1); } throw new FormatException("no data chunk"); } private static string Tag(byte[] bytes, int at) { return Encoding.ASCII.GetString(bytes, at, 4); } } } namespace WrongLever.Patches { [HarmonyPatch] internal static class ConfirmButtonPatch { private const string ButtonType = "com.github.zehsteam.ExtractionPointConfirmButton.MonoBehaviours.ConfirmButton"; private static FieldInfo? pointField; private static bool Prepare() { return AccessTools.TypeByName("com.github.zehsteam.ExtractionPointConfirmButton.MonoBehaviours.ConfirmButton") != null; } private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("com.github.zehsteam.ExtractionPointConfirmButton.MonoBehaviours.ConfirmButton"); pointField = AccessTools.Field(type, "_extractionPoint"); return AccessTools.Method(type, "OnClickRPC", (Type[])null, (Type[])null); } private static void Postfix(object __instance) { object? obj = pointField?.GetValue(__instance); ExtractionPoint val = (ExtractionPoint)((obj is ExtractionPoint) ? obj : null); if (val != null) { LeverBit component = ((Component)val).GetComponent<LeverBit>(); if (Object.op_Implicit((Object)(object)component)) { component.Confirmed(); } } } } [HarmonyPatch(typeof(ExtractionPoint), "Start")] internal static class ExtractionPointPatch { private static void Postfix(ExtractionPoint __instance) { if (!__instance.isShop) { ((Component)__instance).gameObject.AddComponent<LeverBit>(); } } } }