Decompiled source of TheFEINScott v1.0.1

plugins/RimuGOD-The_FEIN_Scott-1.0.0/TheFEINScott.dll

Decompiled a month ago
using 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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TheFEINScott")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TheFEINScott")]
[assembly: AssemblyTitle("TheFEINScott")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace TheFEINScott
{
	[BepInPlugin("thundermod.the_fein_scott", "The FEIN Scott", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <LoadFeinAudio>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string path;

			private UnityWebRequest <request>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadFeinAudio>d__5(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<request>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Invalid comparison between Unknown and I4
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						string text = "file:///" + path.Replace("\\", "/");
						<request>5__2 = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)14);
						<>1__state = -3;
						((DownloadHandlerAudioClip)<request>5__2.downloadHandler).streamAudio = false;
						<>2__current = <request>5__2.SendWebRequest();
						<>1__state = 1;
						return true;
					}
					case 1:
						<>1__state = -3;
						if ((int)<request>5__2.result == 1)
						{
							FeinClip = DownloadHandlerAudioClip.GetContent(<request>5__2);
							((Object)FeinClip).name = "fein";
							Log.LogInfo((object)"[The FEIN Scott] loaded successfully!");
						}
						else
						{
							Log.LogError((object)("[The FEIN Scott] Failed to load: " + <request>5__2.error));
						}
						<>m__Finally1();
						<request>5__2 = null;
						return false;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__2 != null)
				{
					((IDisposable)<request>5__2).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static ManualLogSource Log;

		public static AudioClip FeinClip;

		public static ConfigEntry<float> VolumeConfig;

		public static AudioSource ReplacedSource;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			VolumeConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.125f, "Volume of the Fein track (0.0 = muted, 1.0 = max).");
			VolumeConfig.SettingChanged += delegate
			{
				if ((Object)(object)ReplacedSource != (Object)null)
				{
					ReplacedSource.volume = VolumeConfig.Value;
				}
			};
			if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"))
			{
				LethalConfigHelper.Register(VolumeConfig);
			}
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "fein.ogg");
			if (!File.Exists(text))
			{
				Log.LogError((object)("[The FEIN Scott] fein.ogg not found at: " + text));
				return;
			}
			((MonoBehaviour)this).StartCoroutine(LoadFeinAudio(text));
			PatchTheFiend();
		}

		[IteratorStateMachine(typeof(<LoadFeinAudio>d__5))]
		private IEnumerator LoadFeinAudio(string path)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadFeinAudio>d__5(0)
			{
				path = path
			};
		}

		private void PatchTheFiend()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			try
			{
				Type type = AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly a)
				{
					try
					{
						return a.GetTypes();
					}
					catch
					{
						return Array.Empty<Type>();
					}
				}).FirstOrDefault((Type t) => t.Name == "TheFiendAI");
				if (type == null)
				{
					Log.LogError((object)"[The FEIN Scott] Could not find TheFiendAI type. Is The Fiend mod installed?");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(type, "Start", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Log.LogError((object)"[The FEIN Scott] Could not find TheFiendAI.Start method.");
					return;
				}
				Harmony val = new Harmony("thundermod.the_fein_scott");
				HarmonyMethod val2 = new HarmonyMethod(typeof(TheFiendPatches), "StartPostfix", (Type[])null);
				val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(AudioSource), "Play", new Type[0], (Type[])null);
				HarmonyMethod val3 = new HarmonyMethod(typeof(TheFiendPatches), "AudioSourcePlayPrefix", (Type[])null);
				val.Patch((MethodBase)methodInfo2, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(AudioSource), "Stop", (Type[])null, (Type[])null);
				HarmonyMethod val4 = new HarmonyMethod(typeof(TheFiendPatches), "AudioSourceStopPrefix", (Type[])null);
				val.Patch((MethodBase)methodInfo3, val4, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log.LogInfo((object)"[The FEIN Scott] Patched — ambient music will be replaced with Fein on all clients.");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"[The FEIN Scott] Patching failed: {arg}");
			}
		}
	}
	public static class TheFiendPatches
	{
		[CompilerGenerated]
		private sealed class <ReplaceAmbientMusic>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MonoBehaviour instance;

			private float <timeout>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ReplaceAmbientMusic>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<timeout>5__2 = 20f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)Plugin.FeinClip == (Object)null && <timeout>5__2 > 0f)
				{
					<timeout>5__2 -= Time.deltaTime;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)Plugin.FeinClip == (Object)null)
				{
					Plugin.Log.LogWarning((object)"[The FEIN Scott] Fein clip not ready in time. Skipping replacement.");
					return false;
				}
				AudioSource[] componentsInChildren = ((Component)instance).GetComponentsInChildren<AudioSource>(true);
				bool flag = false;
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource val in array)
				{
					if ((Object)(object)val.clip != (Object)null && ((Object)val.clip).name.Contains("Fran Bow"))
					{
						bool isPlaying = val.isPlaying;
						val.clip = Plugin.FeinClip;
						val.loop = true;
						val.volume = Plugin.VolumeConfig.Value;
						val.dopplerLevel = 0f;
						val.pitch = 1f;
						Plugin.ReplacedSource = val;
						if (isPlaying)
						{
							val.Stop();
							_ourPlay = true;
							val.Play();
							_ourPlay = false;
						}
						flag = true;
						Plugin.Log.LogInfo((object)"[The FEIN Scott] Ambient music replaced with Fein!");
						break;
					}
				}
				if (!flag)
				{
					Plugin.Log.LogInfo((object)"[The FEIN Scott] AudioSource.Play prefix already handled replacement.");
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <VolumeEnforcer>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MonoBehaviour instance;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <VolumeEnforcer>d__5(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)instance != (Object)null)
				{
					if ((Object)(object)Plugin.ReplacedSource != (Object)null)
					{
						Plugin.ReplacedSource.volume = Plugin.VolumeConfig.Value;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				Plugin.ReplacedSource = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		internal static bool _ourPlay;

		public static void StartPostfix(object __instance)
		{
			MonoBehaviour val = (MonoBehaviour)((__instance is MonoBehaviour) ? __instance : null);
			if (val != null)
			{
				val.StartCoroutine(ReplaceAmbientMusic(val));
				val.StartCoroutine(VolumeEnforcer(val));
			}
		}

		public static bool AudioSourcePlayPrefix(AudioSource __instance)
		{
			if ((Object)(object)Plugin.FeinClip == (Object)null)
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)(object)Plugin.ReplacedSource && (Object)(object)__instance.clip == (Object)(object)Plugin.FeinClip && __instance.isPlaying && !_ourPlay)
			{
				return false;
			}
			if ((Object)(object)__instance.clip != (Object)null && ((Object)__instance.clip).name.Contains("Fran Bow"))
			{
				__instance.clip = Plugin.FeinClip;
				__instance.loop = true;
				__instance.volume = Plugin.VolumeConfig.Value;
				__instance.dopplerLevel = 0f;
				__instance.pitch = 1f;
				Plugin.ReplacedSource = __instance;
			}
			return true;
		}

		public static bool AudioSourceStopPrefix(AudioSource __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Plugin.ReplacedSource && (Object)(object)__instance.clip == (Object)(object)Plugin.FeinClip && __instance.isPlaying && !_ourPlay)
			{
				return false;
			}
			return true;
		}

		[IteratorStateMachine(typeof(<ReplaceAmbientMusic>d__4))]
		private static IEnumerator ReplaceAmbientMusic(MonoBehaviour instance)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ReplaceAmbientMusic>d__4(0)
			{
				instance = instance
			};
		}

		[IteratorStateMachine(typeof(<VolumeEnforcer>d__5))]
		private static IEnumerator VolumeEnforcer(MonoBehaviour instance)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <VolumeEnforcer>d__5(0)
			{
				instance = instance
			};
		}
	}
	public static class LethalConfigHelper
	{
		public static void Register(ConfigEntry<float> entry)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			FloatSliderOptions val = new FloatSliderOptions();
			((BaseRangeOptions<float>)val).Min = 0f;
			((BaseRangeOptions<float>)val).Max = 1f;
			((BaseOptions)val).RequiresRestart = false;
			FloatSliderOptions val2 = val;
			LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(entry, val2));
		}
	}
}