Decompiled source of REPO SOUNDBOARD v2.0.1

sonic.dll

Decompiled 2 weeks 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.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using MenuLib.Structs;
using MonoMod.RuntimeDetour;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("sonic")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("sonic")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("98f6da0c-f28e-4d99-a81d-92f0e99ae946")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
public class WavUtility
{
	private const int BlockSize_16Bit = 2;

	public static AudioClip ToAudioClip(string filePath)
	{
		if (!filePath.StartsWith(Application.persistentDataPath) && !filePath.StartsWith(Application.dataPath))
		{
			Debug.LogWarning((object)"This only supports files that are stored using Unity's Application data path. \nTo load bundled resources use 'Resources.Load(\"filename\") typeof(AudioClip)' method. \nhttps://docs.unity3d.com/ScriptReference/Resources.Load.html");
			return null;
		}
		byte[] fileBytes = File.ReadAllBytes(filePath);
		return ToAudioClip(fileBytes);
	}

	public static AudioClip ToAudioClip(byte[] fileBytes, int offsetSamples = 0, string name = "wav")
	{
		int num = BitConverter.ToInt32(fileBytes, 16);
		ushort code = BitConverter.ToUInt16(fileBytes, 20);
		string text = FormatCode(code);
		ushort num2 = BitConverter.ToUInt16(fileBytes, 22);
		int num3 = BitConverter.ToInt32(fileBytes, 24);
		ushort num4 = BitConverter.ToUInt16(fileBytes, 34);
		int num5 = 20 + num + 4;
		int dataSize = BitConverter.ToInt32(fileBytes, num5);
		float[] array = num4 switch
		{
			8 => Convert8BitByteArrayToAudioClipData(fileBytes, num5, dataSize), 
			16 => Convert16BitByteArrayToAudioClipData(fileBytes, num5, dataSize), 
			24 => Convert24BitByteArrayToAudioClipData(fileBytes, num5, dataSize), 
			32 => Convert32BitByteArrayToAudioClipData(fileBytes, num5, dataSize), 
			_ => throw new Exception(num4 + " bit depth is not supported."), 
		};
		AudioClip val = AudioClip.Create(name, array.Length, (int)num2, num3, false);
		val.SetData(array, 0);
		return val;
	}

	private static float[] Convert8BitByteArrayToAudioClipData(byte[] source, int headerOffset, int dataSize)
	{
		int num = BitConverter.ToInt32(source, headerOffset);
		headerOffset += 4;
		float[] array = new float[num];
		sbyte b = sbyte.MaxValue;
		for (int i = 0; i < num; i++)
		{
			array[i] = (float)(int)source[i] / (float)b;
		}
		return array;
	}

	private static float[] Convert16BitByteArrayToAudioClipData(byte[] source, int headerOffset, int dataSize)
	{
		int num = BitConverter.ToInt32(source, headerOffset);
		headerOffset += 4;
		int num2 = 2;
		int num3 = num / num2;
		float[] array = new float[num3];
		short num4 = short.MaxValue;
		int num5 = 0;
		for (int i = 0; i < num3; i++)
		{
			num5 = i * num2 + headerOffset;
			array[i] = (float)BitConverter.ToInt16(source, num5) / (float)num4;
		}
		return array;
	}

	private static float[] Convert24BitByteArrayToAudioClipData(byte[] source, int headerOffset, int dataSize)
	{
		int num = BitConverter.ToInt32(source, headerOffset);
		headerOffset += 4;
		int num2 = 3;
		int num3 = num / num2;
		int num4 = int.MaxValue;
		float[] array = new float[num3];
		byte[] array2 = new byte[4];
		int num5 = 0;
		for (int i = 0; i < num3; i++)
		{
			num5 = i * num2 + headerOffset;
			Buffer.BlockCopy(source, num5, array2, 1, num2);
			array[i] = (float)BitConverter.ToInt32(array2, 0) / (float)num4;
		}
		return array;
	}

	private static float[] Convert32BitByteArrayToAudioClipData(byte[] source, int headerOffset, int dataSize)
	{
		int num = BitConverter.ToInt32(source, headerOffset);
		headerOffset += 4;
		int num2 = 4;
		int num3 = num / num2;
		int num4 = int.MaxValue;
		float[] array = new float[num3];
		int num5 = 0;
		for (int i = 0; i < num3; i++)
		{
			num5 = i * num2 + headerOffset;
			array[i] = (float)BitConverter.ToInt32(source, num5) / (float)num4;
		}
		return array;
	}

	public static byte[] FromAudioClip(AudioClip audioClip)
	{
		string filepath;
		return FromAudioClip(audioClip, out filepath, saveAsFile: false);
	}

	public static byte[] FromAudioClip(AudioClip audioClip, out string filepath, bool saveAsFile = true, string dirname = "recordings")
	{
		MemoryStream stream = new MemoryStream();
		ushort bitDepth = 16;
		int fileSize = audioClip.samples * 2 + 44;
		WriteFileHeader(ref stream, fileSize);
		WriteFileFormat(ref stream, audioClip.channels, audioClip.frequency, bitDepth);
		WriteFileData(ref stream, audioClip, bitDepth);
		byte[] array = stream.ToArray();
		if (saveAsFile)
		{
			filepath = string.Format("{0}/{1}/{2}.{3}", Application.persistentDataPath, dirname, DateTime.UtcNow.ToString("yyMMdd-HHmmss-fff"), "wav");
			Directory.CreateDirectory(Path.GetDirectoryName(filepath));
			File.WriteAllBytes(filepath, array);
		}
		else
		{
			filepath = null;
		}
		stream.Dispose();
		return array;
	}

	private static int WriteFileHeader(ref MemoryStream stream, int fileSize)
	{
		int num = 0;
		int num2 = 12;
		byte[] bytes = Encoding.ASCII.GetBytes("RIFF");
		num += WriteBytesToMemoryStream(ref stream, bytes, "ID");
		int value = fileSize - 8;
		num += WriteBytesToMemoryStream(ref stream, BitConverter.GetBytes(value), "CHUNK_SIZE");
		byte[] bytes2 = Encoding.ASCII.GetBytes("WAVE");
		return num + WriteBytesToMemoryStream(ref stream, bytes2, "FORMAT");
	}

	private static int WriteFileFormat(ref MemoryStream stream, int channels, int sampleRate, ushort bitDepth)
	{
		int num = 0;
		int num2 = 24;
		byte[] bytes = Encoding.ASCII.GetBytes("fmt ");
		num += WriteBytesToMemoryStream(ref stream, bytes, "FMT_ID");
		int value = 16;
		num += WriteBytesToMemoryStream(ref stream, BitConverter.GetBytes(value), "SUBCHUNK_SIZE");
		ushort value2 = 1;
		num += WriteBytesToMemoryStream(ref stream, BitConverter.GetBytes(value2), "AUDIO_FORMAT");
		ushort value3 = Convert.ToUInt16(channels);
		num += WriteBytesToMemoryStream(ref stream, BitConverter.GetBytes(value3), "CHANNELS");
		num += WriteBytesToMemoryStream(ref stream, BitConverter.GetBytes(sampleRate), "SAMPLE_RATE");
		int value4 = sampleRate * channels * BytesPerSample(bitDepth);
		num += WriteBytesToMemoryStream(ref stream, BitConverter.GetBytes(value4), "BYTE_RATE");
		ushort value5 = Convert.ToUInt16(channels * BytesPerSample(bitDepth));
		num += WriteBytesToMemoryStream(ref stream, BitConverter.GetBytes(value5), "BLOCK_ALIGN");
		return num + WriteBytesToMemoryStream(ref stream, BitConverter.GetBytes(bitDepth), "BITS_PER_SAMPLE");
	}

	private static int WriteFileData(ref MemoryStream stream, AudioClip audioClip, ushort bitDepth)
	{
		int num = 0;
		int num2 = 8;
		float[] array = new float[audioClip.samples * audioClip.channels];
		audioClip.GetData(array, 0);
		byte[] bytes = ConvertAudioClipDataToInt16ByteArray(array);
		byte[] bytes2 = Encoding.ASCII.GetBytes("data");
		num += WriteBytesToMemoryStream(ref stream, bytes2, "DATA_ID");
		int value = Convert.ToInt32(audioClip.samples * 2);
		num += WriteBytesToMemoryStream(ref stream, BitConverter.GetBytes(value), "SAMPLES");
		return num + WriteBytesToMemoryStream(ref stream, bytes, "DATA");
	}

	private static byte[] ConvertAudioClipDataToInt16ByteArray(float[] data)
	{
		MemoryStream memoryStream = new MemoryStream();
		int count = 2;
		short num = short.MaxValue;
		for (int i = 0; i < data.Length; i++)
		{
			memoryStream.Write(BitConverter.GetBytes(Convert.ToInt16(data[i] * (float)num)), 0, count);
		}
		byte[] result = memoryStream.ToArray();
		memoryStream.Dispose();
		return result;
	}

	private static int WriteBytesToMemoryStream(ref MemoryStream stream, byte[] bytes, string tag = "")
	{
		int num = bytes.Length;
		stream.Write(bytes, 0, num);
		return num;
	}

	public static ushort BitDepth(AudioClip audioClip)
	{
		return Convert.ToUInt16((float)(audioClip.samples * audioClip.channels) * audioClip.length / (float)audioClip.frequency);
	}

	private static int BytesPerSample(ushort bitDepth)
	{
		return bitDepth / 8;
	}

	private static int BlockSize(ushort bitDepth)
	{
		return bitDepth switch
		{
			32 => 4, 
			16 => 2, 
			8 => 1, 
			_ => throw new Exception(bitDepth + " bit depth is not supported."), 
		};
	}

	private static string FormatCode(ushort code)
	{
		switch (code)
		{
		case 1:
			return "PCM";
		case 2:
			return "ADPCM";
		case 3:
			return "IEEE";
		case 7:
			return "μ-law";
		case 65534:
			return "WaveFormatExtensable";
		default:
			Debug.LogWarning((object)("Unknown wav code format:" + code));
			return "";
		}
	}
}
namespace SingularitySoundboard;

[BepInPlugin("com.soundboard", "Soundboard", "1.0.0")]
[BepInDependency("nickklmao.menulib", "2.5.0")]
public class SoundboardPlugin : BaseUnityPlugin
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static BuilderDelegate <>9__32_0;

		public static Func<PlayerAvatar, bool> <>9__37_0;

		public static Func<PlayerAvatar, bool> <>9__43_0;

		public static Func<Transform, bool> <>9__44_0;

		public static Func<Transform, float> <>9__44_1;

		public static Action<float> <>9__46_5;

		public static ScrollViewBuilderDelegate <>9__46_0;

		public static Action<float> <>9__46_9;

		public static ScrollViewBuilderDelegate <>9__46_2;

		public static Action<float> <>9__46_10;

		public static ScrollViewBuilderDelegate <>9__46_3;

		public static Func<PlayerAvatar, bool> <>9__46_12;

		public static Action<bool> <>9__46_11;

		public static ScrollViewBuilderDelegate <>9__46_4;

		public static ScrollViewBuilderDelegate <>9__48_0;

		public static ScrollViewBuilderDelegate <>9__48_1;

		public static Action<string> <>9__51_2;

		public static ScrollViewBuilderDelegate <>9__51_0;

		internal void <Awake>b__32_0(Transform parent)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			MenuAPI.CreateREPOButton("Soundboard", (Action)CreateSoundboardMenu, parent, new Vector2(126f, 86f));
		}

		internal bool <PlayAudioClip>b__37_0(PlayerAvatar p)
		{
			return (Object)(object)p.photonView == (Object)null || p.photonView.IsMine;
		}

		internal bool <StopPlayback>b__43_0(PlayerAvatar p)
		{
			return (Object)(object)p.photonView == (Object)null || p.photonView.IsMine;
		}

		internal bool <MenuPageMain_StartHook>b__44_0(Transform t)
		{
			return ((Object)t).name.Contains("Menu Button");
		}

		internal float <MenuPageMain_StartHook>b__44_1(Transform t)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return t.localPosition.y;
		}

		internal RectTransform <AddGlobalControls>b__46_0(Transform scrollView)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			return ((REPOElement)MenuAPI.CreateREPOSlider("Volume", "Loudness", (Action<float>)delegate(float v)
			{
				CurrentVolume = v;
				if ((Object)(object)_localHearSelfSource != (Object)null)
				{
					_localHearSelfSource.volume = v;
				}
				Instance.SaveConfig();
			}, scrollView, Vector2.zero, 0f, 2f, 1, CurrentVolume, "", "", (BarBehavior)0)).rectTransform;
		}

		internal void <AddGlobalControls>b__46_5(float v)
		{
			CurrentVolume = v;
			if ((Object)(object)_localHearSelfSource != (Object)null)
			{
				_localHearSelfSource.volume = v;
			}
			Instance.SaveConfig();
		}

		internal RectTransform <AddGlobalControls>b__46_2(Transform scrollView)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			return ((REPOElement)MenuAPI.CreateREPOSlider("Pitch", "Deepness", (Action<float>)delegate(float p)
			{
				CurrentPitch = p;
				if ((Object)(object)_localHearSelfSource != (Object)null)
				{
					_localHearSelfSource.pitch = p;
				}
				Instance.SaveConfig();
			}, scrollView, Vector2.zero, 0.1f, 3f, 1, CurrentPitch, "", "", (BarBehavior)0)).rectTransform;
		}

		internal void <AddGlobalControls>b__46_9(float p)
		{
			CurrentPitch = p;
			if ((Object)(object)_localHearSelfSource != (Object)null)
			{
				_localHearSelfSource.pitch = p;
			}
			Instance.SaveConfig();
		}

		internal RectTransform <AddGlobalControls>b__46_3(Transform scrollView)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			return ((REPOElement)MenuAPI.CreateREPOSlider("Bass", "Thick", (Action<float>)delegate(float b)
			{
				CurrentBass = b;
				Instance.SaveConfig();
			}, scrollView, Vector2.zero, 0f, 1f, 1, CurrentBass, "", "", (BarBehavior)0)).rectTransform;
		}

		internal void <AddGlobalControls>b__46_10(float b)
		{
			CurrentBass = b;
			Instance.SaveConfig();
		}

		internal RectTransform <AddGlobalControls>b__46_4(Transform scrollView)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			return ((REPOElement)MenuAPI.CreateREPOToggle("Loop Mode", (Action<bool>)delegate(bool l)
			{
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Expected O, but got Unknown
				IsLooping = l;
				if ((Object)(object)_localHearSelfSource != (Object)null)
				{
					_localHearSelfSource.loop = l;
				}
				PlayerAvatar val = GameDirector.instance?.PlayerList?.FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => (Object)(object)p.photonView == (Object)null || p.photonView.IsMine));
				if ((Object)(object)val != (Object)null)
				{
					object obj = typeof(PlayerAvatar).GetField("voiceChat", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val);
					if (obj != null)
					{
						AudioSource val2 = (AudioSource)AccessTools.Field(typeof(PlayerVoiceChat), "audioSource").GetValue(obj);
						if ((Object)(object)val2 != (Object)null)
						{
							val2.loop = l;
						}
					}
				}
				Instance.SaveConfig();
			}, scrollView, Vector2.zero, "ON", "OFF", IsLooping)).rectTransform;
		}

		internal void <AddGlobalControls>b__46_11(bool l)
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			IsLooping = l;
			if ((Object)(object)_localHearSelfSource != (Object)null)
			{
				_localHearSelfSource.loop = l;
			}
			PlayerAvatar val = GameDirector.instance?.PlayerList?.FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => (Object)(object)p.photonView == (Object)null || p.photonView.IsMine));
			if ((Object)(object)val != (Object)null)
			{
				object obj = typeof(PlayerAvatar).GetField("voiceChat", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val);
				if (obj != null)
				{
					AudioSource val2 = (AudioSource)AccessTools.Field(typeof(PlayerVoiceChat), "audioSource").GetValue(obj);
					if ((Object)(object)val2 != (Object)null)
					{
						val2.loop = l;
					}
				}
			}
			Instance.SaveConfig();
		}

		internal bool <AddGlobalControls>b__46_12(PlayerAvatar p)
		{
			return (Object)(object)p.photonView == (Object)null || p.photonView.IsMine;
		}

		internal RectTransform <ToggleQuickMenu>b__48_0(Transform scrollView)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return ((REPOElement)MenuAPI.CreateREPOButton("\ud83d\udd04 REFRESH LAYOUT", (Action)RefreshQuickLayout, scrollView, Vector2.zero)).rectTransform;
		}

		internal RectTransform <ToggleQuickMenu>b__48_1(Transform scrollView)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return ((REPOElement)MenuAPI.CreateREPOButton("STOP ALL", (Action)StopPlayback, scrollView, Vector2.zero)).rectTransform;
		}

		internal RectTransform <OpenFolder>b__51_0(Transform scrollView)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			REPOInputField val2 = MenuAPI.CreateREPOInputField("SEARCH SFX", (Action<string>)delegate(string val)
			{
				currentSearchFilter = val.ToLower().Trim();
			}, scrollView, Vector2.zero, false, "Type here...", currentSearchFilter);
			return ((REPOElement)val2).rectTransform;
		}

		internal void <OpenFolder>b__51_2(string val)
		{
			currentSearchFilter = val.ToLower().Trim();
		}
	}

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

		private object <>2__current;

		public AudioSource source;

		public AudioClip clip;

		public object recorder;

		private float <duration>5__1;

		private Type <recType>5__2;

		private AudioClip <baked>5__3;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<recType>5__2 = null;
			<baked>5__3 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<duration>5__1 = clip.length;
				break;
			case 1:
				<>1__state = -1;
				if (IsLooping && IsPlayingSound)
				{
					if (MelodyStepCount > 0 && MelodyPitches.Count > 0)
					{
						PlayAudioClip(GetOriginalClip(clip));
						return false;
					}
					if (recorder != null)
					{
						<recType>5__2 = recorder.GetType();
						<recType>5__2.GetMethod("StopRecording")?.Invoke(recorder, null);
						AccessTools.Property(<recType>5__2, "SourceType").SetValue(recorder, 0);
						AccessTools.Property(<recType>5__2, "SourceType").SetValue(recorder, 1);
						<baked>5__3 = (AudioClip)AccessTools.Property(<recType>5__2, "AudioClip").GetValue(recorder);
						AccessTools.Property(<recType>5__2, "AudioClip").SetValue(recorder, <baked>5__3);
						<recType>5__2.GetMethod("StartRecording")?.Invoke(recorder, null);
						<recType>5__2 = null;
						<baked>5__3 = null;
					}
					source.Play();
					if ((Object)(object)_localHearSelfSource != (Object)null)
					{
						_localHearSelfSource.Play();
					}
					break;
				}
				StopPlayback();
				return false;
			}
			if (IsPlayingSound)
			{
				<>2__current = (object)new WaitForSeconds(<duration>5__1);
				<>1__state = 1;
				return true;
			}
			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();
		}
	}

	private static Dictionary<string, AssetBundle> _loadedBundles = new Dictionary<string, AssetBundle>();

	public static float CurrentBass = 0f;

	private static ConfigEntry<float> configBass;

	public static bool IsPlayingSound = false;

	public static float CurrentVolume = 1f;

	public static float CurrentPitch = 1f;

	public static bool IsLooping = false;

	private static string currentSearchFilter = "";

	private static float _currentClipLength = 0f;

	private static AudioSource _localHearSelfSource;

	private static REPOPopupPage _quickMenuPage;

	private static List<string> quickBoardSounds = new List<string>();

	private static List<string> favouriteSounds = new List<string>();

	private static List<string> repoSounds = new List<string>();

	private static List<string> memeSounds = new List<string>();

	private static List<string> otherSounds = new List<string>();

	private static List<string> myInstantsSounds = new List<string>();

	private static List<string> musicSounds = new List<string>();

	private static ConfigEntry<string> configQuickBoard;

	private static ConfigEntry<float> configVolume;

	private static ConfigEntry<float> configPitch;

	private static ConfigEntry<bool> configLoop;

	private static ConfigEntry<string> configFavourites;

	public static int MelodyStepCount = 0;

	public static List<float> MelodyPitches = new List<float>();

	private static int _currentMelodyIndex = 0;

	private static ConfigEntry<int> configMelodyCount;

	private static ConfigEntry<string> configMelodyPitches;

	public static SoundboardPlugin Instance { get; private set; }

	private void Awake()
	{
		//IL_0486: Unknown result type (might be due to invalid IL or missing references)
		//IL_048b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0491: Expected O, but got Unknown
		//IL_0446: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		configVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Soundboard", "Volume", 1f, "Default volume for soundboard.");
		configPitch = ((BaseUnityPlugin)this).Config.Bind<float>("Soundboard", "Pitch", 1f, "Default pitch for soundboard.");
		configLoop = ((BaseUnityPlugin)this).Config.Bind<bool>("Soundboard", "Loop", false, "Toggle if sounds should loop by default.");
		configFavourites = ((BaseUnityPlugin)this).Config.Bind<string>("Soundboard", "Favourites", "", "Comma-separated list of favourited sound names.");
		configQuickBoard = ((BaseUnityPlugin)this).Config.Bind<string>("Soundboard", "QuickBoard", "", "Sounds to show on screen.");
		configBass = ((BaseUnityPlugin)this).Config.Bind<float>("Soundboard", "BassBoost", 0f, "Default bass boost for soundboard.");
		CurrentBass = configBass.Value;
		if (!string.IsNullOrEmpty(configQuickBoard.Value))
		{
			configMelodyCount = ((BaseUnityPlugin)this).Config.Bind<int>("Soundboard", "Note Change Count", 0, (ConfigDescription)null);
		}
		configMelodyPitches = ((BaseUnityPlugin)this).Config.Bind<string>("Soundboard", "Note Pitches", "", (ConfigDescription)null);
		MelodyStepCount = configMelodyCount.Value;
		if (!string.IsNullOrEmpty(configMelodyPitches.Value))
		{
			MelodyPitches = configMelodyPitches.Value.Split(new char[1] { ',' }).Select(float.Parse).ToList();
		}
		quickBoardSounds = configQuickBoard.Value.Split(new char[1] { ',' }).ToList();
		CurrentVolume = configVolume.Value;
		CurrentPitch = configPitch.Value;
		IsLooping = configLoop.Value;
		if (!string.IsNullOrEmpty(configFavourites.Value))
		{
			favouriteSounds = configFavourites.Value.Split(new char[1] { ',' }).ToList();
		}
		string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		string[] files = Directory.GetFiles(directoryName);
		if (files.Length != 0)
		{
			string[] array = files;
			foreach (string text in array)
			{
				string text2 = Path.GetFileName(text).ToLower();
				if (text2.EndsWith(".dll") || text2.EndsWith(".repobundle") || text2.EndsWith(".hhh") || text2.EndsWith(".md") || text2.EndsWith(".png") || text2.EndsWith(".bundle") || text2.EndsWith(".ini") || text2.EndsWith(".json"))
				{
					continue;
				}
				AssetBundle val = AssetBundle.LoadFromFile(text);
				if (!((Object)(object)val != (Object)null))
				{
					continue;
				}
				string[] allAssetNames = val.GetAllAssetNames();
				foreach (string path in allAssetNames)
				{
					_loadedBundles[Path.GetFileNameWithoutExtension(path).ToUpper()] = val;
					string text3 = Path.GetFileNameWithoutExtension(path).ToUpper();
					if (text3.Contains("MYINSTANT") || text3.Contains("INSTANT"))
					{
						myInstantsSounds.Add(text3);
					}
					else if (text3.Contains("REPO") || text3.Contains("R E P O"))
					{
						repoSounds.Add(text3);
					}
					else if (text3.Contains("MEME"))
					{
						memeSounds.Add(text3);
					}
					else if (text3.StartsWith("MUSIC"))
					{
						musicSounds.Add(text3);
					}
					else
					{
						otherSounds.Add(text3);
					}
				}
			}
		}
		try
		{
			new Hook((MethodBase)AccessTools.Method(typeof(MenuPageMain), "Start", (Type[])null, (Type[])null), (Delegate)new Action<Action<MenuPageMain>, MenuPageMain>(MenuPageMain_StartHook));
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Menu hook failed: " + ex.Message));
		}
		object obj = <>c.<>9__32_0;
		if (obj == null)
		{
			BuilderDelegate val2 = delegate(Transform parent)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				MenuAPI.CreateREPOButton("Soundboard", (Action)CreateSoundboardMenu, parent, new Vector2(126f, 86f));
			};
			<>c.<>9__32_0 = val2;
			obj = (object)val2;
		}
		MenuAPI.AddElementToEscapeMenu((BuilderDelegate)obj);
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Singularity Soundboard loaded!");
	}

	private void Update()
	{
		if (Input.GetKeyDown((KeyCode)121))
		{
			ToggleQuickMenu();
		}
	}

	private void SaveConfig()
	{
		configVolume.Value = CurrentVolume;
		configPitch.Value = CurrentPitch;
		configLoop.Value = IsLooping;
		configFavourites.Value = string.Join(",", favouriteSounds);
		configQuickBoard.Value = string.Join(",", quickBoardSounds);
		configMelodyCount.Value = MelodyStepCount;
		configMelodyPitches.Value = string.Join(",", MelodyPitches);
	}

	[HarmonyPatch(typeof(PlayerVoiceChat), "Update")]
	[HarmonyPrefix]
	private static void VoiceChatUpdatePrefix(object __instance)
	{
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Expected O, but got Unknown
		if (!IsPlayingSound || __instance == null)
		{
			return;
		}
		object value = AccessTools.Field(typeof(PlayerVoiceChat), "photonView").GetValue(__instance);
		if (value == null || !(bool)AccessTools.Property(value.GetType(), "IsMine").GetValue(value))
		{
			return;
		}
		AudioSource val = (AudioSource)AccessTools.Field(typeof(PlayerVoiceChat), "audioSource").GetValue(__instance);
		if ((Object)(object)val != (Object)null)
		{
			val.pitch = CurrentPitch;
			val.loop = IsLooping;
		}
		object value2 = AccessTools.Field(typeof(PlayerVoiceChat), "recorder").GetValue(__instance);
		if (value2 != null)
		{
			Type type = value2.GetType();
			PropertyInfo property = type.GetProperty("Pitch");
			if (property != null)
			{
				property.SetValue(value2, CurrentPitch);
			}
			AccessTools.Property(type, "TransmitEnabled").SetValue(value2, true);
		}
		AccessTools.Field(typeof(PlayerVoiceChat), "isTalking").SetValue(__instance, true);
		AccessTools.Field(typeof(PlayerVoiceChat), "overrideMuteTimer").SetValue(__instance, 1f);
	}

	[HarmonyPatch(typeof(PlayerVoiceChat), "LateUpdate")]
	[HarmonyPostfix]
	private static void VoiceChatLateUpdatePostfix(object __instance)
	{
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Expected O, but got Unknown
		if (!IsPlayingSound || __instance == null)
		{
			return;
		}
		object value = AccessTools.Field(typeof(PlayerVoiceChat), "photonView").GetValue(__instance);
		if (value != null && (bool)AccessTools.Property(value.GetType(), "IsMine").GetValue(value))
		{
			object value2 = AccessTools.Field(typeof(PlayerVoiceChat), "playerAvatar").GetValue(__instance);
			bool flag = (bool)AccessTools.Property(value2.GetType(), "isDisabled").GetValue(value2);
			AudioSource val = (AudioSource)AccessTools.Field(typeof(PlayerVoiceChat), "audioSource").GetValue(__instance);
			if ((Object)(object)val != (Object)null && val.isPlaying && flag)
			{
				val.volume = 0.5f;
			}
		}
	}

	public static void PlayAudioClip(AudioClip clip)
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Expected O, but got Unknown
		if ((Object)(object)clip == (Object)null)
		{
			return;
		}
		PlayerAvatar val = GameDirector.instance?.PlayerList?.FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => (Object)(object)p.photonView == (Object)null || p.photonView.IsMine));
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		object obj = typeof(PlayerAvatar).GetField("voiceChat", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val);
		if (obj == null)
		{
			return;
		}
		AudioSource val2 = (AudioSource)AccessTools.Field(typeof(PlayerVoiceChat), "audioSource").GetValue(obj);
		object value = AccessTools.Field(typeof(PlayerVoiceChat), "recorder").GetValue(obj);
		if (!((Object)(object)val2 == (Object)null) && value != null)
		{
			StopPlayback();
			if (IsLooping && MelodyStepCount > 0 && MelodyPitches.Count > 0)
			{
				CurrentPitch = MelodyPitches[_currentMelodyIndex];
				_currentMelodyIndex = (_currentMelodyIndex + 1) % MelodyStepCount;
			}
			else
			{
				_currentMelodyIndex = 0;
			}
			AudioClip clip2 = CreatePitchedAndResampledClip(clip, CurrentPitch, clip.frequency);
			AudioClip value2 = CreatePitchedAndResampledClip(clip, CurrentPitch, 48000);
			val2.Stop();
			val2.clip = clip2;
			val2.loop = IsLooping;
			val2.pitch = 1f;
			val2.spatialBlend = 0f;
			val2.Play();
			Type type = value.GetType();
			type.GetMethod("StopRecording")?.Invoke(value, null);
			AccessTools.Property(type, "SourceType").SetValue(value, 1);
			AccessTools.Property(type, "AudioClip").SetValue(value, value2);
			AccessTools.Property(type, "SamplingRate").SetValue(value, 48000);
			AccessTools.Property(type, "TransmitEnabled").SetValue(value, true);
			PropertyInfo property = type.GetProperty("Loop");
			if (property != null)
			{
				property.SetValue(value, IsLooping);
			}
			type.GetMethod("StartRecording")?.Invoke(value, null);
			SetupLocalSource(val);
			if ((Object)(object)_localHearSelfSource != (Object)null)
			{
				_localHearSelfSource.clip = clip2;
				_localHearSelfSource.pitch = 1f;
				_localHearSelfSource.volume = CurrentVolume;
				_localHearSelfSource.loop = IsLooping;
				_localHearSelfSource.Play();
			}
			IsPlayingSound = true;
			((MonoBehaviour)Instance).StartCoroutine(MonitorPlayback(val2, clip2, value));
		}
	}

	private static AudioClip CreatePitchedAndResampledClip(AudioClip input, float pitch, int targetFreq)
	{
		float[] array = new float[input.samples * input.channels];
		input.GetData(array, 0);
		int num = Mathf.RoundToInt((float)input.samples * ((float)targetFreq / (float)input.frequency) / pitch);
		float[] array2 = new float[num];
		float num2 = 0f;
		float num3 = 0f;
		float num4 = 0f;
		float num5 = 0f;
		float num6 = 100f;
		float num7 = 0.8f;
		float num8 = CurrentBass * 30f;
		float num9 = Mathf.Pow(10f, num8 / 40f);
		float num10 = (float)Math.PI * 2f * num6 / (float)targetFreq;
		float num11 = Mathf.Sin(num10);
		float num12 = Mathf.Cos(num10);
		float num13 = num11 / (2f * num7);
		float num14 = Mathf.Sqrt(num9) * 2f * num13;
		float num15 = num9 * (num9 + 1f - (num9 - 1f) * num12 + num14);
		float num16 = 2f * num9 * (num9 - 1f - (num9 + 1f) * num12);
		float num17 = num9 * (num9 + 1f - (num9 - 1f) * num12 - num14);
		float num18 = num9 + 1f + (num9 - 1f) * num12 + num14;
		float num19 = -2f * (num9 - 1f + (num9 + 1f) * num12);
		float num20 = num9 + 1f + (num9 - 1f) * num12 - num14;
		for (int i = 0; i < num; i++)
		{
			float num21 = (float)i * ((float)input.frequency / (float)targetFreq) * pitch;
			int num22 = (int)num21;
			int num23 = num22 + 1;
			float num24 = 0f;
			if (num22 < input.samples - 1)
			{
				float num25 = num21 - (float)num22;
				num24 = ((input.channels != 2) ? Mathf.Lerp(array[num22], array[num23], num25) : ((Mathf.Lerp(array[num22 * 2], array[num23 * 2], num25) + Mathf.Lerp(array[num22 * 2 + 1], array[num23 * 2 + 1], num25)) / 2f));
			}
			float num26 = num15 / num18 * num24 + num16 / num18 * num2 + num17 / num18 * num3 - num19 / num18 * num4 - num20 / num18 * num5;
			num3 = num2;
			num2 = num24;
			num5 = num4;
			num4 = num26;
			float num27 = (float)Math.Tanh(num26 * 0.9f);
			array2[i] = num27;
		}
		AudioClip val = AudioClip.Create(((Object)input).name + "_MegaBass", num, 1, targetFreq, false);
		val.SetData(array2, 0);
		return val;
	}

	private static AudioClip MakeMono(AudioClip stereoClip)
	{
		if (stereoClip.channels == 1)
		{
			return stereoClip;
		}
		float[] array = new float[stereoClip.samples * stereoClip.channels];
		stereoClip.GetData(array, 0);
		float[] array2 = new float[stereoClip.samples];
		for (int i = 0; i < array2.Length; i++)
		{
			array2[i] = (array[i * 2] + array[i * 2 + 1]) / 2f;
		}
		AudioClip val = AudioClip.Create(((Object)stereoClip).name + "_Mono", stereoClip.samples, 1, stereoClip.frequency, false);
		val.SetData(array2, 0);
		return val;
	}

	private static void SetupLocalSource(PlayerAvatar player)
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Expected O, but got Unknown
		if (!((Object)(object)_localHearSelfSource != (Object)null) || !((Object)(object)((Component)_localHearSelfSource).transform.parent == (Object)(object)((Component)player).transform))
		{
			if ((Object)(object)_localHearSelfSource != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_localHearSelfSource).gameObject);
			}
			GameObject val = new GameObject("SoundboardLocalOnly");
			val.transform.SetParent(((Component)player).transform, false);
			_localHearSelfSource = val.AddComponent<AudioSource>();
			_localHearSelfSource.spatialBlend = 0f;
			_localHearSelfSource.playOnAwake = false;
			_localHearSelfSource.volume = CurrentVolume;
			_localHearSelfSource.outputAudioMixerGroup = null;
		}
	}

	[IteratorStateMachine(typeof(<MonitorPlayback>d__41))]
	private static IEnumerator MonitorPlayback(AudioSource source, AudioClip clip, object recorder)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <MonitorPlayback>d__41(0)
		{
			source = source,
			clip = clip,
			recorder = recorder
		};
	}

	private static AudioClip GetOriginalClip(AudioClip bakedClip)
	{
		string text = ((Object)bakedClip).name.Replace("_MegaBass", "").Replace("_Modified", "").ToUpper();
		if (_loadedBundles.TryGetValue(text, out var value))
		{
			return value.LoadAsset<AudioClip>(text);
		}
		return null;
	}

	public static void StopPlayback()
	{
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected O, but got Unknown
		if ((Object)(object)_localHearSelfSource != (Object)null)
		{
			_localHearSelfSource.Stop();
		}
		PlayerAvatar val = GameDirector.instance?.PlayerList?.FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => (Object)(object)p.photonView == (Object)null || p.photonView.IsMine));
		if ((Object)(object)val != (Object)null)
		{
			object obj = typeof(PlayerAvatar).GetField("voiceChat", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val);
			AudioSource val2 = (AudioSource)AccessTools.Field(typeof(PlayerVoiceChat), "audioSource").GetValue(obj);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.Stop();
			}
		}
		IsPlayingSound = false;
		((MonoBehaviour)Instance).StopAllCoroutines();
	}

	private static void MenuPageMain_StartHook(Action<MenuPageMain> orig, MenuPageMain self)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		REPOButton val = MenuAPI.CreateREPOButton("Soundboard", (Action)CreateSoundboardMenu, ((Component)self).transform, new Vector2(48.3f, 0f));
		List<Transform> list = (from Transform t in (IEnumerable)((Component)self).transform
			where ((Object)t).name.Contains("Menu Button")
			orderby t.localPosition.y descending
			select t).ToList();
		list.Insert(list.Count - 1, ((Component)val).transform);
		float num = 224f;
		foreach (Transform item in list)
		{
			item.localPosition = new Vector3(item.localPosition.x, num, item.localPosition.z);
			num -= 30f;
		}
		orig(self);
	}

	internal static void CreateSoundboardMenu()
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Expected O, but got Unknown
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Expected O, but got Unknown
		REPOPopupPage soundboardPage = MenuAPI.CreateREPOPopupPage("SOUNDBOARD", (PresetSide)0, false, true, 0f);
		soundboardPage.scrollView.scrollSpeed = 3f;
		soundboardPage.maskPadding = new Padding(0f, 35f, 0f, 25f);
		AddGlobalControls(soundboardPage);
		if (favouriteSounds.Count > 0)
		{
			AddCategory(soundboardPage, "FAVOURITES", favouriteSounds, isFavourite: true);
		}
		if (repoSounds.Count > 0)
		{
			AddCategory(soundboardPage, "REPO SFX", repoSounds);
		}
		if (memeSounds.Count > 0)
		{
			AddCategory(soundboardPage, "MEMES", memeSounds);
		}
		if (myInstantsSounds.Count > 0)
		{
			AddCategory(soundboardPage, "MYINSTANTS", myInstantsSounds);
		}
		if (otherSounds.Count > 0)
		{
			AddCategory(soundboardPage, "OTHER", otherSounds);
		}
		if (musicSounds.Count > 0)
		{
			AddCategory(soundboardPage, "MUSIC", musicSounds);
		}
		soundboardPage.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("Show On Screen", (Action)delegate
		{
			soundboardPage.ClosePage(true);
			ToggleQuickMenu();
		}, scrollView, Vector2.zero)).rectTransform), 0f, 0f);
		soundboardPage.AddElement((BuilderDelegate)delegate(Transform p)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			MenuAPI.CreateREPOButton("Back", (Action)delegate
			{
				soundboardPage.ClosePage(true);
			}, p, new Vector2(66f, 18f));
		});
		soundboardPage.OpenPage(false);
	}

	private static void AddGlobalControls(REPOPopupPage page)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Expected O, but got Unknown
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Expected O, but got Unknown
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Expected O, but got Unknown
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Expected O, but got Unknown
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Expected O, but got Unknown
		REPOPopupPage obj = page;
		object obj2 = <>c.<>9__46_0;
		if (obj2 == null)
		{
			ScrollViewBuilderDelegate val2 = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOSlider("Volume", "Loudness", (Action<float>)delegate(float v)
			{
				CurrentVolume = v;
				if ((Object)(object)_localHearSelfSource != (Object)null)
				{
					_localHearSelfSource.volume = v;
				}
				Instance.SaveConfig();
			}, scrollView, Vector2.zero, 0f, 2f, 1, CurrentVolume, "", "", (BarBehavior)0)).rectTransform;
			<>c.<>9__46_0 = val2;
			obj2 = (object)val2;
		}
		obj.AddElementToScrollView((ScrollViewBuilderDelegate)obj2, 0f, 0f);
		page.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOInputField("MELODY STEPS", (Action<string>)delegate(string val)
		{
			if (int.TryParse(val, out var result))
			{
				MelodyStepCount = Mathf.Clamp(result, 0, 20);
				while (MelodyPitches.Count < MelodyStepCount)
				{
					MelodyPitches.Add(CurrentPitch);
				}
				Instance.SaveConfig();
				page.ClosePage(true);
				CreateSoundboardMenu();
			}
		}, scrollView, Vector2.zero, false, "0 = Off", MelodyStepCount.ToString())).rectTransform), 0f, 0f);
		for (int i = 0; i < MelodyStepCount; i++)
		{
			int index = i;
			page.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOSlider($"Note {index + 1}", "Pitch", (Action<float>)delegate(float p)
			{
				MelodyPitches[index] = p;
				Instance.SaveConfig();
			}, scrollView, Vector2.zero, 0.1f, 3f, 1, MelodyPitches[index], "", "", (BarBehavior)0)).rectTransform), 0f, 0f);
		}
		REPOPopupPage obj3 = page;
		object obj4 = <>c.<>9__46_2;
		if (obj4 == null)
		{
			ScrollViewBuilderDelegate val3 = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOSlider("Pitch", "Deepness", (Action<float>)delegate(float p)
			{
				CurrentPitch = p;
				if ((Object)(object)_localHearSelfSource != (Object)null)
				{
					_localHearSelfSource.pitch = p;
				}
				Instance.SaveConfig();
			}, scrollView, Vector2.zero, 0.1f, 3f, 1, CurrentPitch, "", "", (BarBehavior)0)).rectTransform;
			<>c.<>9__46_2 = val3;
			obj4 = (object)val3;
		}
		obj3.AddElementToScrollView((ScrollViewBuilderDelegate)obj4, 0f, 0f);
		REPOPopupPage obj5 = page;
		object obj6 = <>c.<>9__46_3;
		if (obj6 == null)
		{
			ScrollViewBuilderDelegate val4 = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOSlider("Bass", "Thick", (Action<float>)delegate(float b)
			{
				CurrentBass = b;
				Instance.SaveConfig();
			}, scrollView, Vector2.zero, 0f, 1f, 1, CurrentBass, "", "", (BarBehavior)0)).rectTransform;
			<>c.<>9__46_3 = val4;
			obj6 = (object)val4;
		}
		obj5.AddElementToScrollView((ScrollViewBuilderDelegate)obj6, 0f, 0f);
		REPOPopupPage obj7 = page;
		object obj8 = <>c.<>9__46_4;
		if (obj8 == null)
		{
			ScrollViewBuilderDelegate val5 = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOToggle("Loop Mode", (Action<bool>)delegate(bool l)
			{
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Expected O, but got Unknown
				IsLooping = l;
				if ((Object)(object)_localHearSelfSource != (Object)null)
				{
					_localHearSelfSource.loop = l;
				}
				PlayerAvatar val6 = GameDirector.instance?.PlayerList?.FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => (Object)(object)p.photonView == (Object)null || p.photonView.IsMine));
				if ((Object)(object)val6 != (Object)null)
				{
					object obj9 = typeof(PlayerAvatar).GetField("voiceChat", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val6);
					if (obj9 != null)
					{
						AudioSource val7 = (AudioSource)AccessTools.Field(typeof(PlayerVoiceChat), "audioSource").GetValue(obj9);
						if ((Object)(object)val7 != (Object)null)
						{
							val7.loop = l;
						}
					}
				}
				Instance.SaveConfig();
			}, scrollView, Vector2.zero, "ON", "OFF", IsLooping)).rectTransform;
			<>c.<>9__46_4 = val5;
			obj8 = (object)val5;
		}
		obj7.AddElementToScrollView((ScrollViewBuilderDelegate)obj8, 0f, 0f);
	}

	private static void RefreshQuickLayout()
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_quickMenuPage == (Object)null))
		{
			Canvas.ForceUpdateCanvases();
			((Component)_quickMenuPage).gameObject.SetActive(true);
			CanvasGroup component = ((Component)_quickMenuPage).GetComponent<CanvasGroup>();
			if ((Object)(object)component != (Object)null)
			{
				component.alpha = 1f;
				component.interactable = true;
				component.blocksRaycasts = true;
			}
			((Component)_quickMenuPage).transform.localScale = Vector3.one;
			VerticalLayoutGroup componentInChildren = ((Component)_quickMenuPage.scrollView).GetComponentInChildren<VerticalLayoutGroup>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((LayoutGroup)componentInChildren).CalculateLayoutInputVertical();
				((LayoutGroup)componentInChildren).SetLayoutVertical();
				LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)componentInChildren).GetComponent<RectTransform>());
			}
		}
	}

	private static void ToggleQuickMenu()
	{
		//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_00a8: Expected O, but got Unknown
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Expected O, but got Unknown
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Expected O, but got Unknown
		if ((Object)(object)_quickMenuPage != (Object)null)
		{
			_quickMenuPage.ClosePage(false);
			Object.Destroy((Object)(object)((Component)_quickMenuPage).gameObject);
			_quickMenuPage = null;
			Cursor.visible = false;
			Cursor.lockState = (CursorLockMode)1;
			return;
		}
		Cursor.visible = true;
		Cursor.lockState = (CursorLockMode)0;
		_quickMenuPage = MenuAPI.CreateREPOPopupPage("Quick Board", (PresetSide)1, false, false, 5f);
		_quickMenuPage.scrollView.scrollSpeed = 3f;
		REPOPopupPage quickMenuPage = _quickMenuPage;
		object obj = <>c.<>9__48_0;
		if (obj == null)
		{
			ScrollViewBuilderDelegate val = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("\ud83d\udd04 REFRESH LAYOUT", (Action)RefreshQuickLayout, scrollView, Vector2.zero)).rectTransform;
			<>c.<>9__48_0 = val;
			obj = (object)val;
		}
		quickMenuPage.AddElementToScrollView((ScrollViewBuilderDelegate)obj, 0f, 10f);
		REPOPopupPage quickMenuPage2 = _quickMenuPage;
		object obj2 = <>c.<>9__48_1;
		if (obj2 == null)
		{
			ScrollViewBuilderDelegate val2 = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOButton("STOP ALL", (Action)StopPlayback, scrollView, Vector2.zero)).rectTransform;
			<>c.<>9__48_1 = val2;
			obj2 = (object)val2;
		}
		quickMenuPage2.AddElementToScrollView((ScrollViewBuilderDelegate)obj2, 0f, 10f);
		foreach (string audioToPlay in quickBoardSounds)
		{
			string cleanName = audioToPlay.Replace("REPO", "").Replace("MEME", "").Replace("_", " ")
				.Trim();
			_quickMenuPage.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				REPOButton val3 = MenuAPI.CreateREPOButton(cleanName, (Action)delegate
				{
					PlayAudio(audioToPlay);
				}, scrollView, Vector2.zero);
				RectTransform rectTransform = ((REPOElement)val3).rectTransform;
				rectTransform.sizeDelta = new Vector2(200f, 35f);
				((TMP_Text)val3.labelTMP).fontSize = 14f;
				return rectTransform;
			}, 0f, 5f);
		}
		_quickMenuPage.OpenPage(false);
		RefreshQuickLayout();
	}

	private static void AddCategory(REPOPopupPage mainPage, string folderName, List<string> soundList, bool isFavourite = false)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		mainPage.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			REPOButton val = MenuAPI.CreateREPOButton(folderName, (Action)delegate
			{
				OpenFolder(folderName, soundList, isFavourite);
			}, scrollView, Vector2.zero);
			((TMP_Text)val.labelTMP).fontStyle = (FontStyles)0;
			return ((REPOElement)val).rectTransform;
		}, 0f, 0f);
	}

	[HarmonyPatch(typeof(PlayerVoiceChat), "Update")]
	[HarmonyPostfix]
	private static void SyncRemotePitch(PlayerVoiceChat __instance)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		AudioSource val = (AudioSource)AccessTools.Field(typeof(PlayerVoiceChat), "audioSource").GetValue(__instance);
		if ((Object)(object)val != (Object)null && IsPlayingSound)
		{
			val.pitch = CurrentPitch;
			val.loop = IsLooping;
		}
	}

	private static void OpenFolder(string title, List<string> sounds, bool isFavouriteCategory = false)
	{
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Expected O, but got Unknown
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Expected O, but got Unknown
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Expected O, but got Unknown
		MenuAPI.CloseAllPagesAddedOnTop();
		REPOPopupPage folderPage = MenuAPI.CreateREPOPopupPage(title, (PresetSide)1, false, false, 5f);
		folderPage.scrollView.scrollSpeed = 3f;
		REPOPopupPage obj = folderPage;
		object obj2 = <>c.<>9__51_0;
		if (obj2 == null)
		{
			ScrollViewBuilderDelegate val2 = delegate(Transform scrollView)
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				REPOInputField val6 = MenuAPI.CreateREPOInputField("SEARCH SFX", (Action<string>)delegate(string val)
				{
					currentSearchFilter = val.ToLower().Trim();
				}, scrollView, Vector2.zero, false, "Type here...", currentSearchFilter);
				return ((REPOElement)val6).rectTransform;
			};
			<>c.<>9__51_0 = val2;
			obj2 = (object)val2;
		}
		obj.AddElementToScrollView((ScrollViewBuilderDelegate)obj2, 0f, 15f);
		foreach (string sound in sounds)
		{
			string audioToPlay = sound;
			string cleanName = sound.Replace("REPO", "").Replace("MEME", "").Replace("_", " ")
				.Trim();
			bool isFav = favouriteSounds.Contains(sound);
			if (!string.IsNullOrEmpty(currentSearchFilter) && !cleanName.ToLower().Contains(currentSearchFilter))
			{
				continue;
			}
			folderPage.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0150: Unknown result type (might be due to invalid IL or missing references)
				//IL_0149: Unknown result type (might be due to invalid IL or missing references)
				//IL_0196: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0227: 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_01fb: Unknown result type (might be due to invalid IL or missing references)
				REPOButton val3 = MenuAPI.CreateREPOButton(cleanName, (Action)delegate
				{
					PlayAudio(audioToPlay);
				}, scrollView, new Vector2(20f, 0f));
				RectTransform rectTransform = ((REPOElement)val3).rectTransform;
				rectTransform.sizeDelta = new Vector2(150f, 28f);
				TMP_Text labelTMP = (TMP_Text)(object)val3.labelTMP;
				labelTMP.fontSize = 15f;
				labelTMP.alignment = (TextAlignmentOptions)513;
				labelTMP.rectTransform.offsetMin = new Vector2(5f, 0f);
				string text = (isFavouriteCategory ? "UNFAV" : (isFav ? "★" : "☆"));
				REPOButton val4 = MenuAPI.CreateREPOButton(text, (Action)delegate
				{
					if (favouriteSounds.Contains(audioToPlay))
					{
						favouriteSounds.Remove(audioToPlay);
					}
					else
					{
						favouriteSounds.Add(audioToPlay);
					}
					Instance.SaveConfig();
					folderPage.ClosePage(false);
					OpenFolder(title, sounds, isFavouriteCategory);
				}, ((Component)rectTransform).transform, new Vector2(95f, 0f));
				val4.overrideButtonSize = new Vector2(isFavouriteCategory ? 45f : 25f, 25f);
				((Graphic)val4.labelTMP).color = (isFav ? Color.yellow : Color.white);
				((TMP_Text)val4.labelTMP).fontSize = 12f;
				REPOButton showBtn = null;
				showBtn = MenuAPI.CreateREPOButton("SHOW", (Action)delegate
				{
					//IL_005a: Unknown result type (might be due to invalid IL or missing references)
					if (!quickBoardSounds.Contains(audioToPlay))
					{
						quickBoardSounds.Add(audioToPlay);
						Instance.SaveConfig();
						if ((Object)(object)showBtn != (Object)null)
						{
							((Graphic)showBtn.labelTMP).color = Color.green;
						}
					}
				}, ((Component)rectTransform).transform, new Vector2(135f, 0f));
				showBtn.overrideButtonSize = new Vector2(40f, 25f);
				((TMP_Text)showBtn.labelTMP).fontSize = 10f;
				if (quickBoardSounds.Contains(audioToPlay))
				{
					((Graphic)showBtn.labelTMP).color = Color.green;
				}
				REPOButton val5 = MenuAPI.CreateREPOButton("HIDE", (Action)delegate
				{
					//IL_0057: Unknown result type (might be due to invalid IL or missing references)
					if (quickBoardSounds.Contains(audioToPlay))
					{
						quickBoardSounds.Remove(audioToPlay);
						Instance.SaveConfig();
						if ((Object)(object)showBtn != (Object)null)
						{
							((Graphic)showBtn.labelTMP).color = Color.white;
						}
					}
				}, ((Component)rectTransform).transform, new Vector2(175f, 0f));
				val5.overrideButtonSize = new Vector2(40f, 25f);
				((TMP_Text)val5.labelTMP).fontSize = 10f;
				return rectTransform;
			}, 0f, 4f);
		}
		folderPage.AddElement((BuilderDelegate)delegate(Transform p)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			MenuAPI.CreateREPOButton("Back", (Action)delegate
			{
				folderPage.ClosePage(true);
				CreateSoundboardMenu();
			}, p, new Vector2(66f, 18f));
		});
		folderPage.OpenPage(true);
	}

	private static void PlayAudio(string assetName)
	{
		if (!_loadedBundles.ContainsKey(assetName))
		{
			((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Sound not found: " + assetName));
			return;
		}
		StopPlayback();
		AudioClip val = _loadedBundles[assetName].LoadAsset<AudioClip>(assetName);
		if ((Object)(object)val != (Object)null)
		{
			PlayAudioClip(val);
		}
		else
		{
			((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Could not load audio: " + assetName));
		}
	}
}