using System; using System.Collections; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ComputerysModdingUtilities; using HarmonyLib; using Microsoft.CodeAnalysis; using ModMenu.Api; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: StraftatMod(true)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("KillSoundPlugin")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("KillSoundPlugin")] [assembly: AssemblyTitle("KillSoundPlugin")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 ValorantKillSoundMod { [BepInPlugin("Killsound", "Kill Sound Plugin", "3.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class KillSoundPlugin : BaseUnityPlugin { private const string ModMenuGuid = "kestrel.straftat.modmenu"; private const string ModDescription = "Plays a custom sound upon kill"; private static AudioClip currentClip; private static string soundsFolder; private static ConfigEntry selectedSound; private const string NoneOption = "(none found)"; private void Awake() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown soundsFolder = Path.Combine(Paths.PluginPath, "KillSounds"); Directory.CreateDirectory(soundsFolder); string[] array = ScanSoundFiles(); selectedSound = ((BaseUnityPlugin)this).Config.Bind("General", "Kill Sound File", (array.Length != 0) ? array[0] : "(none found)", new ConfigDescription("Which sound plays when you get a kill. Add .mp3/.mpeg files to the KillSounds folder, then restart the game to see them here.", (AcceptableValueBase)(object)new AcceptableValueList((array.Length != 0) ? array : new string[1] { "(none found)" }), Array.Empty())); selectedSound.SettingChanged += delegate { ((MonoBehaviour)this).StartCoroutine(LoadSelectedSound()); }; Harmony.CreateAndPatchAll(typeof(KillSoundPlugin), (string)null); ((MonoBehaviour)this).StartCoroutine(LoadSelectedSound()); TrySetModMenuDescription(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Kill Sound Mod loaded. Found {array.Length} sound file(s) in {soundsFolder}."); } private void TrySetModMenuDescription() { if (Chainloader.PluginInfos.ContainsKey("kestrel.straftat.modmenu")) { SetModMenuDescription(); } } [MethodImpl(MethodImplOptions.NoInlining)] private void SetModMenuDescription() { ModMenuCustomisation.SetPluginDescription("Plays a custom sound upon kill"); } private static string[] ScanSoundFiles() { return (from f in Directory.GetFiles(soundsFolder) where f.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".mpeg", StringComparison.OrdinalIgnoreCase) select f).Select(Path.GetFileName).OrderBy((string f) => f, StringComparer.OrdinalIgnoreCase).ToArray(); } private IEnumerator LoadSelectedSound() { string fileName = selectedSound.Value; if (string.IsNullOrEmpty(fileName) || fileName == "(none found)") { currentClip = null; yield break; } string text = Path.Combine(soundsFolder, fileName); if (!File.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Selected kill sound not found on disk: " + text)); currentClip = null; yield break; } UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("file://" + text, (AudioType)13); try { yield return www.SendWebRequest(); if ((int)www.result != 1) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load kill sound '" + fileName + "': " + www.error)); currentClip = null; yield break; } currentClip = DownloadHandlerAudioClip.GetContent(www); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded kill sound: " + fileName)); } finally { ((IDisposable)www)?.Dispose(); } } [HarmonyPatch(typeof(PauseManager), "WriteLog")] [HarmonyPostfix] private static void PlaySoundOnKillLog(string __0) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(__0) || (Object)(object)ClientInstance.Instance == (Object)null) { return; } string playerNameTag = ClientInstance.Instance.PlayerNameTag; if (string.IsNullOrEmpty(playerNameTag)) { return; } int num = __0.LastIndexOf(" by "); int num2 = __0.LastIndexOf(playerNameTag); if (num != -1 && num2 > num && !((Object)(object)currentClip == (Object)null)) { GameObject val = new GameObject("ForceKillSound"); Camera main = Camera.main; if ((Object)(object)main != (Object)null) { val.transform.SetParent(((Component)main).transform); val.transform.localPosition = Vector3.zero; } AudioSource obj = val.AddComponent(); obj.clip = currentClip; obj.spatialBlend = 0f; obj.volume = 1f; obj.bypassEffects = true; obj.bypassListenerEffects = true; obj.bypassReverbZones = true; obj.ignoreListenerPause = true; obj.Play(); Object.Destroy((Object)(object)val, currentClip.length + 0.35f); } } } }