Decompiled source of ValheimSpeakerMode v1.0.1

ValheimSpeakerMode.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Valheim.SettingsGui;

[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("ValheimSpeakerMode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+c2f09e5b130fe4c806a0e2f92c47ad58657b82ab")]
[assembly: AssemblyProduct("ValheimSpeakerMode")]
[assembly: AssemblyTitle("ValheimSpeakerMode")]
[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 ValheimSpeakerMode
{
	[HarmonyPatch(typeof(AudioSettings), "Initialize")]
	internal static class AudioSettingsInitializePatch
	{
		private static void Postfix(AudioSettings __instance, Toggle ___m_continousMusic)
		{
			try
			{
				AudioModeDropdown.Attach(__instance, ___m_continousMusic);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Could not inject speaker mode dropdown: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(AudioSettings), "OnTabOpen")]
	internal static class AudioSettingsTabOpenPatch
	{
		private static void Postfix(AudioSettings __instance, Button backButton, Button okButton)
		{
			AudioModeDropdown component = ((Component)__instance).GetComponent<AudioModeDropdown>();
			if ((Object)(object)component != (Object)null)
			{
				component.RefreshSelection();
				component.UpdateNavigation(backButton, okButton);
			}
		}
	}
	[HarmonyPatch(typeof(AudioSettings), "OnOkAsync")]
	internal static class AudioSettingsOkPatch
	{
		private static void Prefix()
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				Plugin.Instance.CommitSpeakerMode();
			}
		}
	}
	[HarmonyPatch(typeof(AudioSettings), "OnBack")]
	internal static class AudioSettingsBackPatch
	{
		private static void Postfix()
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				Plugin.Instance.RevertSpeakerMode();
			}
		}
	}
	internal sealed class AudioModeDropdown : MonoBehaviour
	{
		private static readonly int[] ModeValues = new int[7] { 1, 2, 3, 4, 5, 6, 7 };

		private TMP_Dropdown _dropdown;

		private Toggle _lastVanillaControl;

		internal static void Attach(AudioSettings audio, Toggle lastVanillaControl)
		{
			if (!((Object)(object)audio == (Object)null) && !((Object)(object)lastVanillaControl == (Object)null) && !((Object)(object)((Component)audio).GetComponent<AudioModeDropdown>() != (Object)null))
			{
				Component val = FindNativeDropdown();
				if ((Object)(object)val == (Object)null)
				{
					throw new InvalidOperationException("Could not find Valheim's native GuiDropdown template.");
				}
				Transform parent = ((Component)lastVanillaControl).transform.parent;
				if ((Object)(object)parent == (Object)null || (Object)(object)((Component)parent).GetComponent<VerticalLayoutGroup>() == (Object)null)
				{
					throw new InvalidOperationException("Could not find the Audio Settings VerticalLayoutGroup.");
				}
				Transform val2 = parent.Find("MasterVolume");
				if ((Object)(object)val2 == (Object)null)
				{
					throw new InvalidOperationException("Could not find MasterVolume row.");
				}
				Transform obj = val2.Find("Label");
				if ((Object)(object)obj == (Object)null)
				{
					throw new InvalidOperationException("Could not find MasterVolume Label.");
				}
				TMP_Text component = ((Component)obj).GetComponent<TMP_Text>();
				if ((Object)(object)component == (Object)null)
				{
					throw new InvalidOperationException("MasterVolume Label has no TMP_Text component.");
				}
				AudioModeDropdown audioModeDropdown = ((Component)audio).gameObject.AddComponent<AudioModeDropdown>();
				audioModeDropdown._lastVanillaControl = lastVanillaControl;
				audioModeDropdown.Build(parent, val2, component, val);
			}
		}

		private static Component FindNativeDropdown()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Type type = AccessTools.TypeByName("Valheim.SettingsGui.GraphicsSettings");
			if (type == null)
			{
				type = AccessTools.TypeByName("GraphicsSettings");
			}
			if (type == null)
			{
				return null;
			}
			FieldInfo fieldInfo = AccessTools.Field(type, "m_resolutionDropdown");
			if (fieldInfo == null)
			{
				return null;
			}
			Object[] array = Resources.FindObjectsOfTypeAll(type);
			Object[] array2 = array;
			foreach (Object obj in array2)
			{
				Component val = (Component)(object)((obj is Component) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Scene scene = val.gameObject.scene;
				if (((Scene)(ref scene)).IsValid())
				{
					object? value = fieldInfo.GetValue(val);
					Component val2 = (Component)((value is Component) ? value : null);
					if ((Object)(object)val2 != (Object)null && (Object)(object)val2.GetComponent<TMP_Dropdown>() != (Object)null)
					{
						return val2;
					}
				}
			}
			array2 = array;
			foreach (Object obj2 in array2)
			{
				Component val3 = (Component)(object)((obj2 is Component) ? obj2 : null);
				if (!((Object)(object)val3 == (Object)null))
				{
					object? value2 = fieldInfo.GetValue(val3);
					Component val4 = (Component)((value2 is Component) ? value2 : null);
					if ((Object)(object)val4 != (Object)null && (Object)(object)val4.GetComponent<TMP_Dropdown>() != (Object)null)
					{
						return val4;
					}
				}
			}
			return null;
		}

		private void Build(Transform layoutParent, Transform rowTemplate, TMP_Text labelSource, Component dropdownTemplate)
		{
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)rowTemplate).gameObject, layoutParent, false);
			((Object)val).name = "SpeakerMode";
			Transform val2 = val.transform.Find("Background");
			Transform val3 = val.transform.Find("Fill Area");
			Transform val4 = val.transform.Find("Handle Slide Area");
			Transform val5 = val.transform.Find("Value");
			if ((Object)(object)val2 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val2).gameObject);
			}
			if ((Object)(object)val3 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val3).gameObject);
			}
			if ((Object)(object)val4 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val4).gameObject);
			}
			if ((Object)(object)val5 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val5).gameObject);
			}
			Selectable component = val.GetComponent<Selectable>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Slider component2 = val.GetComponent<Slider>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.Destroy((Object)(object)component2);
			}
			Component[] components = val.GetComponents<Component>();
			foreach (Component val6 in components)
			{
				if (!((Object)(object)val6 == (Object)null) && ((object)val6).GetType().Name == "GuiSlider")
				{
					Object.Destroy((Object)(object)val6);
				}
			}
			Transform obj = val.transform.Find("Label");
			if ((Object)(object)obj == (Object)null)
			{
				throw new InvalidOperationException("Cloned slider row has no Label.");
			}
			TMP_Text component3 = ((Component)obj).GetComponent<TMP_Text>();
			if ((Object)(object)component3 == (Object)null)
			{
				throw new InvalidOperationException("Cloned slider label has no TMP_Text.");
			}
			component3.text = "Speaker mode";
			((Graphic)component3).raycastTarget = false;
			LayoutElement val7 = val.GetComponent<LayoutElement>();
			if ((Object)(object)val7 == (Object)null)
			{
				val7 = val.AddComponent<LayoutElement>();
			}
			val7.minHeight = 46f;
			val7.preferredHeight = 46f;
			val7.flexibleHeight = 0f;
			((Transform)val.GetComponent<RectTransform>()).localScale = Vector3.one;
			GameObject val8 = Object.Instantiate<GameObject>(dropdownTemplate.gameObject, val.transform, false);
			((Object)val8).name = "SpeakerModeDropdown";
			val8.SetActive(true);
			_dropdown = val8.GetComponent<TMP_Dropdown>();
			if ((Object)(object)_dropdown == (Object)null)
			{
				throw new InvalidOperationException("Cloned native dropdown has no TMP_Dropdown.");
			}
			RectTransform component4 = val8.GetComponent<RectTransform>();
			component4.anchorMin = new Vector2(0f, 0.5f);
			component4.anchorMax = new Vector2(0f, 0.5f);
			component4.pivot = new Vector2(0f, 0.5f);
			component4.SetSizeWithCurrentAnchors((Axis)0, 180f);
			component4.SetSizeWithCurrentAnchors((Axis)1, 46f);
			component4.anchoredPosition = Vector2.zero;
			((Transform)component4).localScale = Vector3.one;
			LayoutElement val9 = val8.GetComponent<LayoutElement>();
			if ((Object)(object)val9 == (Object)null)
			{
				val9 = val8.AddComponent<LayoutElement>();
			}
			val9.ignoreLayout = true;
			_dropdown.ClearOptions();
			_dropdown.AddOptions(new List<string> { "Mono", "Stereo", "Quad", "5.0 Surround", "5.1 Surround", "7.1 Surround", "Prologic" });
			((UnityEvent<int>)(object)_dropdown.onValueChanged).AddListener((UnityAction<int>)OnModeSelected);
			RefreshSelection();
			val.transform.SetSiblingIndex(((Component)_lastVanillaControl).transform.GetSiblingIndex());
			val.SetActive(true);
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)layoutParent).GetComponent<RectTransform>());
		}

		private void OnModeSelected(int index)
		{
			if (index >= 0 && index < ModeValues.Length && !((Object)(object)Plugin.Instance == (Object)null))
			{
				Plugin.Instance.PreviewSpeakerMode(ModeValues[index]);
			}
		}

		internal void RefreshSelection()
		{
			if (!((Object)(object)_dropdown == (Object)null) && !((Object)(object)Plugin.Instance == (Object)null))
			{
				_dropdown.SetValueWithoutNotify(IndexForMode(Plugin.Instance.PreviewMode));
				_dropdown.RefreshShownValue();
			}
		}

		internal void UpdateNavigation(Button backButton, Button okButton)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_dropdown == (Object)null) && !((Object)(object)_lastVanillaControl == (Object)null))
			{
				Navigation navigation = ((Selectable)_lastVanillaControl).navigation;
				((Navigation)(ref navigation)).mode = (Mode)4;
				((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)_dropdown;
				((Selectable)_lastVanillaControl).navigation = navigation;
				Navigation navigation2 = ((Selectable)_dropdown).navigation;
				((Navigation)(ref navigation2)).mode = (Mode)4;
				((Navigation)(ref navigation2)).selectOnUp = (Selectable)(object)_lastVanillaControl;
				if ((Object)(object)backButton != (Object)null)
				{
					((Navigation)(ref navigation2)).selectOnDown = (Selectable)(object)backButton;
				}
				((Selectable)_dropdown).navigation = navigation2;
				if ((Object)(object)backButton != (Object)null)
				{
					Navigation navigation3 = ((Selectable)backButton).navigation;
					((Navigation)(ref navigation3)).mode = (Mode)4;
					((Navigation)(ref navigation3)).selectOnUp = (Selectable)(object)_dropdown;
					((Selectable)backButton).navigation = navigation3;
				}
				if ((Object)(object)okButton != (Object)null)
				{
					Navigation navigation4 = ((Selectable)okButton).navigation;
					((Navigation)(ref navigation4)).mode = (Mode)4;
					((Navigation)(ref navigation4)).selectOnUp = (Selectable)(object)_dropdown;
					((Selectable)okButton).navigation = navigation4;
				}
			}
		}

		private static int IndexForMode(int mode)
		{
			for (int i = 0; i < ModeValues.Length; i++)
			{
				if (ModeValues[i] == mode)
				{
					return i;
				}
			}
			return 0;
		}
	}
	[BepInPlugin("com.patrickmollohan.valheimspeakermode", "Valheim Speaker Mode", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private sealed class MusicSnapshot
		{
			public object NamedMusic;

			public string MusicName;

			public int TimeSamples;

			public bool WasPlaying;
		}

		public const string PluginGuid = "com.patrickmollohan.valheimspeakermode";

		public const string PluginName = "Valheim Speaker Mode";

		public const string PluginVersion = "1.0.1";

		private Harmony _harmony;

		private int _committedMode;

		private int _previewMode;

		private MusicSnapshot _musicSnapshot;

		private Coroutine _musicRestoreCoroutine;

		private static readonly BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic;

		private static readonly FieldInfo MusicManSourceField = typeof(MusicMan).GetField("m_musicSource", PrivateInstance);

		private static readonly FieldInfo MusicManCurrentField = typeof(MusicMan).GetField("m_currentMusic", PrivateInstance);

		private static readonly FieldInfo MusicManQueuedField = typeof(MusicMan).GetField("m_queuedMusic", PrivateInstance);

		private static readonly FieldInfo MusicManStopField = typeof(MusicMan).GetField("m_stopMusic", PrivateInstance);

		private static readonly FieldInfo NamedMusicNameField = typeof(NamedMusic).GetField("m_name");

		private static readonly FieldInfo NamedMusicResumeField = typeof(NamedMusic).GetField("m_resume");

		private static readonly FieldInfo NamedMusicLoopField = typeof(NamedMusic).GetField("m_loop");

		private static readonly FieldInfo NamedMusicSavedPositionField = typeof(NamedMusic).GetField("m_savedPlaybackPos");

		private static readonly FieldInfo NamedMusicLastPlayedField = typeof(NamedMusic).GetField("m_lastPlayedTime");

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal ConfigEntry<int> SavedSpeakerMode { get; private set; }

		internal int PreviewMode => _previewMode;

		private void Awake()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			SavedSpeakerMode = ((BaseUnityPlugin)this).Config.Bind<int>("Audio", "SpeakerMode", 2, "Unity speaker mode.");
			_committedMode = SavedSpeakerMode.Value;
			_previewMode = _committedMode;
			_harmony = new Harmony("com.patrickmollohan.valheimspeakermode");
			try
			{
				ApplySpeakerMode(_committedMode, "startup");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Could not apply the saved speaker mode: " + ex));
			}
			_harmony.PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Valheim Speaker Mode 1.0.1 loaded.");
		}

		internal void PreviewSpeakerMode(int requestedMode)
		{
			_previewMode = requestedMode;
			ApplySpeakerMode(requestedMode, "preview");
		}

		internal void CommitSpeakerMode()
		{
			_committedMode = _previewMode;
			SavedSpeakerMode.Value = _committedMode;
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Saved speaker mode: " + ModeName(_committedMode)));
		}

		internal void RevertSpeakerMode()
		{
			_previewMode = _committedMode;
			ApplySpeakerMode(_committedMode, "revert");
		}

		private unsafe void ApplySpeakerMode(int requestedMode, string reason)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if (!Enum.IsDefined(typeof(AudioSpeakerMode), requestedMode))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Ignoring invalid AudioSpeakerMode value: " + requestedMode));
				return;
			}
			AudioSpeakerMode val = (AudioSpeakerMode)requestedMode;
			AudioConfiguration configuration = AudioSettings.GetConfiguration();
			if (configuration.speakerMode == val)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Speaker mode already " + ((object)(*(AudioSpeakerMode*)(&val))/*cast due to .constrained prefix*/).ToString() + " (" + reason + ")."));
				return;
			}
			CaptureMusicState();
			configuration.speakerMode = val;
			bool flag = AudioSettings.Reset(configuration);
			AudioSpeakerMode speakerMode = AudioSettings.GetConfiguration().speakerMode;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Speaker mode " + reason + ": requested " + ((object)(*(AudioSpeakerMode*)(&val))/*cast due to .constrained prefix*/).ToString() + ", actual " + ((object)(*(AudioSpeakerMode*)(&speakerMode))/*cast due to .constrained prefix*/).ToString() + ", Reset returned " + flag + "."));
			if (!flag || speakerMode != val)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("The audio driver did not accept " + ((object)(*(AudioSpeakerMode*)(&val))/*cast due to .constrained prefix*/).ToString() + ". Check the operating system's speaker layout and audio device capabilities."));
			}
			RestoreMusicStateAfterReset();
		}

		private void CaptureMusicState()
		{
			_musicSnapshot = null;
			try
			{
				MusicMan instance = MusicMan.instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				object? obj = MusicManSourceField?.GetValue(instance);
				AudioSource val = (AudioSource)((obj is AudioSource) ? obj : null);
				object obj2 = MusicManCurrentField?.GetValue(instance);
				object obj3 = MusicManQueuedField?.GetValue(instance) ?? obj2;
				if (obj3 != null)
				{
					string text = NamedMusicNameField?.GetValue(obj3) as string;
					if (!string.IsNullOrEmpty(text))
					{
						bool flag = (Object)(object)val != (Object)null && val.isPlaying;
						int timeSamples = (flag ? val.timeSamples : 0);
						_musicSnapshot = new MusicSnapshot
						{
							NamedMusic = obj3,
							MusicName = text,
							TimeSamples = timeSamples,
							WasPlaying = flag
						};
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Captured music before audio reset: " + text + ", playing=" + flag + ", samples=" + timeSamples));
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not capture music state before audio reset: " + ex));
			}
		}

		private void RestoreMusicStateAfterReset()
		{
			if (_musicSnapshot != null && _musicSnapshot.WasPlaying)
			{
				if (_musicRestoreCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_musicRestoreCoroutine);
				}
				_musicRestoreCoroutine = ((MonoBehaviour)this).StartCoroutine(RestoreMusicAfterDelay());
			}
		}

		private IEnumerator RestoreMusicAfterDelay()
		{
			yield return null;
			yield return null;
			try
			{
				MusicMan instance = MusicMan.instance;
				if ((Object)(object)instance == (Object)null || (Object)/*isinst with value type is only supported in some contexts*/ == (Object)null)
				{
					yield break;
				}
				object namedMusic = _musicSnapshot.NamedMusic;
				if (namedMusic != null)
				{
					MusicManQueuedField?.SetValue(instance, namedMusic);
					MusicManStopField?.SetValue(instance, false);
					bool flag = NamedMusicLoopField != null && (bool)NamedMusicLoopField.GetValue(namedMusic);
					bool flag2 = NamedMusicResumeField != null && (bool)NamedMusicResumeField.GetValue(namedMusic);
					if (flag && flag2)
					{
						NamedMusicSavedPositionField?.SetValue(namedMusic, Mathf.Max(0, _musicSnapshot.TimeSamples));
						NamedMusicLastPlayedField?.SetValue(namedMusic, Time.time);
					}
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Queued music restoration: " + _musicSnapshot.MusicName + ", resume=" + (flag && flag2) + ", samples=" + _musicSnapshot.TimeSamples));
					_musicSnapshot = null;
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not restore music after audio reset: " + ex));
				_musicSnapshot = null;
			}
			finally
			{
				_musicRestoreCoroutine = null;
			}
		}

		internal static string ModeName(int mode)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected I4, but got Unknown
			AudioSpeakerMode val = (AudioSpeakerMode)mode;
			return (val - 1) switch
			{
				0 => "Mono", 
				1 => "Stereo", 
				2 => "Quad", 
				3 => "5.0 Surround", 
				4 => "5.1 Surround", 
				5 => "7.1 Surround", 
				6 => "Prologic", 
				_ => "Unknown (" + mode + ")", 
			};
		}

		private void OnDestroy()
		{
			if (_musicRestoreCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_musicRestoreCoroutine);
			}
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
}