Decompiled source of FettyRockBugle v1.0.2

FettyRockBugle.dll

Decompiled 15 hours ago
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<AudioClip> clips = new List<AudioClip>();

		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<string> list = new List<string>(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<float> 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<float>("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<float>(0f, 1f), Array.Empty<object>()));
			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).");
		}
	}
}