using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Networking; [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("FettyRockBugle")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("FettyRockBugle")] [assembly: AssemblyTitle("FettyRockBugle")] [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 FettyRockBugle { internal static class Bugle { public const string FolderName = "bugle"; private static readonly List clips = new List(); private static bool loggedWobble; private static bool loggedDoppler; private static bool loggedPitch; public static int Count => clips.Count; public static void Load(string modFolder) { clips.Clear(); List list = new List(Files(modFolder)); string text = Path.Combine(modFolder, "bugle"); if (Directory.Exists(text)) { list.AddRange(Files(text)); } if (list.Count == 0) { Plugin.Log.LogWarning((object)"[Bugle] no audio found; bugle untouched."); return; } foreach (string item in list) { AudioClip val = Load(item, Path.GetFileNameWithoutExtension(item)); if (!((Object)(object)val == (Object)null)) { clips.Add(val); Plugin.Log.LogInfo((object)("[Bugle] loaded " + Path.GetFileName(item))); } } Plugin.Log.LogInfo((object)$"[Bugle] {clips.Count} clip(s)."); } private static string[] Files(string dir) { string[] files = Directory.GetFiles(dir, "*.ogg"); string[] files2 = Directory.GetFiles(dir, "*.wav"); if (files2.Length == 0) { return files; } if (files.Length == 0) { return files2; } string[] array = new string[files.Length + files2.Length]; files.CopyTo(array, 0); files2.CopyTo(array, files.Length); return array; } private static AudioClip Load(string file, string name) { //IL_0016: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 try { AudioType val = (AudioType)(file.EndsWith(".ogg", StringComparison.OrdinalIgnoreCase) ? 14 : 20); string text = new Uri(file).AbsoluteUri.Replace("+", "%2B"); UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(text, val); try { UnityWebRequestAsyncOperation val2 = audioClip.SendWebRequest(); while (!((AsyncOperation)val2).isDone) { } if ((int)audioClip.result == 2 || (int)audioClip.result == 3) { Plugin.Log.LogError((object)("[Bugle] " + file + ": " + audioClip.error)); return null; } AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip); if ((Object)(object)content != (Object)null) { ((Object)content).name = name; } return content; } finally { ((IDisposable)audioClip)?.Dispose(); } } catch (Exception ex) { Plugin.Log.LogError((object)("[Bugle] " + file + ": " + ex.Message)); return null; } } public static void Apply(BugleSFX sfx) { if (!((Object)(object)sfx == (Object)null) && clips.Count != 0 && sfx.bugle != null && sfx.bugle.Length != 0) { for (int i = 0; i < sfx.bugle.Length; i++) { sfx.bugle[i] = clips[i % clips.Count]; } ApplyVolume(sfx); Plugin.Log.LogInfo((object)$"[Bugle] swapped {sfx.bugle.Length} slot(s); ceiling {sfx.volume:0.00}."); } } public static void ApplyVolume(BugleSFX sfx) { if (!((Object)(object)sfx == (Object)null) && clips.Count != 0 && Plugin.Bound != null) { sfx.volume = Mathf.Clamp01(Plugin.Bound.Volume.Value); CentrePitch(sfx); NoDoppler(sfx); LockPitch(sfx); } } private static void LockPitch(BugleSFX sfx) { if (sfx.pitchWobble != 0f) { if (!loggedWobble) { loggedWobble = true; Plugin.Log.LogInfo((object)($"[Bugle] pitch wobble was {sfx.pitchWobble:0.000}; now held steady so " + "every listener hears the note it started on.")); } sfx.pitchWobble = 0f; } } private static void NoDoppler(BugleSFX sfx) { bool flag = false; if ((Object)(object)sfx.buglePlayer != (Object)null && sfx.buglePlayer.dopplerLevel != 0f) { if (!loggedDoppler) { Plugin.Log.LogInfo((object)$"[Bugle] doppler was {sfx.buglePlayer.dopplerLevel:0.00}; now off."); } sfx.buglePlayer.dopplerLevel = 0f; flag = true; } if ((Object)(object)sfx.bugleEnd != (Object)null && sfx.bugleEnd.dopplerLevel != 0f) { sfx.bugleEnd.dopplerLevel = 0f; flag = true; } if (flag) { loggedDoppler = true; } } private static void CentrePitch(BugleSFX sfx) { float num = sfx.pitchMax - sfx.pitchMin; if (num <= 0f) { return; } float num2 = 1f - num * 0.5f; float num3 = 1f + num * 0.5f; if (!(Mathf.Abs(sfx.pitchMin - num2) < 0.0001f) || !(Mathf.Abs(sfx.pitchMax - num3) < 0.0001f)) { if (!loggedPitch) { loggedPitch = true; Plugin.Log.LogInfo((object)($"[Bugle] pitch range {sfx.pitchMin:0.00}-{sfx.pitchMax:0.00} " + $"(level look played at {(sfx.pitchMin + sfx.pitchMax) * 0.5f:0.00}x) " + $"-> {num2:0.00}-{num3:0.00}, level look now 1.00x")); } sfx.pitchMin = num2; sfx.pitchMax = num3; } } } [HarmonyPatch(typeof(BugleSFX), "Update")] public static class PatchBugleVolume { private static void Prefix(BugleSFX __instance) { try { Bugle.ApplyVolume(__instance); } catch { } } } [HarmonyPatch(typeof(BugleSFX), "Start")] public static class PatchBugleStart { private static void Postfix(BugleSFX __instance) { try { Bugle.Apply(__instance); } catch (Exception arg) { Plugin.Log.LogError((object)$"[Bugle] {arg}"); } } } public class ModConfig { public readonly ConfigEntry Volume; public ModConfig(ConfigFile cfg) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown cfg.SaveOnConfigSet = false; Volume = cfg.Bind("FettyRockBugle", "Volume", 1f, new ConfigDescription("How loud the bugle gets. Replaces the game's own ceiling of 0.35, so 1 is about 9 dB louder than vanilla ever managed.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); cfg.Save(); cfg.SaveOnConfigSet = true; } } [BepInPlugin("FettyRockBugle", "FettyRockBugle", "1.0.0")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("FettyRockBugle"); internal static ManualLogSource Log { get; private set; } internal static ModConfig Bound { get; private set; } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Bound = new ModConfig(((BaseUnityPlugin)this).Config); Bugle.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); harmony.PatchAll(); Log.LogInfo((object)$"FettyRockBugle loaded with {Bugle.Count} clip(s)."); } } }