using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using GameNetcodeStuff; using LethalCompanyInputUtils.Api; using LethalNetworkAPI; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("PeashooterSoundboardremake")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PeashooterSoundboardremake")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9d878c88-8e69-45ad-80f3-897a0d8733f4")] [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")] namespace PeashooterSoundboard; [BepInPlugin("chee.peashooter.soundboard", "PeashooterSoundboard", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SoundboardMod : BaseUnityPlugin { public struct SoundEventData { public string group; public int index; public Vector3 position; public bool deadAudio; } private Dictionary> groups; private AudioSource audioSource; private static LNetworkMessage soundMessage; internal static SoundboardKeybinds binds; private float lastPlayTime; private float currentCooldown = 1.6f; private const float baseCooldown = 1.6f; private const float maxCooldown = 4f; private const float cooldownRecoveryRate = 0.5f; private void Awake() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[PeashooterSoundboard] Initializing"); binds = new SoundboardKeybinds(); ((LcInputActions)binds).Enable(); audioSource = ((Component)this).gameObject.AddComponent(); audioSource.spatialBlend = 1f; audioSource.minDistance = 2f; audioSource.maxDistance = 25f; LoadAllGroups(); RegisterNetworkMessage(); } private void RegisterNetworkMessage() { soundMessage = LNetworkMessage.Connect("CheePeashooterSoundboard", (Action)null, (Action)null, (Action)OnClientReceivedFromClient); } private void OnClientReceivedFromClient(SoundEventData data, ulong senderId) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) bool isPlayerDead = StartOfRound.Instance.localPlayerController.isPlayerDead; if ((data.deadAudio && !isPlayerDead) || !groups.ContainsKey(data.group)) { return; } List list = groups[data.group]; if (data.index >= 0 && data.index < list.Count) { AudioClip val = list[data.index]; audioSource.spatialBlend = (data.deadAudio ? 0f : 1f); if (!data.deadAudio) { ((Component)audioSource).transform.position = data.position; } audioSource.PlayOneShot(val); } } private void Update() { RecoverCooldown(); if (groups != null && groups.Count != 0) { if (binds.psIdle.WasPressedThisFrame()) { PlayAndSync("ps_idle"); } if (binds.psExcited.WasPressedThisFrame()) { PlayAndSync("ps_excited"); } if (binds.psTaunt.WasPressedThisFrame()) { PlayAndSync("ps_taunt"); } if (binds.pcExcited.WasPressedThisFrame()) { PlayAndSync("pc_excited"); } if (binds.pcDeath.WasPressedThisFrame()) { PlayAndSync("pc_death"); } if (binds.psYes.WasPressedThisFrame()) { PlayAndSync("ps_yes"); } if (binds.psNo.WasPressedThisFrame()) { PlayAndSync("ps_no"); } if (binds.psSilly.WasPressedThisFrame()) { PlayAndSync("ps_silly"); } if (((ButtonControl)Keyboard.current.rightCtrlKey).isPressed && binds.scream.WasPressedThisFrame()) { PlayAndSync("scream"); } } } private void RecoverCooldown() { if (currentCooldown > 1.6f) { currentCooldown -= Time.deltaTime * 0.5f; if (currentCooldown < 1.6f) { currentCooldown = 1.6f; } } } private void LoadAllGroups() { groups = new Dictionary>(); string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); string audioRoot = Path.Combine(directoryName, "audio"); LoadGroup("ps_idle", audioRoot); LoadGroup("ps_excited", audioRoot); LoadGroup("ps_taunt", audioRoot); LoadGroup("pc_excited", audioRoot); LoadGroup("pc_death", audioRoot); LoadGroup("scream", audioRoot); BuildCustomGroups(directoryName); } private void BuildCustomGroups(string pluginFolder) { groups["ps_yes"] = new List(); AddClip(groups["ps_yes"], pluginFolder, "ps_taunt", "ps_taunt_25"); AddClip(groups["ps_yes"], pluginFolder, "ps_taunt", "ps_taunt_42"); AddClip(groups["ps_yes"], pluginFolder, "ps_taunt", "ps_taunt_37"); groups["ps_no"] = new List(); AddClip(groups["ps_no"], pluginFolder, "ps_taunt", "ps_taunt_23"); AddClip(groups["ps_no"], pluginFolder, "ps_taunt", "ps_taunt_24"); groups["ps_silly"] = new List(); AddClip(groups["ps_silly"], pluginFolder, "ps_taunt", "ps_taunt_11"); AddClip(groups["ps_silly"], pluginFolder, "ps_taunt", "ps_taunt_15"); AddClip(groups["ps_silly"], pluginFolder, "ps_taunt", "ps_taunt_16"); } private void AddClip(List list, string pluginFolder, string folder, string filename) { string path = Path.Combine(pluginFolder, "audio", folder, filename + ".wav"); if (File.Exists(path)) { AudioClip val = LoadWav(path); if ((Object)(object)val != (Object)null) { list.Add(val); } } } private void LoadGroup(string groupName, string audioRoot) { string text = Path.Combine(audioRoot, groupName); if (!Directory.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[PeashooterSoundboard] Missing folder: " + text)); return; } string[] files = Directory.GetFiles(text, "*.wav"); List list = new List(); string[] array = files; foreach (string path in array) { AudioClip val = LoadWav(path); if ((Object)(object)val != (Object)null) { list.Add(val); } } if (list.Count > 0) { groups[groupName] = list; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Loaded {list.Count} clips for '{groupName}'"); } } private AudioClip LoadWav(string path) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown WWW val = new WWW("file://" + path.Replace("\\", "/")); try { while (!val.isDone) { } if (!string.IsNullOrEmpty(val.error)) { ((BaseUnityPlugin)this).Logger.LogError((object)("Error loading '" + path + "': " + val.error)); return null; } AudioClip audioClip = val.GetAudioClip(false, false, (AudioType)20); if ((Object)(object)audioClip == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to decode WAV: " + path)); return null; } ((Object)audioClip).name = Path.GetFileName(path); return audioClip; } finally { ((IDisposable)val)?.Dispose(); } } private void PlayAndSync(string group) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null) { return; } if (Time.time - lastPlayTime < currentCooldown) { currentCooldown += 0.25f; if (currentCooldown > 4f) { currentCooldown = 4f; } return; } lastPlayTime = Time.time; if (!groups.ContainsKey(group)) { return; } List list = groups[group]; if (list.Count == 0) { return; } int index = Random.Range(0, list.Count); AudioClip val = list[index]; bool isPlayerDead = localPlayerController.isPlayerDead; audioSource.spatialBlend = (isPlayerDead ? 0f : 1f); if (!isPlayerDead) { ((Component)audioSource).transform.position = ((Component)localPlayerController).transform.position; } float num = ((group == "ps_excited") ? 0.8f : 1f); audioSource.PlayOneShot(val, num); SoundEventData soundEventData = default(SoundEventData); soundEventData.group = group; soundEventData.index = index; soundEventData.position = ((Component)localPlayerController).transform.position; soundEventData.deadAudio = isPlayerDead; SoundEventData soundEventData2 = soundEventData; if (!isPlayerDead) { soundMessage.SendOtherClients(soundEventData2); return; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val2 in allPlayerScripts) { if ((Object)(object)val2 != (Object)null && val2.isPlayerDead && val2.actualClientId != localPlayerController.actualClientId) { soundMessage.SendClient(soundEventData2, val2.actualClientId); } } } } public class SoundboardKeybinds : LcInputActions { [InputAction("/numpad7", Name = "PS Idle")] public InputAction psIdle { get; set; } [InputAction("/numpad8", Name = "PS Excited")] public InputAction psExcited { get; set; } [InputAction("/numpad9", Name = "PS Taunt")] public InputAction psTaunt { get; set; } [InputAction("/numpad4", Name = "PC Excited")] public InputAction pcExcited { get; set; } [InputAction("/numpad5", Name = "PC Death")] public InputAction pcDeath { get; set; } [InputAction("/numpad6", Name = "PS Yes")] public InputAction psYes { get; set; } [InputAction("/numpad3", Name = "PS No")] public InputAction psNo { get; set; } [InputAction("/enter", Name = "PS Silly")] public InputAction psSilly { get; set; } [InputAction("/numpad0", Name = "Scream")] public InputAction scream { get; set; } }