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 DeathTunes v1.0.0
DeathTunes/DeathTunes.dll
Decompiled 4 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalNetworkAPI; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("DeathTunes")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DeathTunes")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3bc8e91e-4245-4e07-9d3d-f9b30954ac9d")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] internal class EmptyMonoBehaviour : MonoBehaviour { } namespace DeathTunes; public static class DeathCustomizationManager { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__10_2; internal void <OpenMenu>b__10_2() { PlaySelectedSound(); } } public static Dictionary<string, AudioClip> Sounds = new Dictionary<string, AudioClip>(); public static List<string> SoundIDs = new List<string>(); public static string SelectedSound = ""; private static int soundIndex = 0; public static string PendingSoundSelection = null; private static GameObject menu; public static int CurrentSoundIndex => soundIndex; private static void SendPlayerSound(PlayerControllerB player) { ulong playerSteamId = player.playerSteamId; DeathTunesPlugin.Log.LogInfo((object)("Sending sound '" + SelectedSound + "' for SteamID " + playerSteamId)); DeathSoundNetworking.SendSelection(playerSteamId, SelectedSound); } public static void LoadSounds() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); List<string> list = new List<string>(); DeathTunesPlugin.Log.LogInfo((object)"Searching for death sounds..."); string path = Path.Combine(directoryName, "Sounds"); if (Directory.Exists(path)) { list.AddRange(Directory.GetFiles(path, "*.wav", SearchOption.AllDirectories)); } list.AddRange(Directory.GetFiles(directoryName, "*.wav", SearchOption.TopDirectoryOnly)); list = list.Distinct().ToList(); foreach (string item in list) { AudioClip val = DeathTunesPlugin.Instance.LoadWav(item); if ((Object)(object)val != (Object)null) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item); if (!Sounds.ContainsKey(fileNameWithoutExtension)) { Sounds.Add(fileNameWithoutExtension, val); SoundIDs.Add(fileNameWithoutExtension); DeathTunesPlugin.Log.LogInfo((object)("Loaded death sound: " + fileNameWithoutExtension)); } } } if (SoundIDs.Count > 0) { string value = DeathTunesPlugin.SavedDeathSound.Value; if (!string.IsNullOrEmpty(value) && Sounds.ContainsKey(value)) { SelectedSound = value; } else { SelectedSound = SoundIDs[0]; } } DeathTunesPlugin.Log.LogInfo((object)("Total death sounds loaded: " + Sounds.Count)); } public static void OpenMenu() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown if ((Object)(object)menu != (Object)null) { menu.SetActive(true); return; } menu = new GameObject("DeathTunesMenu"); Canvas val = menu.AddComponent<Canvas>(); val.renderMode = (RenderMode)0; CanvasScaler val2 = menu.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; menu.AddComponent<GraphicRaycaster>(); GameObject val3 = CreatePanel(menu.transform, new Vector2(500f, 300f), new Vector2(0f, 0f)); Image component = val3.GetComponent<Image>(); ((Graphic)component).color = new Color(0f, 0f, 0f, 0.85f); GameObject val4 = CreateText(val3.transform, "Choose Death Sound", 32, new Vector2(0f, 100f)); GameObject val5 = CreateText(val3.transform, "", 24, new Vector2(0f, 20f)); TextMeshProUGUI soundLabel = val5.GetComponent<TextMeshProUGUI>(); UpdateSoundText(soundLabel); GameObject val6 = CreateButton(val3.transform, "<", new Vector2(-150f, -50f)); ((UnityEvent)val6.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { PreviousSound(); UpdateSoundText(soundLabel); }); GameObject val7 = CreateButton(val3.transform, ">", new Vector2(150f, -50f)); ((UnityEvent)val7.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { NextSound(); UpdateSoundText(soundLabel); }); GameObject val8 = CreateButton(val3.transform, "Preview", new Vector2(0f, -100f)); ButtonClickedEvent onClick = val8.GetComponent<Button>().onClick; object obj = <>c.<>9__10_2; if (obj == null) { UnityAction val9 = delegate { PlaySelectedSound(); }; <>c.<>9__10_2 = val9; obj = (object)val9; } ((UnityEvent)onClick).AddListener((UnityAction)obj); GameObject val10 = CreateButton(val3.transform, "Save & Close", new Vector2(0f, -150f)); ((UnityEvent)val10.GetComponent<Button>().onClick).AddListener(new UnityAction(SaveAndClose)); } private static void SaveAndClose() { DeathTunesPlugin.Log.LogInfo((object)"===== SAVING DEATH SOUND ====="); DeathTunesPlugin.Log.LogInfo((object)("Selected sound: " + SelectedSound)); DeathTunesPlugin.SavedDeathSound.Value = SelectedSound; if ((Object)(object)GameNetworkManager.Instance == (Object)null) { DeathTunesPlugin.Log.LogWarning((object)"GameNetworkManager not initialized yet."); PendingSoundSelection = SelectedSound; menu.SetActive(false); return; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null) { DeathTunesPlugin.Log.LogWarning((object)"Local player controller not available. Saving locally for later."); PendingSoundSelection = SelectedSound; menu.SetActive(false); } else { SendPlayerSound(localPlayerController); menu.SetActive(false); } } public static void CloseMenu() { if ((Object)(object)menu != (Object)null) { menu.SetActive(false); } } private static void UpdateSoundText(TextMeshProUGUI text) { if (SoundIDs.Count == 0) { ((TMP_Text)text).text = "No sounds found"; } else { ((TMP_Text)text).text = SoundIDs[soundIndex]; } } public static void NextSound() { soundIndex++; if (soundIndex >= SoundIDs.Count) { soundIndex = 0; } SelectedSound = SoundIDs[soundIndex]; DeathTunesPlugin.Log.LogInfo((object)("Changed selected sound to: " + SelectedSound)); } public static void PreviousSound() { soundIndex--; if (soundIndex < 0) { soundIndex = SoundIDs.Count - 1; } SelectedSound = SoundIDs[soundIndex]; DeathTunesPlugin.Log.LogInfo((object)("Changed selected sound to: " + SelectedSound)); } private static void PlaySelectedSound() { if (Sounds.ContainsKey(SelectedSound)) { DeathTunesPlugin.PlayClip(Sounds[SelectedSound]); } } private static GameObject CreatePanel(Transform parent, Vector2 size, Vector2 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Panel"); val.transform.SetParent(parent); RectTransform val2 = val.AddComponent<RectTransform>(); val2.sizeDelta = size; val2.anchoredPosition = position; val.AddComponent<Image>(); return val; } private static GameObject CreateText(Transform parent, string value, int size, Vector2 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Text"); val.transform.SetParent(parent); RectTransform val2 = val.AddComponent<RectTransform>(); val2.sizeDelta = new Vector2(400f, 50f); val2.anchoredPosition = position; TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val3).text = value; ((TMP_Text)val3).fontSize = size; ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; return val; } private static GameObject CreateButton(Transform parent, string value, Vector2 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(value); val.transform.SetParent(parent); RectTransform val2 = val.AddComponent<RectTransform>(); val2.sizeDelta = new Vector2(120f, 40f); val2.anchoredPosition = position; Image val3 = val.AddComponent<Image>(); ((Graphic)val3).color = Color.gray; Button val4 = val.AddComponent<Button>(); GameObject val5 = CreateText(val.transform, value, 18, Vector2.zero); return val; } } public static class DeathCustomizationMenuUtils { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__0_0; public static Func<Button, GameObject> <>9__0_1; public static Func<GameObject, float> <>9__0_3; public static Func<float, float, float> <>9__0_4; internal void <InjectMenu>b__0_0() { DeathCustomizationManager.OpenMenu(); } internal GameObject <InjectMenu>b__0_1(Button b) { return ((Component)b).gameObject; } internal float <InjectMenu>b__0_3(GameObject b) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return b.GetComponent<RectTransform>().anchoredPosition.y; } internal float <InjectMenu>b__0_4(float a, float b) { return Mathf.Abs(b - a); } } public static void InjectMenu(Transform mainButtonsTransform, GameObject quitButton) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) DeathTunesPlugin.Log.LogInfo((object)"Injecting DeathTunes button..."); DeathCustomizationManager.OpenMenu(); DeathCustomizationManager.CloseMenu(); GameObject deathButton = Object.Instantiate<GameObject>(quitButton, mainButtonsTransform); ((Object)deathButton).name = "DeathTunesButton"; Button component = deathButton.GetComponent<Button>(); ((UnityEventBase)component.onClick).RemoveAllListeners(); component.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = component.onClick; object obj = <>c.<>9__0_0; if (obj == null) { UnityAction val = delegate { DeathCustomizationManager.OpenMenu(); }; <>c.<>9__0_0 = val; obj = (object)val; } ((UnityEvent)onClick).AddListener((UnityAction)obj); TextMeshProUGUI componentInChildren = deathButton.GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)componentInChildren).text = "> Death Sounds"; } List<GameObject> source = (from b in ((Component)mainButtonsTransform).GetComponentsInChildren<Button>() select ((Component)b).gameObject).ToList(); List<float> list = (from b in source where (Object)(object)b != (Object)(object)deathButton select b.GetComponent<RectTransform>().anchoredPosition.y).ToList(); float num = 55f; if (list.Count >= 2) { num = list.Zip(list.Skip(1), (float a, float b) => Mathf.Abs(b - a)).Min(); } foreach (GameObject item in source.Where((GameObject g) => (Object)(object)g != (Object)(object)quitButton)) { RectTransform component2 = item.GetComponent<RectTransform>(); component2.anchoredPosition += new Vector2(0f, num); } RectTransform component3 = quitButton.GetComponent<RectTransform>(); RectTransform component4 = deathButton.GetComponent<RectTransform>(); component4.anchoredPosition = component3.anchoredPosition + new Vector2(0f, num); DeathTunesPlugin.Log.LogInfo((object)"DeathTunes button positioned successfully."); } } [HarmonyPatch(typeof(PlayerControllerB))] public class DeathPatch { [HarmonyPatch("Update")] [HarmonyPostfix] private static void CheckDeath(PlayerControllerB __instance) { if (!((Object)(object)__instance == (Object)null)) { ulong playerSteamId = __instance.playerSteamId; bool isPlayerDead = __instance.isPlayerDead; bool value = false; DeathTunesPlugin.LastDeathState.TryGetValue(playerSteamId, out value); if (isPlayerDead && !value) { DeathTunesPlugin.Log.LogInfo((object)("DEATH DETECTED: Player " + playerSteamId)); PlayerDeathSoundManager.PlayPlayerDeathSound(__instance); } DeathTunesPlugin.LastDeathState[playerSteamId] = isPlayerDead; } } } public class SoundSelectionData { public ulong SteamID; public string SoundName; } public static class DeathSoundNetworking { public static readonly Dictionary<ulong, string> PlayerSounds = new Dictionary<ulong, string>(); public static LNetworkMessage<SoundSelectionData> SoundMessage; public static LNetworkMessage<string> RequestMessage; public static void Initialize() { SoundMessage = LNetworkMessage<SoundSelectionData>.Create("DeathSoundSelection", (Action<SoundSelectionData, ulong>)OnServerReceived, (Action<SoundSelectionData>)OnClientReceived, (Action<SoundSelectionData, ulong>)null); RequestMessage = LNetworkMessage<string>.Create("DeathSoundRequest", (Action<string, ulong>)OnRequestReceived, (Action<string>)null, (Action<string, ulong>)null); DeathTunesPlugin.Log.LogInfo((object)"Death sound networking initialized."); } public static void SendSelection(ulong steamID, string sound) { SoundSelectionData soundSelectionData = new SoundSelectionData { SteamID = steamID, SoundName = sound }; PlayerSounds[steamID] = sound; DeathTunesPlugin.Log.LogInfo((object)$"Sending sound selection: {steamID} -> {sound}"); SoundMessage.SendServer(soundSelectionData); } private static void OnServerReceived(SoundSelectionData data, ulong sender) { PlayerSounds[data.SteamID] = data.SoundName; DeathTunesPlugin.Log.LogInfo((object)$"Host stored sound: {data.SteamID} -> {data.SoundName}"); SoundMessage.SendClients(data); } private static void OnClientReceived(SoundSelectionData data) { PlayerSounds[data.SteamID] = data.SoundName; DeathTunesPlugin.Log.LogInfo((object)$"Client stored sound: {data.SteamID} -> {data.SoundName}"); } public static void RequestAllSounds() { DeathTunesPlugin.Log.LogInfo((object)"Requesting all death sounds..."); RequestMessage.SendServer(""); } private static void OnRequestReceived(string unused, ulong sender) { DeathTunesPlugin.Log.LogInfo((object)$"Sending all sounds to client {sender}"); Dictionary<ulong, string> dictionary = new Dictionary<ulong, string>(PlayerSounds); foreach (KeyValuePair<ulong, string> item in dictionary) { SoundSelectionData soundSelectionData = new SoundSelectionData { SteamID = item.Key, SoundName = item.Value }; SoundMessage.SendClient(soundSelectionData, sender); } DeathTunesPlugin.Log.LogInfo((object)$"Finished sending {dictionary.Count} sounds to client {sender}"); } public static void PrintDatabase() { DeathTunesPlugin.Log.LogInfo((object)"===== DEATH SOUND DATABASE ====="); foreach (KeyValuePair<ulong, string> playerSound in PlayerSounds) { DeathTunesPlugin.Log.LogInfo((object)$"{playerSound.Key} -> {playerSound.Value}"); } } } [BepInPlugin("ryang.deathtunes", "DeathTunes", "0.1.0")] public class DeathTunesPlugin : BaseUnityPlugin { public static DeathTunesPlugin Instance; public static ManualLogSource Log; public static AudioSource AudioSource; public static ConfigEntry<string> SavedDeathSound; public static Dictionary<ulong, bool> LastDeathState = new Dictionary<ulong, bool>(); private void Awake() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; SavedDeathSound = ((BaseUnityPlugin)this).Config.Bind<string>("DeathTunes", "SelectedDeathSound", "", "The selected death sound for this player."); Log.LogInfo((object)"DeathTunes starting..."); Log.LogInfo((object)("DLL location: " + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))); DeathCustomizationManager.LoadSounds(); DeathSoundNetworking.Initialize(); Harmony val = new Harmony("ryang.deathtunes"); val.PatchAll(); ((MonoBehaviour)this).StartCoroutine(CreateAudioSource()); Log.LogInfo((object)"DeathTunes loaded!"); } private void Update() { if (DeathCustomizationManager.PendingSoundSelection == null) { return; } Log.LogInfo((object)("DeathTunes pending sound: " + DeathCustomizationManager.PendingSoundSelection)); if ((Object)(object)StartOfRound.Instance == (Object)null) { Log.LogInfo((object)"Waiting for StartOfRound..."); return; } Log.LogInfo((object)"StartOfRound exists"); PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null) { Log.LogInfo((object)"Waiting for local player..."); return; } Log.LogInfo((object)"Local player found!"); ulong playerSteamId = localPlayerController.playerSteamId; DeathSoundNetworking.SendSelection(playerSteamId, DeathCustomizationManager.PendingSoundSelection); Log.LogInfo((object)("Sent sound " + DeathCustomizationManager.PendingSoundSelection + " for SteamID " + playerSteamId)); DeathCustomizationManager.PendingSoundSelection = null; } private IEnumerator CreateAudioSource() { yield return (object)new WaitForSeconds(3f); CreateAudioObject(); Log.LogInfo((object)"DeathTunes AudioSource created"); } public static void CreateAudioObject() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)AudioSource != (Object)null)) { GameObject val = new GameObject("DeathTunesAudio"); Object.DontDestroyOnLoad((Object)(object)val); AudioSource = val.AddComponent<AudioSource>(); AudioSource.playOnAwake = false; AudioSource.loop = false; AudioSource.spatialBlend = 0f; AudioSource.volume = 1f; AudioSource.ignoreListenerVolume = true; AudioSource.priority = 0; } } public static AudioClip LoadWavPublic(string path) { return Instance.LoadWav(path); } public AudioClip LoadWav(string path) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 try { UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip("file:///" + path, (AudioType)20); UnityWebRequestAsyncOperation val = audioClip.SendWebRequest(); while (!((AsyncOperation)val).isDone) { Thread.Sleep(10); } if ((int)audioClip.result != 1) { Log.LogError((object)audioClip.error); return null; } AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip); ((Object)content).name = Path.GetFileNameWithoutExtension(path); return content; } catch (Exception ex) { Log.LogError((object)ex.Message); return null; } } public static void PlayClip(AudioClip clip) { if ((Object)(object)clip == (Object)null) { Log.LogError((object)"Tried to play NULL clip"); return; } if ((Object)(object)AudioSource == (Object)null) { CreateAudioObject(); } AudioSource.Stop(); AudioSource.clip = clip; AudioSource.volume = 1f; AudioSource.Play(); Log.LogInfo((object)("Playing death sound: " + ((Object)clip).name)); } } [HarmonyPatch(typeof(MenuManager))] public class MainMenuPatch { [HarmonyPatch("Start")] [HarmonyPostfix] public static void Start(MenuManager __instance) { if (!__instance.isInitScene) { DeathTunesPlugin.Log.LogInfo((object)"DeathTunes injecting menu..."); ((MonoBehaviour)__instance).StartCoroutine(DelayedInjection()); } } private static IEnumerator DelayedInjection() { yield return (object)new WaitForSeconds(1f); InjectMenu(); } private static void InjectMenu() { GameObject val = GameObject.Find("MenuContainer"); if ((Object)(object)val == (Object)null) { return; } Transform val2 = val.transform.Find("MainButtons"); if (!((Object)(object)val2 == (Object)null)) { Transform val3 = val2.Find("QuitButton"); if ((Object)(object)val3 == (Object)null) { DeathTunesPlugin.Log.LogError((object)"QuitButton missing!"); } else { DeathCustomizationMenuUtils.InjectMenu(val2, ((Component)val3).gameObject); } } } } [HarmonyPatch(typeof(StartOfRound))] public class PlayerConnectionPatch { private static bool hasSynced; [HarmonyPatch("Start")] [HarmonyPostfix] public static void OnGameStart(StartOfRound __instance) { if (!hasSynced) { hasSynced = true; DeathTunesPlugin.Log.LogInfo((object)"DeathTunes player connection sync started."); ((MonoBehaviour)__instance).StartCoroutine(DelayedSync()); } } private static IEnumerator DelayedSync() { yield return (object)new WaitForSeconds(3f); PlayerControllerB player = StartOfRound.Instance.localPlayerController; if ((Object)(object)player == (Object)null) { DeathTunesPlugin.Log.LogWarning((object)"Cannot sync death sound. Local player missing."); yield break; } ulong steamID = player.playerSteamId; DeathTunesPlugin.Log.LogInfo((object)$"Local player found. SteamID: {steamID}"); if (!string.IsNullOrEmpty(DeathTunesPlugin.SavedDeathSound.Value)) { DeathSoundNetworking.SendSelection(steamID, DeathTunesPlugin.SavedDeathSound.Value); DeathTunesPlugin.Log.LogInfo((object)"Sent saved death sound."); } else { DeathTunesPlugin.Log.LogInfo((object)"No saved death sound found."); } DeathSoundNetworking.RequestAllSounds(); DeathTunesPlugin.Log.LogInfo((object)"Requested all player death sounds."); } [HarmonyPatch("OnDestroy")] [HarmonyPostfix] public static void OnDestroy() { hasSynced = false; DeathTunesPlugin.Log.LogInfo((object)"DeathTunes player sync reset."); } } public static class PlayerDeathSoundManager { public static void PlayPlayerDeathSound(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return; } ulong playerSteamId = player.playerSteamId; DeathTunesPlugin.Log.LogInfo((object)$"Looking up death sound for SteamID: {playerSteamId}"); AudioClip val = null; if (DeathSoundNetworking.PlayerSounds.TryGetValue(playerSteamId, out var value)) { DeathTunesPlugin.Log.LogInfo((object)$"Found sound entry: {playerSteamId} -> {value}"); if (DeathCustomizationManager.Sounds.ContainsKey(value)) { val = DeathCustomizationManager.Sounds[value]; } else { DeathTunesPlugin.Log.LogWarning((object)("Sound file does not exist: " + value)); } } else { DeathTunesPlugin.Log.LogWarning((object)$"No sound registered for SteamID: {playerSteamId}"); } if ((Object)(object)val == (Object)null && (Object)(object)player == (Object)(object)StartOfRound.Instance.localPlayerController) { string value2 = DeathTunesPlugin.SavedDeathSound.Value; if (!string.IsNullOrEmpty(value2) && DeathCustomizationManager.Sounds.ContainsKey(value2)) { DeathTunesPlugin.Log.LogInfo((object)("Using local saved fallback sound: " + value2)); val = DeathCustomizationManager.Sounds[value2]; } } if ((Object)(object)val == (Object)null) { DeathTunesPlugin.Log.LogWarning((object)$"Could not find death sound for {playerSteamId}"); return; } DeathTunesPlugin.Log.LogInfo((object)$"Playing death sound for {playerSteamId}: {((Object)val).name}"); DeathTunesPlugin.PlayClip(val); } }