Decompiled source of MelaniesVoice v1.7.1

com.github.zehsteam.MelaniesVoice.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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 System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalConfig.Mods;
using Microsoft.CodeAnalysis;
using Mirage.Domain.Audio;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Networking;
using com.github.zehsteam.MelaniesVoice.Dependencies;
using com.github.zehsteam.MelaniesVoice.Extensions;
using com.github.zehsteam.MelaniesVoice.Helpers;
using com.github.zehsteam.MelaniesVoice.Managers;
using com.github.zehsteam.MelaniesVoice.MonoBehaviours;
using com.github.zehsteam.MelaniesVoice.NetcodePatcher;
using com.github.zehsteam.MelaniesVoice.Objects;
using com.github.zehsteam.MelaniesVoice.Objects.Config;
using com.github.zehsteam.MelaniesVoice.Objects.Voices;
using com.github.zehsteam.MelaniesVoice.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("LethalConfig")]
[assembly: IgnoresAccessChecksTo("Mirage")]
[assembly: IgnoresAccessChecksTo("Mirage.Plugin")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.zehsteam.MelaniesVoice")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2025 Zehs")]
[assembly: AssemblyDescription("[v73+] Allows players to talk through Text-To-Speech (TTS) by using the in-game chat.")]
[assembly: AssemblyFileVersion("1.7.1.0")]
[assembly: AssemblyInformationalVersion("1.7.1+8c4053cd6b7ff3035525326c94660163e55ec054")]
[assembly: AssemblyProduct("MelaniesVoice")]
[assembly: AssemblyTitle("com.github.zehsteam.MelaniesVoice")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 com.github.zehsteam.MelaniesVoice
{
	internal static class Assets
	{
		public static AssetBundle AssetBundle { get; private set; }

		public static GameObject VoiceControllerPrefab { get; private set; }

		public static void Load()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = "melaniesvoice_assets";
			string text2 = Path.Combine(directoryName, text);
			if (!File.Exists(text2))
			{
				Logger.LogFatal("Failed to load assets. AssetBundle file could not be found at path \"" + text2 + "\". Make sure the \"" + text + "\" file is in the same folder as the mod's DLL file.");
			}
			else
			{
				AssetBundle val = AssetBundle.LoadFromFile(text2);
				if ((Object)(object)val == (Object)null)
				{
					Logger.LogFatal("Failed to load assets. AssetBundle is null.");
				}
				else
				{
					OnAssetBundleLoaded(val);
				}
			}
		}

		private static void OnAssetBundleLoaded(AssetBundle assetBundle)
		{
			AssetBundle = assetBundle;
			VoiceControllerPrefab = LoadAsset<GameObject>("VoiceController", assetBundle);
		}

		private static T LoadAsset<T>(string name, AssetBundle assetBundle) where T : Object
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace.");
				return default(T);
			}
			if ((Object)(object)assetBundle == (Object)null)
			{
				Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null.");
				return default(T);
			}
			T val = assetBundle.LoadAsset<T>(name);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name.");
				return default(T);
			}
			return val;
		}

		private static bool TryLoadAsset<T>(string name, AssetBundle assetBundle, out T asset) where T : Object
		{
			asset = LoadAsset<T>(name, assetBundle);
			return (Object)(object)asset != (Object)null;
		}
	}
	internal static class Utils
	{
		[CompilerGenerated]
		private sealed class <WaitForTask>d__4<T> : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Task<T> task;

			public Action<T> result;

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

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

			[DebuggerHidden]
			public <WaitForTask>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;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!task.IsCompleted)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if (task.IsFaulted)
				{
					throw task.Exception;
				}
				result?.Invoke(task.Result);
				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();
			}
		}

		public static string GetPluginPersistentDataPath()
		{
			return Path.Combine(Application.persistentDataPath, "MelaniesVoice");
		}

		public static ConfigFile CreateConfigFile(BaseUnityPlugin plugin, string path, string name = null, bool saveOnInit = false)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			BepInPlugin metadata = MetadataHelper.GetMetadata((object)plugin);
			if (name == null)
			{
				name = metadata.GUID;
			}
			name += ".cfg";
			return new ConfigFile(Path.Combine(path, name), saveOnInit, metadata);
		}

		public static ConfigFile CreateLocalConfigFile(BaseUnityPlugin plugin, string name = null, bool saveOnInit = false)
		{
			return CreateConfigFile(plugin, Paths.ConfigPath, name, saveOnInit);
		}

		public static ConfigFile CreateGlobalConfigFile(BaseUnityPlugin plugin, string name = null, bool saveOnInit = false)
		{
			string pluginPersistentDataPath = GetPluginPersistentDataPath();
			if (name == null)
			{
				name = "global";
			}
			return CreateConfigFile(plugin, pluginPersistentDataPath, name, saveOnInit);
		}

		[IteratorStateMachine(typeof(<WaitForTask>d__4<>))]
		public static IEnumerator WaitForTask<T>(Task<T> task, Action<T> result)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForTask>d__4<T>(0)
			{
				task = task,
				result = result
			};
		}

		public static string SanitizeFileName(string input)
		{
			char[] invalidChars = Path.GetInvalidFileNameChars();
			return string.Concat(input.Where((char c) => !invalidChars.Contains(c)));
		}

		public static void DisplayMessage(string text, bool isError = false)
		{
			string text2 = "MelaniesVoice";
			if (isError)
			{
				text2 += " - ERROR";
			}
			HUDManager instance = HUDManager.Instance;
			if (instance != null)
			{
				instance.DisplayTip(text2, text, isError, false, "LC_Tip1");
			}
		}
	}
	internal static class Logger
	{
		public static ManualLogSource ManualLogSource { get; private set; }

		public static void Initialize(ManualLogSource manualLogSource)
		{
			ManualLogSource = manualLogSource;
		}

		public static void LogDebug(object data, bool extended = false)
		{
			Log((LogLevel)32, data, extended);
		}

		public static void LogInfo(object data, bool extended = false)
		{
			Log((LogLevel)16, data, extended);
		}

		public static void LogMessage(object data, bool extended = false)
		{
			Log((LogLevel)8, data, extended);
		}

		public static void LogWarning(object data, bool extended = false)
		{
			Log((LogLevel)4, data, extended);
		}

		public static void LogError(object data, bool extended = false)
		{
			Log((LogLevel)2, data, extended);
		}

		public static void LogFatal(object data, bool extended = false)
		{
			Log((LogLevel)1, data, extended);
		}

		public static void Log(LogLevel logLevel, object data, bool extended = false)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!extended || IsExtendedLoggingEnabled())
			{
				ManualLogSource manualLogSource = ManualLogSource;
				if (manualLogSource != null)
				{
					manualLogSource.Log(logLevel, data);
				}
			}
		}

		public static bool IsExtendedLoggingEnabled()
		{
			if (ConfigManager.ExtendedLogging == null)
			{
				return false;
			}
			return ConfigManager.ExtendedLogging.Value;
		}
	}
	[BepInPlugin("com.github.zehsteam.MelaniesVoice", "MelaniesVoice", "1.7.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("com.github.zehsteam.MelaniesVoice");

		public static Plugin Instance { get; private set; }

		public ConfigFile Config { get; private set; }

		private void Awake()
		{
			Instance = this;
			Logger.Initialize(Logger.CreateLogSource("com.github.zehsteam.MelaniesVoice"));
			Logger.LogInfo("MelaniesVoice has awoken!");
			Config = Utils.CreateGlobalConfigFile((BaseUnityPlugin)(object)this);
			_harmony.PatchAll(typeof(GameNetworkManagerPatch));
			_harmony.PatchAll(typeof(StartOfRoundPatch));
			_harmony.PatchAll(typeof(HUDManagerPatch));
			_harmony.PatchAll(typeof(PlayerControllerBPatch));
			Assets.Load();
			ConfigManager.Initialize(Config);
			NetcodePatcherAwake();
		}

		private void NetcodePatcherAwake()
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				Type[] types = executingAssembly.GetTypes();
				Type[] array = types;
				foreach (Type type in array)
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					MethodInfo[] array2 = methods;
					foreach (MethodInfo methodInfo in array2)
					{
						try
						{
							object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
							if (customAttributes.Length != 0)
							{
								try
								{
									methodInfo.Invoke(null, null);
								}
								catch (TargetInvocationException ex)
								{
									((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to invoke method " + methodInfo.Name + ": " + ex.Message));
								}
							}
						}
						catch (Exception ex2)
						{
							((BaseUnityPlugin)this).Logger.LogWarning((object)("Error processing method " + methodInfo.Name + " in type " + type.Name + ": " + ex2.Message));
						}
					}
				}
			}
			catch (Exception ex3)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("An error occurred in NetcodePatcherAwake: " + ex3.Message));
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.zehsteam.MelaniesVoice";

		public const string PLUGIN_NAME = "MelaniesVoice";

		public const string PLUGIN_VERSION = "1.7.1";
	}
}
namespace com.github.zehsteam.MelaniesVoice.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal static class GameNetworkManagerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch()
		{
			AddNetworkPrefabs();
			TTSVoice_TTSMonster.FetchVoices();
		}

		private static void AddNetworkPrefabs()
		{
			AddNetworkPrefab(Assets.VoiceControllerPrefab);
		}

		private static void AddNetworkPrefab(GameObject prefab)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				Logger.LogError("Failed to register network prefab. GameObject is null.");
				return;
			}
			NetworkManager.Singleton.AddNetworkPrefab(prefab);
			Logger.LogInfo("Registered \"" + ((Object)prefab).name + "\" network prefab.");
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	internal static class HUDManagerPatch
	{
		[HarmonyPatch("AddTextToChatOnServer")]
		[HarmonyPostfix]
		private static void AddTextToChatOnServerPatch(string chatMessage, int playerId)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (playerId == -1 || ConfigManager.TTS_DisableMyVoice.Value || chatMessage.StartsWithAny(ConfigManager.TTS_IgnorePefixesArray))
			{
				return;
			}
			PlayerControllerB localPlayerScript = PlayerUtils.GetLocalPlayerScript();
			if (!((Object)(object)localPlayerScript == (Object)null))
			{
				VoiceController componentInChildren = ((Component)localPlayerScript).GetComponentInChildren<VoiceController>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					componentInChildren.CreateVoiceMessage_ServerRpc(ConfigManager.TTS_Voice.Value, chatMessage);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerBPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch(PlayerControllerB __instance)
		{
			if (NetworkUtils.IsServer)
			{
				GameObject val = Object.Instantiate<GameObject>(Assets.VoiceControllerPrefab, ((Component)__instance).transform);
				NetworkObject component = val.GetComponent<NetworkObject>();
				component.DontDestroyWithOwner = true;
				component.SpawnWithOwnership(__instance.actualClientId, false);
				component.TrySetParent(((Component)__instance).transform, true);
			}
		}

		[HarmonyPatch("OnDestroy")]
		[HarmonyPrefix]
		private static void OnDestroyPatch(PlayerControllerB __instance)
		{
			if (NetworkUtils.IsServer)
			{
				VoiceController componentInChildren = ((Component)__instance).GetComponentInChildren<VoiceController>();
				NetworkObject val = default(NetworkObject);
				if (!((Object)(object)componentInChildren == (Object)null) && ((Component)componentInChildren).TryGetComponent<NetworkObject>(ref val) && val.IsSpawned)
				{
					val.Despawn(true);
				}
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal static class StartOfRoundPatch
	{
		[HarmonyPatch("OnClientConnect")]
		[HarmonyPostfix]
		private static void OnClientConnectPatch(ulong clientId)
		{
			PlayerControllerB playerScriptByClientId = PlayerUtils.GetPlayerScriptByClientId(clientId);
			if (!((Object)(object)playerScriptByClientId == (Object)null))
			{
				VoiceController componentInChildren = ((Component)playerScriptByClientId).GetComponentInChildren<VoiceController>();
				NetworkObject val = default(NetworkObject);
				if (!((Object)(object)componentInChildren == (Object)null) && ((Component)componentInChildren).TryGetComponent<NetworkObject>(ref val) && val.IsSpawned)
				{
					val.ChangeOwnership(playerScriptByClientId.actualClientId);
				}
			}
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Objects
{
	public class PlayerAudioGroup
	{
		public AudioSource VoiceAudio { get; private set; }

		public AudioSource DeadAudio { get; private set; }

		public bool IsPlaying => VoiceAudio.isPlaying;

		public float Volume
		{
			get
			{
				return VoiceAudio.volume;
			}
			set
			{
				VoiceAudio.volume = value;
				DeadAudio.volume = value;
			}
		}

		public float MaxDistance
		{
			get
			{
				return VoiceAudio.maxDistance;
			}
			set
			{
				VoiceAudio.maxDistance = value;
				DeadAudio.maxDistance = value;
			}
		}

		public AudioClip Clip
		{
			get
			{
				return VoiceAudio.clip;
			}
			set
			{
				VoiceAudio.clip = value;
				DeadAudio.clip = value;
			}
		}

		public bool Mute
		{
			get
			{
				if (VoiceAudio.mute)
				{
					return DeadAudio.mute;
				}
				return false;
			}
			set
			{
				VoiceAudio.mute = value;
				DeadAudio.mute = value;
			}
		}

		public PlayerAudioGroup(AudioSource voiceAudio, AudioSource deadAudio)
		{
			VoiceAudio = voiceAudio;
			DeadAudio = deadAudio;
		}

		public void Play()
		{
			AudioSource voiceAudio = VoiceAudio;
			if (voiceAudio != null)
			{
				voiceAudio.Play();
			}
			AudioSource deadAudio = DeadAudio;
			if (deadAudio != null)
			{
				deadAudio.Play();
			}
		}

		public void Pause()
		{
			AudioSource voiceAudio = VoiceAudio;
			if (voiceAudio != null)
			{
				voiceAudio.Pause();
			}
			AudioSource deadAudio = DeadAudio;
			if (deadAudio != null)
			{
				deadAudio.Pause();
			}
		}

		public void Stop()
		{
			AudioSource voiceAudio = VoiceAudio;
			if (voiceAudio != null)
			{
				voiceAudio.Stop();
			}
			AudioSource deadAudio = DeadAudio;
			if (deadAudio != null)
			{
				deadAudio.Stop();
			}
		}
	}
	public struct RequestHeader
	{
		public string Name { get; set; }

		public string Value { get; set; }

		public RequestHeader(string name, string value)
		{
			Name = name;
			Value = value;
		}
	}
	public class VoiceMessage
	{
		public int Channels = 1;

		public int SampleRate = 48000;

		private float _timer;

		public int Id { get; private set; }

		public string VoiceName { get; private set; }

		public string Message { get; private set; }

		public AudioClip AudioClip { get; set; }

		public List<ulong> ClientsReceivedAudioClip { get; private set; } = new List<ulong>();


		public List<float> BufferedSamples { get; private set; } = new List<float>();


		public bool IsClipBuilt { get; private set; }

		public bool HasBufferedAudio => BufferedSamples.Count > 0;

		public bool IsReady
		{
			get
			{
				if (!ClientsReceivedAudioClip.Contains(NetworkUtils.GetLocalClientId()))
				{
					return false;
				}
				return ClientsReceivedAudioClip.Count >= NetworkUtils.ConnectedPlayerCount;
			}
		}

		public bool IsTimedout => _timer >= ConfigManager.TTS_RequestTimeoutDuration.Value;

		public VoiceMessage(int id, string voiceName, string message)
		{
			Id = id;
			VoiceName = voiceName;
			Message = message;
		}

		public void Tick()
		{
			_timer += Time.deltaTime;
		}

		public void BuildClipIfNeeded()
		{
			if (!IsClipBuilt && BufferedSamples.Count != 0)
			{
				AudioClip = AudioClip.Create($"VoiceMessage_{Id}", BufferedSamples.Count / Channels, Channels, SampleRate, false);
				AudioClip.SetData(BufferedSamples.ToArray(), 0);
				IsClipBuilt = true;
			}
		}

		public override string ToString()
		{
			return $"(Id: {Id}, VoiceName: \"{VoiceName}\", Message: \"{Message}\")";
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Objects.Voices
{
	public enum VoiceService
	{
		Unknown = -1,
		Streamlabs,
		LazyPy,
		TTSMonster
	}
	public abstract class TTSVoice
	{
		protected const int DEFAULT_VOLUME = 100;

		protected static string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 OPR/123.0.0.0";

		public string Name { get; protected set; }

		public string VoiceId { get; protected set; }

		public int DefaultVolume { get; protected set; } = 100;


		public abstract VoiceService Service { get; }

		protected TTSVoice(string name, string voiceId, int defaultVolume = 100)
		{
			Name = name;
			VoiceId = voiceId;
			DefaultVolume = defaultVolume;
		}

		public virtual void RequestAudio(string text, Action<AudioClip> onClipReady)
		{
			CoroutineRunner.Start(RequestAudioCoroutine(text, onClipReady));
		}

		public abstract IEnumerator RequestAudioCoroutine(string text, Action<AudioClip> onClipReady);

		protected async Task<JObject> FetchJsonAsync(string url, WWWForm form, List<RequestHeader> requestHeaders = null)
		{
			LogInfo("Sending POST request to \"" + url + "\"", extended: true);
			UnityWebRequest www = UnityWebRequest.Post(url, form);
			try
			{
				www.SetRequestHeader("User-Agent", UserAgent);
				if (requestHeaders != null)
				{
					foreach (RequestHeader requestHeader in requestHeaders)
					{
						www.SetRequestHeader(requestHeader.Name, requestHeader.Value);
					}
				}
				UnityWebRequestAsyncOperation operation = www.SendWebRequest();
				while (!((AsyncOperation)operation).isDone)
				{
					await Task.Yield();
				}
				if ((int)www.result == 4)
				{
					LogError("Failed to process data: " + www.error, extended: false, displayMessage: true);
					return null;
				}
				if ((int)www.result != 1)
				{
					LogError("Failed to fetch audio: " + www.error, extended: false, displayMessage: true);
					return null;
				}
				string text = www.downloadHandler.text;
				try
				{
					JObject val = JObject.Parse(text);
					LogInfo("Response data:\n" + JsonConvert.SerializeObject((object)val, (Formatting)1), extended: true);
					return val;
				}
				catch (Exception arg)
				{
					LogError($"Failed to parse response as JSON:\n\nResponse:\n\"{text}\"\n\nError:\n{arg}");
					DisplayMessage("Failed to parse response. Check logs", isError: true);
					return null;
				}
			}
			finally
			{
				((IDisposable)www)?.Dispose();
			}
		}

		protected async Task<JObject> FetchJsonAsync(string url, JObject body, List<RequestHeader> requestHeaders = null)
		{
			LogInfo("Sending POST request to \"" + url + "\"", extended: true);
			string s = ((body != null) ? ((JToken)body).ToString((Formatting)0, Array.Empty<JsonConverter>()) : "{}");
			byte[] bytes = Encoding.UTF8.GetBytes(s);
			UnityWebRequest www = new UnityWebRequest(url, "POST");
			try
			{
				www.uploadHandler = (UploadHandler)new UploadHandlerRaw(bytes);
				www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
				www.SetRequestHeader("Content-Type", "application/json");
				www.SetRequestHeader("User-Agent", UserAgent);
				if (requestHeaders != null)
				{
					foreach (RequestHeader requestHeader in requestHeaders)
					{
						www.SetRequestHeader(requestHeader.Name, requestHeader.Value);
					}
				}
				UnityWebRequestAsyncOperation operation = www.SendWebRequest();
				while (!((AsyncOperation)operation).isDone)
				{
					await Task.Yield();
				}
				if ((int)www.result == 4)
				{
					LogError("Failed to process data: " + www.error, extended: false, displayMessage: true);
					return null;
				}
				if ((int)www.result != 1)
				{
					LogError("Failed to fetch audio: " + www.error, extended: false, displayMessage: true);
					LogError(www.downloadHandler.text, extended: true);
					return null;
				}
				string text = www.downloadHandler.text;
				try
				{
					JObject val = JObject.Parse(text);
					LogInfo("Response data:\n" + JsonConvert.SerializeObject((object)val, (Formatting)1), extended: true);
					return val;
				}
				catch (Exception arg)
				{
					LogError($"Failed to parse response as JSON:\n\nResponse:\n\"{text}\"\n\nError:\n{arg}");
					DisplayMessage("Failed to parse response. Check logs", isError: true);
					return null;
				}
			}
			finally
			{
				((IDisposable)www)?.Dispose();
			}
		}

		protected async Task<AudioClip> DownloadAudioClipAsync(string url, AudioType audioType = 13)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			LogInfo("Sending GET request to \"" + url + "\"", extended: true);
			UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, audioType);
			try
			{
				www.SetRequestHeader("User-Agent", UserAgent);
				UnityWebRequestAsyncOperation operation = www.SendWebRequest();
				while (!((AsyncOperation)operation).isDone)
				{
					await Task.Yield();
				}
				if ((int)www.result != 1)
				{
					LogError("Failed to download audio: " + www.error, extended: false, displayMessage: true);
					return null;
				}
				try
				{
					AudioClip content = DownloadHandlerAudioClip.GetContent(www);
					((Object)content).name = string.Format("{0}_{1}_{2}", "MelaniesVoice", Utils.SanitizeFileName(Name), Guid.NewGuid());
					return content;
				}
				catch (Exception ex)
				{
					LogError("Failed to download audio: " + ex.Message, extended: false, displayMessage: true);
					return null;
				}
			}
			finally
			{
				((IDisposable)www)?.Dispose();
			}
		}

		protected void DisplayMessage(string text, bool isError = false)
		{
			Utils.DisplayMessage(text, isError);
		}

		public override string ToString()
		{
			return $"(Name: \"{Name}\", Service: {Service}, VoiceId: \"{VoiceId}\")";
		}

		protected void Log(LogLevel logLevel, object data, bool extended = false, bool displayMessage = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			Logger.Log(logLevel, $"[{GetType().Name}] [{Name}] {data}", extended);
			if (displayMessage)
			{
				DisplayMessage(data.ToString(), (int)logLevel == 2);
			}
		}

		protected void LogInfo(object data, bool extended = false, bool displayMessage = false)
		{
			Log((LogLevel)16, data, extended, displayMessage);
		}

		protected void LogWarning(object data, bool extended = false, bool displayMessage = false)
		{
			Log((LogLevel)4, data, extended, displayMessage);
		}

		protected void LogError(object data, bool extended = false, bool displayMessage = false)
		{
			Log((LogLevel)2, data, extended, displayMessage);
		}
	}
	public class TTSVoice_LazyPy : TTSVoice
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass7_0
		{
			public JObject responseJson;

			public Action<AudioClip> onClipReady;

			internal void <RequestAudioCoroutine>b__0(JObject result)
			{
				responseJson = result;
			}

			internal void <RequestAudioCoroutine>b__1(AudioClip clip)
			{
				onClipReady?.Invoke(clip);
			}
		}

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

			private object <>2__current;

			public Action<AudioClip> onClipReady;

			public TTSVoice_LazyPy <>4__this;

			public string text;

			private <>c__DisplayClass7_0 <>8__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Expected O, but got Unknown
				int num = <>1__state;
				TTSVoice_LazyPy tTSVoice_LazyPy = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass7_0();
					<>8__1.onClipReady = onClipReady;
					string url = "https://lazypy.ro/tts/request_tts.php";
					WWWForm val = new WWWForm();
					val.AddField("service", tTSVoice_LazyPy.RedirectService);
					val.AddField("voice", tTSVoice_LazyPy.VoiceId);
					val.AddField("text", this.text);
					Task<JObject> task2 = tTSVoice_LazyPy.FetchJsonAsync(url, val);
					<>8__1.responseJson = null;
					<>2__current = Utils.WaitForTask(task2, delegate(JObject result)
					{
						<>8__1.responseJson = result;
					});
					<>1__state = 1;
					return true;
				}
				case 1:
				{
					<>1__state = -1;
					if (<>8__1.responseJson == null)
					{
						tTSVoice_LazyPy.LogError("Failed to request audio. Response from server is invalid.");
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					JToken obj = <>8__1.responseJson["success"];
					if (obj == null || !obj.ToObject<bool>())
					{
						string text = ((object)<>8__1.responseJson["error_msg"])?.ToString();
						tTSVoice_LazyPy.LogError("Failed to fetch audio: " + text);
						tTSVoice_LazyPy.DisplayMessage(text, isError: true);
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					string text2 = ((object)<>8__1.responseJson["audio_url"])?.ToString();
					if (string.IsNullOrEmpty(text2))
					{
						tTSVoice_LazyPy.LogError("Failed to fetch audio: 'audio_url' is missing.", extended: false, displayMessage: true);
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					Task<AudioClip> task = tTSVoice_LazyPy.DownloadAudioClipAsync(text2, (AudioType)13);
					<>2__current = Utils.WaitForTask(task, delegate(AudioClip clip)
					{
						<>8__1.onClipReady?.Invoke(clip);
					});
					<>1__state = 2;
					return true;
				}
				case 2:
					<>1__state = -1;
					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();
			}
		}

		public override VoiceService Service => VoiceService.LazyPy;

		public string RedirectService { get; protected set; }

		public TTSVoice_LazyPy(string name, string redirectService, string voiceId, int defaultVolume = 100)
			: base(name, voiceId, defaultVolume)
		{
			RedirectService = redirectService;
		}

		[IteratorStateMachine(typeof(<RequestAudioCoroutine>d__7))]
		public override IEnumerator RequestAudioCoroutine(string text, Action<AudioClip> onClipReady)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RequestAudioCoroutine>d__7(0)
			{
				<>4__this = this,
				text = text,
				onClipReady = onClipReady
			};
		}
	}
	public class TTSVoice_Streamlabs : TTSVoice
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass3_0
		{
			public JObject responseJson;

			public Action<AudioClip> onClipReady;

			internal void <RequestAudioCoroutine>b__0(JObject result)
			{
				responseJson = result;
			}

			internal void <RequestAudioCoroutine>b__1(AudioClip clip)
			{
				onClipReady?.Invoke(clip);
			}
		}

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

			private object <>2__current;

			public Action<AudioClip> onClipReady;

			public TTSVoice_Streamlabs <>4__this;

			public string text;

			private <>c__DisplayClass3_0 <>8__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Expected O, but got Unknown
				int num = <>1__state;
				TTSVoice_Streamlabs tTSVoice_Streamlabs = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass3_0();
					<>8__1.onClipReady = onClipReady;
					string url = "https://streamlabs.com/tts/polly/speak";
					WWWForm val = new WWWForm();
					val.AddField("voice", tTSVoice_Streamlabs.VoiceId);
					val.AddField("text", this.text);
					Task<JObject> task2 = tTSVoice_Streamlabs.FetchJsonAsync(url, val);
					<>8__1.responseJson = null;
					<>2__current = Utils.WaitForTask(task2, delegate(JObject result)
					{
						<>8__1.responseJson = result;
					});
					<>1__state = 1;
					return true;
				}
				case 1:
				{
					<>1__state = -1;
					if (<>8__1.responseJson == null)
					{
						tTSVoice_Streamlabs.LogError("Failed to request audio. Response from server is invalid.");
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					JToken obj = <>8__1.responseJson["success"];
					if (obj == null || !obj.ToObject<bool>())
					{
						string text = ((object)<>8__1.responseJson["message"])?.ToString();
						tTSVoice_Streamlabs.LogError("Failed to fetch audio: " + (object)<>8__1.responseJson["message"]);
						tTSVoice_Streamlabs.DisplayMessage(text, isError: true);
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					string text2 = ((object)<>8__1.responseJson["speak_url"])?.ToString();
					if (string.IsNullOrEmpty(text2))
					{
						tTSVoice_Streamlabs.LogError("Failed to fetch audio: 'speak_url' is missing.", extended: false, displayMessage: true);
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					Task<AudioClip> task = tTSVoice_Streamlabs.DownloadAudioClipAsync(text2, (AudioType)13);
					<>2__current = Utils.WaitForTask(task, delegate(AudioClip clip)
					{
						<>8__1.onClipReady?.Invoke(clip);
					});
					<>1__state = 2;
					return true;
				}
				case 2:
					<>1__state = -1;
					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();
			}
		}

		public override VoiceService Service => VoiceService.Streamlabs;

		public TTSVoice_Streamlabs(string name, string voiceId, int defaultVolume = 100)
			: base(name, voiceId, defaultVolume)
		{
		}

		[IteratorStateMachine(typeof(<RequestAudioCoroutine>d__3))]
		public override IEnumerator RequestAudioCoroutine(string text, Action<AudioClip> onClipReady)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RequestAudioCoroutine>d__3(0)
			{
				<>4__this = this,
				text = text,
				onClipReady = onClipReady
			};
		}
	}
	public class TTSVoice_TTSMonster : TTSVoice
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass5_0
		{
			public JObject responseJson;

			public Action<AudioClip> onClipReady;

			internal void <RequestAudioCoroutine>b__0(JObject result)
			{
				responseJson = result;
			}

			internal void <RequestAudioCoroutine>b__1(AudioClip clip)
			{
				onClipReady?.Invoke(clip);
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass8_0
		{
			public JObject responseJson;

			internal void <FetchVoicesCoroutine>b__0(JObject result)
			{
				responseJson = result;
			}
		}

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

			private object <>2__current;

			private <>c__DisplayClass8_0 <>8__1;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass8_0();
					string value = ConfigManager.TTSMonster_APIKey.Value;
					if (string.IsNullOrEmpty(value))
					{
						StaticLogError("Failed to fetch voices. TTS.Monster API key required. Set in config file.");
						return false;
					}
					Task<JObject> task = FetchVoicesJsonAsync(value);
					<>8__1.responseJson = null;
					<>2__current = Utils.WaitForTask(task, delegate(JObject result)
					{
						<>8__1.responseJson = result;
					});
					<>1__state = 1;
					return true;
				}
				case 1:
				{
					<>1__state = -1;
					if (<>8__1.responseJson == null)
					{
						StaticLogError("Failed to fetch voices. Response from server is invalid.");
						return false;
					}
					List<TTSMonsterVoice> list = ParseVoicesJson(<>8__1.responseJson);
					if (list.Count == 0)
					{
						StaticLogError("Failed to fetch voices. No voices found from response data.");
						return false;
					}
					List<TTSVoice_TTSMonster> list2 = ConvertToTTSVoices(list);
					if (list2.Count == 0)
					{
						StaticLogError("Failed to fetch voices. Could not convert TTSMonsterVoice(s) to TTSVoice_TTSMonster(s)");
						return false;
					}
					UpdateExistingVoicesData(list2);
					List<TTSVoice_TTSMonster> list3 = TextToSpeech.AddVoices(list2, logErrors: false);
					if (list3.Count > 0)
					{
						VoiceConfigManager.BindConfigs(list3);
						ConfigManager.UpdateTTSVoiceAcceptableValues();
					}
					StaticLogInfo($"Found {list.Count} voices. Registered {list3.Count} new voices.");
					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 <RequestAudioCoroutine>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Action<AudioClip> onClipReady;

			public TTSVoice_TTSMonster <>4__this;

			public string text;

			private <>c__DisplayClass5_0 <>8__1;

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

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

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

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

			private bool MoveNext()
			{
				//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_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Expected O, but got Unknown
				int num = <>1__state;
				TTSVoice_TTSMonster tTSVoice_TTSMonster = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass5_0();
					<>8__1.onClipReady = onClipReady;
					string url = "https://api.console.tts.monster/generate";
					string value = ConfigManager.TTSMonster_APIKey.Value;
					if (string.IsNullOrEmpty(value))
					{
						tTSVoice_TTSMonster.LogError("TTS.Monster API key required. Set in config file.", extended: false, displayMessage: true);
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					List<RequestHeader> requestHeaders = new List<RequestHeader>(1)
					{
						new RequestHeader("Authorization", value)
					};
					JObject body = new JObject
					{
						["voice_id"] = JToken.op_Implicit(tTSVoice_TTSMonster.VoiceId),
						["message"] = JToken.op_Implicit(this.text)
					};
					Task<JObject> task2 = tTSVoice_TTSMonster.FetchJsonAsync(url, body, requestHeaders);
					<>8__1.responseJson = null;
					<>2__current = Utils.WaitForTask(task2, delegate(JObject result)
					{
						<>8__1.responseJson = result;
					});
					<>1__state = 1;
					return true;
				}
				case 1:
				{
					<>1__state = -1;
					if (<>8__1.responseJson == null)
					{
						tTSVoice_TTSMonster.LogError("Failed to request audio. Response from server is invalid.");
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					JToken obj = <>8__1.responseJson["status"];
					int num2 = ((obj != null) ? obj.ToObject<int>() : 0);
					if (num2 != 200)
					{
						string text = num2 switch
						{
							401 => "Unauthorized: Invalid API key", 
							402 => "Character quota exceeded. Upgrade your account or turn on usage-based-billing", 
							429 => "Too many requests. Try again later", 
							500 => "Internal server error", 
							_ => $"Unknown error. Code {num2}", 
						};
						tTSVoice_TTSMonster.LogError("Failed to fetch audio: " + text);
						tTSVoice_TTSMonster.DisplayMessage(text, isError: true);
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					string text2 = ((object)<>8__1.responseJson["url"])?.ToString();
					if (string.IsNullOrEmpty(text2))
					{
						tTSVoice_TTSMonster.LogError("Failed to fetch audio: 'url' is missing.", extended: false, displayMessage: true);
						<>8__1.onClipReady?.Invoke(null);
						return false;
					}
					Task<AudioClip> task = tTSVoice_TTSMonster.DownloadAudioClipAsync(text2, (AudioType)20);
					<>2__current = Utils.WaitForTask(task, delegate(AudioClip clip)
					{
						<>8__1.onClipReady?.Invoke(clip);
					});
					<>1__state = 2;
					return true;
				}
				case 2:
					<>1__state = -1;
					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 readonly Dictionary<string, string> _voiceNameProxies;

		public override VoiceService Service => VoiceService.TTSMonster;

		static TTSVoice_TTSMonster()
		{
			_voiceNameProxies = new Dictionary<string, string>();
			_voiceNameProxies.Add("Chef", "Gordon Ramsay");
			_voiceNameProxies.Add("Circuit", "Linus Tech Tips");
			_voiceNameProxies.Add("Dash", "Sonic");
			_voiceNameProxies.Add("Diplomat", "Joe Biden");
			_voiceNameProxies.Add("Elder", "Morgan Freeman");
			_voiceNameProxies.Add("Frogman", "Kermit");
			_voiceNameProxies.Add("Gravel", "MoistCr1TiKaL");
			_voiceNameProxies.Add("Leader", "Obama");
			_voiceNameProxies.Add("Micro", "Plankton");
			_voiceNameProxies.Add("Oracle", "GLaDOS");
			_voiceNameProxies.Add("Phantom", "Vega");
			_voiceNameProxies.Add("Scout", "Bart Simpson");
			_voiceNameProxies.Add("Spongey", "Sponge Bob");
			_voiceNameProxies.Add("Star", "Patrick Star");
			_voiceNameProxies.Add("Tentacle", "Squidward");
			_voiceNameProxies.Add("Tycoon", "Donald Trump");
		}

		public TTSVoice_TTSMonster(string name, string voiceId, int defaultVolume = 100)
			: base(name, voiceId, defaultVolume)
		{
		}

		[IteratorStateMachine(typeof(<RequestAudioCoroutine>d__5))]
		public override IEnumerator RequestAudioCoroutine(string text, Action<AudioClip> onClipReady)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RequestAudioCoroutine>d__5(0)
			{
				<>4__this = this,
				text = text,
				onClipReady = onClipReady
			};
		}

		public static List<TTSVoice_TTSMonster> CreateDefaultVoices()
		{
			try
			{
				JObject val = PluginResourceHelper.ReadJObject("Data/TTSMonsterVoicesDefault.json");
				if (val == null)
				{
					return new List<TTSVoice_TTSMonster>();
				}
				return ConvertToTTSVoices(ParseVoicesJson(val));
			}
			catch (Exception arg)
			{
				StaticLogError($"Failed to load default voices. {arg}");
				return new List<TTSVoice_TTSMonster>();
			}
		}

		public static void FetchVoices()
		{
			CoroutineRunner.Start(FetchVoicesCoroutine());
		}

		[IteratorStateMachine(typeof(<FetchVoicesCoroutine>d__8))]
		public static IEnumerator FetchVoicesCoroutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FetchVoicesCoroutine>d__8(0);
		}

		protected static async Task<JObject> FetchVoicesJsonAsync(string apiKey)
		{
			string text = "https://api.console.tts.monster/voices";
			StaticLogInfo("Sending POST request to \"" + text + "\"", extended: true);
			UnityWebRequest www = UnityWebRequest.Post(text, new WWWForm());
			try
			{
				www.SetRequestHeader("User-Agent", TTSVoice.UserAgent);
				www.SetRequestHeader("Authorization", apiKey);
				UnityWebRequestAsyncOperation operation = www.SendWebRequest();
				while (!((AsyncOperation)operation).isDone)
				{
					await Task.Yield();
				}
				if ((int)www.result == 4)
				{
					StaticLogError("Failed to process voices data: " + www.error);
					return null;
				}
				if ((int)www.result != 1)
				{
					StaticLogError("Failed to fetch voices: " + www.error);
					return null;
				}
				string text2 = www.downloadHandler.text;
				try
				{
					JObject val = JObject.Parse(text2);
					StaticLogInfo("Response data:\n" + JsonConvert.SerializeObject((object)val, (Formatting)1), extended: true);
					return val;
				}
				catch (Exception arg)
				{
					StaticLogError($"Failed to parse response as JSON:\n\nResponse:\n\"{text2}\"\n\nError:\n{arg}");
					return null;
				}
			}
			finally
			{
				((IDisposable)www)?.Dispose();
			}
		}

		protected static void UpdateExistingVoicesData(List<TTSVoice_TTSMonster> voices)
		{
			List<TTSVoice_TTSMonster> list = (from x in TextToSpeech.GetVoicesByService(VoiceService.TTSMonster)
				select x as TTSVoice_TTSMonster into x
				where x != null
				select x).ToList();
			foreach (TTSVoice_TTSMonster existingVoice in list)
			{
				TTSVoice_TTSMonster tTSVoice_TTSMonster = voices.FirstOrDefault((TTSVoice_TTSMonster x) => x.Name == existingVoice.Name);
				if (tTSVoice_TTSMonster != null && existingVoice.VoiceId != tTSVoice_TTSMonster.VoiceId)
				{
					existingVoice.VoiceId = tTSVoice_TTSMonster.VoiceId;
					StaticLogInfo("Updated already registerd voice \"" + existingVoice.Name + "\" VoiceId to \"" + tTSVoice_TTSMonster.VoiceId + "\"", extended: true);
				}
			}
		}

		protected static string GetProxyName(string name)
		{
			return _voiceNameProxies.GetValueOrDefault(name, name);
		}

		protected static List<TTSMonsterVoice> ParseVoicesJson(string text)
		{
			try
			{
				JObject data = JObject.Parse(text);
				return ParseVoicesJson(data);
			}
			catch (Exception arg)
			{
				StaticLogError($"Failed to parse text as JSON:\n\nResponse:\n\"{text}\"\n\nError:\n{arg}");
				return new List<TTSMonsterVoice>();
			}
		}

		protected static List<TTSMonsterVoice> ParseVoicesJson(JObject data)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			List<TTSMonsterVoice> list = new List<TTSMonsterVoice>();
			string text = "TTSM - ";
			JToken obj = data["customVoices"];
			JArray val = (JArray)(object)((obj is JArray) ? obj : null);
			JToken obj2 = data["voices"];
			JArray val2 = (JArray)(object)((obj2 is JArray) ? obj2 : null);
			foreach (JObject item in val)
			{
				JObject val3 = item;
				string text2 = ((object)val3["name"])?.ToString();
				string text3 = ((object)val3["voice_id"])?.ToString();
				if (!string.IsNullOrEmpty(text2) && !string.IsNullOrEmpty(text3))
				{
					list.Add(new TTSMonsterVoice(text + text2, text3, isCustom: true));
				}
			}
			foreach (JObject item2 in val2)
			{
				JObject val4 = item2;
				string text4 = ((object)val4["name"])?.ToString();
				string text5 = ((object)val4["voice_id"])?.ToString();
				if (!string.IsNullOrEmpty(text4) && !string.IsNullOrEmpty(text5))
				{
					list.Add(new TTSMonsterVoice(text + GetProxyName(text4), text5));
				}
			}
			return list;
		}

		protected static List<TTSVoice_TTSMonster> ConvertToTTSVoices(List<TTSMonsterVoice> ttsMonsterVoices)
		{
			List<TTSVoice_TTSMonster> list = new List<TTSVoice_TTSMonster>();
			foreach (TTSMonsterVoice ttsMonsterVoice in ttsMonsterVoices)
			{
				TTSVoice_TTSMonster tTSVoice_TTSMonster = ConvertToTTSVoice(ttsMonsterVoice);
				if (tTSVoice_TTSMonster != null)
				{
					list.Add(tTSVoice_TTSMonster);
				}
			}
			return list;
		}

		protected static TTSVoice_TTSMonster ConvertToTTSVoice(TTSMonsterVoice ttsMonsterVoice)
		{
			if (!ttsMonsterVoice.IsValid())
			{
				return null;
			}
			return new TTSVoice_TTSMonster(ttsMonsterVoice.Name, ttsMonsterVoice.VoiceId);
		}

		public static void OpenLoginWebpage()
		{
			Application.OpenURL("https://console.tts.monster/login");
		}

		protected static void StaticLog(LogLevel logLevel, object data, bool extended = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Logger.Log(logLevel, string.Format("[{0}] {1}", "TTSVoice_TTSMonster", data), extended);
		}

		protected static void StaticLogInfo(object data, bool extended = false)
		{
			StaticLog((LogLevel)16, data, extended);
		}

		protected static void StaticLogWarning(object data, bool extended = false)
		{
			StaticLog((LogLevel)4, data, extended);
		}

		protected static void StaticLogError(object data, bool extended = false)
		{
			StaticLog((LogLevel)2, data, extended);
		}
	}
	public struct TTSMonsterVoice
	{
		public string Name { get; set; }

		public string VoiceId { get; set; }

		public bool IsCustom { get; set; }

		public TTSMonsterVoice(string name, string voiceId, bool isCustom = false)
		{
			Name = name;
			VoiceId = voiceId;
			IsCustom = isCustom;
		}

		public bool IsValid()
		{
			if (!string.IsNullOrEmpty(Name))
			{
				return !string.IsNullOrEmpty(VoiceId);
			}
			return false;
		}

		public override string ToString()
		{
			return $"(Name: \"{Name}\", IsCustom: {IsCustom}, VoiceId: \"{VoiceId}\")";
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Objects.Config
{
	public class VoiceConfigEntry
	{
		public TTSVoice Voice { get; private set; }

		public ConfigEntry<int> Volume { get; private set; }

		public VoiceConfigEntry(TTSVoice voice, int defaultVolume)
		{
			Bind(voice, defaultVolume);
		}

		private void Bind(TTSVoice voice, int defaultVolume)
		{
			Voice = voice;
			string section = "Voice: " + Voice.Name;
			Volume = ConfigHelper.Bind(section, "Volume", defaultVolume, "The volume of the voice.", requiresRestart: false, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200));
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.MonoBehaviours
{
	internal class CoroutineRunner : MonoBehaviour
	{
		public static CoroutineRunner Instance { get; private set; }

		public static void Spawn()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Instance != (Object)null))
			{
				new GameObject("MelaniesVoice CoroutineRunner", new Type[1] { typeof(CoroutineRunner) });
			}
		}

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			((Object)this).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)this);
		}

		public static Coroutine Start(IEnumerator routine)
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Spawn();
			}
			CoroutineRunner instance = Instance;
			return ((instance != null) ? ((MonoBehaviour)instance).StartCoroutine(routine) : null) ?? null;
		}

		public static void Stop(IEnumerator routine)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				((MonoBehaviour)Instance).StopCoroutine(routine);
			}
		}

		public static void Stop(Coroutine routine)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				((MonoBehaviour)Instance).StopCoroutine(routine);
			}
		}
	}
	public class VoiceController : NetworkBehaviour
	{
		[CompilerGenerated]
		private sealed class <StreamAudio_Local>d__35 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AudioClip clip;

			public VoiceMessage voiceMessage;

			public VoiceController <>4__this;

			private float[] <data>5__2;

			private int <pos>5__3;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0154: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_016e: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				VoiceController voiceController = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)clip == (Object)null)
					{
						return false;
					}
					voiceMessage.AudioClip = clip;
					if (NetworkUtils.ConnectedPlayerCount == 1)
					{
						voiceController.ReceivedVoiceMessageAudioClip_ServerRpc(voiceMessage.Id);
						return false;
					}
					<data>5__2 = new float[clip.samples * clip.channels];
					clip.GetData(<data>5__2, 0);
					<pos>5__3 = 0;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<pos>5__3 < <data>5__2.Length)
				{
					int num2 = Mathf.Min(voiceController._chunkSize, <data>5__2.Length - <pos>5__3);
					float[] array = new float[num2];
					Array.Copy(<data>5__2, <pos>5__3, array, 0, num2);
					voiceController.StreamAudioChunk_ServerRpc(voiceMessage.Id, array, clip.channels, clip.frequency);
					<pos>5__3 += num2;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				voiceController.StreamAudioComplete_ServerRpc(voiceMessage.Id);
				voiceController.ReceivedVoiceMessageAudioClip_ServerRpc(voiceMessage.Id);
				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 readonly List<VoiceController> _instances = new List<VoiceController>();

		[SerializeField]
		private AudioSource _voiceAudio;

		[SerializeField]
		private AudioSource _deadAudio;

		private List<VoiceMessage> _voiceMessageQueue = new List<VoiceMessage>();

		private float _noiseRange = 30f;

		private float _noiseLoudness = 0.7f;

		private float _noiseTimer;

		private float _noiseCooldown = 0.2f;

		private readonly int _chunkSize = 480;

		public static IReadOnlyList<VoiceController> Instances => _instances;

		public PlayerAudioGroup PlayerAudioGroup { get; private set; }

		public PlayerControllerB PlayerScript { get; private set; }

		public bool IsLocal => PlayerUtils.IsLocalPlayer(PlayerScript);

		private void OnEnable()
		{
			if (!_instances.Contains(this))
			{
				_instances.Add(this);
			}
		}

		private void OnDisable()
		{
			_instances.Remove(this);
		}

		private void Start()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB playerScript = default(PlayerControllerB);
			if ((Object)(object)((Component)this).transform.parent == (Object)null)
			{
				LogError("Failed to initialize. Transform parent is null.");
				if (NetworkUtils.IsServer)
				{
					((Component)this).GetComponent<NetworkObject>().Despawn(true);
				}
			}
			else if (!((Component)((Component)this).transform.parent).TryGetComponent<PlayerControllerB>(ref playerScript))
			{
				LogError("Failed to initialize. PlayerControllerB is null.");
				if (NetworkUtils.IsServer)
				{
					((Component)this).GetComponent<NetworkObject>().Despawn(true);
				}
			}
			else
			{
				PlayerScript = playerScript;
				((Component)this).transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
				PlayerAudioGroup = new PlayerAudioGroup(_voiceAudio, _deadAudio);
				PlayerAudioGroup.Volume = 1f;
				ApplySettings();
				LogInfo("Initialized.", extended: true);
			}
		}

		private void Update()
		{
			VoiceMessageTick();
			NoiseTick();
		}

		private void VoiceMessageTick()
		{
			if (!NetworkUtils.IsServer || PlayerAudioGroup == null || IsPlayingVoiceMessage() || _voiceMessageQueue.Count == 0)
			{
				return;
			}
			VoiceMessage voiceMessage = _voiceMessageQueue[0];
			if (voiceMessage == null)
			{
				_voiceMessageQueue.RemoveAt(0);
				return;
			}
			if (voiceMessage.IsReady)
			{
				PlayVoiceMessage_ClientRpc(voiceMessage.Id);
				return;
			}
			voiceMessage.Tick();
			if (voiceMessage.IsTimedout)
			{
				VoiceMessageTimedout_Server(voiceMessage.Id);
			}
		}

		private void NoiseTick()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkUtils.IsServer && PlayerAudioGroup != null && PlayerAudioGroup.IsPlaying && !((Object)(object)PlayerScript == (Object)null))
			{
				if (_noiseTimer >= _noiseCooldown)
				{
					_noiseTimer = 0f;
					RoundManager.Instance.PlayAudibleNoise(((Component)PlayerScript).transform.position, _noiseRange, _noiseLoudness, 0, PlayerScript.isInHangarShipRoom && StartOfRound.Instance.hangarDoorsClosed, 75);
				}
				else
				{
					_noiseTimer += Time.deltaTime;
				}
			}
		}

		private void UpdateVoiceMute()
		{
			if ((Object)(object)PlayerScript == (Object)null || PlayerAudioGroup == null)
			{
				return;
			}
			if (IsLocal)
			{
				PlayerAudioGroup.Mute = !ConfigManager.TTS_HearMyself.Value;
				if (!PlayerAudioGroup.Mute)
				{
					PlayerAudioGroup.VoiceAudio.mute = PlayerScript.isPlayerDead;
					PlayerAudioGroup.DeadAudio.mute = !PlayerScript.isPlayerDead;
				}
			}
			else
			{
				PlayerAudioGroup.VoiceAudio.mute = PlayerScript.isPlayerDead;
				PlayerControllerB localPlayerScript = PlayerUtils.GetLocalPlayerScript();
				if ((Object)(object)localPlayerScript == (Object)null || !localPlayerScript.isPlayerDead)
				{
					PlayerAudioGroup.DeadAudio.mute = true;
				}
				else
				{
					PlayerAudioGroup.DeadAudio.mute = !PlayerScript.isPlayerDead;
				}
			}
		}

		private bool IsPlayingVoiceMessage()
		{
			return PlayerAudioGroup.IsPlaying;
		}

		private VoiceMessage GetVoiceMessage(int id)
		{
			return _voiceMessageQueue.FirstOrDefault((VoiceMessage x) => x.Id == id);
		}

		[ServerRpc]
		public void CreateVoiceMessage_ServerRpc(string voiceName, string message, ServerRpcParams serverRpcParams = default(ServerRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Invalid comparison between Unknown and I4
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2160464779u, serverRpcParams, (RpcDelivery)0);
				bool flag = voiceName != null;
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val)).WriteValueSafe(voiceName, false);
				}
				bool flag2 = message != null;
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
				if (flag2)
				{
					((FastBufferWriter)(ref val)).WriteValueSafe(message, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 2160464779u, serverRpcParams, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				ulong senderClientId = serverRpcParams.Receive.SenderClientId;
				if (((NetworkBehaviour)this).NetworkManager.ConnectedClients.ContainsKey(senderClientId) && !((Object)(object)PlayerScript == (Object)null) && PlayerScript.actualClientId == senderClientId)
				{
					int id = Random.Range(0, 1000000);
					CreateVoiceMessage_ClientRpc(id, voiceName, message);
				}
			}
		}

		[ClientRpc]
		private void CreateVoiceMessage_ClientRpc(int id, string voiceName, string message)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1380029231u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, id);
				bool flag = voiceName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(voiceName, false);
				}
				bool flag2 = message != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
				if (flag2)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(message, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1380029231u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			int id2 = id;
			string voiceName2 = voiceName;
			VoiceMessage voiceMessage = new VoiceMessage(id2, voiceName2, message);
			_voiceMessageQueue.Add(voiceMessage);
			LogInfo($"Created VoiceMessage. {voiceMessage}", extended: true);
			if (!IsLocal)
			{
				return;
			}
			TextToSpeech.RequestAudio(voiceMessage.VoiceName, voiceMessage.Message, delegate(AudioClip clip)
			{
				if ((Object)(object)clip == (Object)null)
				{
					DeleteVoiceMessage_ServerRpc(id2);
				}
				else
				{
					((Object)clip).name = string.Format("{0}_{1}_{2}", "MelaniesVoice", Utils.SanitizeFileName(voiceName2), id2);
					((MonoBehaviour)this).StartCoroutine(StreamAudio_Local(voiceMessage, clip));
					if (MirageProxy.Enabled)
					{
						MirageProxy.SaveAudioClip(clip);
					}
				}
			});
		}

		[ServerRpc]
		private void DeleteVoiceMessage_ServerRpc(int id)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Invalid comparison between Unknown and I4
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4045068609u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, id);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4045068609u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				DeleteVoiceMessage_ClientRpc(id);
				DeleteVoiceMessage_Local(id);
			}
		}

		[ClientRpc]
		private void DeleteVoiceMessage_ClientRpc(int id)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2880339731u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, id);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2880339731u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				if (!NetworkUtils.IsServer)
				{
					DeleteVoiceMessage_Local(id);
				}
			}
		}

		private void DeleteVoiceMessage_Local(int id)
		{
			VoiceMessage voiceMessage = GetVoiceMessage(id);
			if (voiceMessage != null)
			{
				_voiceMessageQueue.Remove(voiceMessage);
			}
		}

		[IteratorStateMachine(typeof(<StreamAudio_Local>d__35))]
		private IEnumerator StreamAudio_Local(VoiceMessage voiceMessage, AudioClip clip)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <StreamAudio_Local>d__35(0)
			{
				<>4__this = this,
				voiceMessage = voiceMessage,
				clip = clip
			};
		}

		[ServerRpc]
		private void StreamAudioChunk_ServerRpc(int id, float[] chunk, int channels, int sampleRate)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Invalid comparison between Unknown and I4
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1252295788u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, id);
				bool flag = chunk != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<float>(chunk, default(ForPrimitives));
				}
				BytePacker.WriteValueBitPacked(val2, channels);
				BytePacker.WriteValueBitPacked(val2, sampleRate);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1252295788u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				StreamAudioChunk_ClientRpc(id, chunk, channels, sampleRate);
			}
		}

		[ClientRpc]
		private void StreamAudioChunk_ClientRpc(int id, float[] chunk, int channels, int sampleRate)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00c9: 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_00ee: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2319454299u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, id);
				bool flag = chunk != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<float>(chunk, default(ForPrimitives));
				}
				BytePacker.WriteValueBitPacked(val2, channels);
				BytePacker.WriteValueBitPacked(val2, sampleRate);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2319454299u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			if (!IsLocal)
			{
				VoiceMessage voiceMessage = GetVoiceMessage(id);
				if (voiceMessage != null)
				{
					voiceMessage.Channels = channels;
					voiceMessage.SampleRate = sampleRate;
					voiceMessage.BufferedSamples.AddRange(chunk);
				}
			}
		}

		[ServerRpc]
		private void StreamAudioComplete_ServerRpc(int id, ServerRpcParams serverRpcParams = default(ServerRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Invalid comparison between Unknown and I4
			//IL_0114: 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)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(3290872701u, serverRpcParams, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, id);
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 3290872701u, serverRpcParams, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				ulong senderClientId = serverRpcParams.Receive.SenderClientId;
				if (((NetworkBehaviour)this).NetworkManager.ConnectedClients.ContainsKey(senderClientId))
				{
					StreamAudioComplete_ClientRpc(id);
				}
			}
		}

		[ClientRpc]
		private void StreamAudioComplete_ClientRpc(int id)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4122899824u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, id);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4122899824u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			if (!IsLocal)
			{
				VoiceMessage voiceMessage = GetVoiceMessage(id);
				if (voiceMessage != null)
				{
					voiceMessage.BuildClipIfNeeded();
					ReceivedVoiceMessageAudioClip_ServerRpc(voiceMessage.Id);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void ReceivedVoiceMessageAudioClip_ServerRpc(int id, ServerRpcParams serverRpcParams = default(ServerRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2085373701u, serverRpcParams, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, id);
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 2085373701u, serverRpcParams, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			ulong senderClientId = serverRpcParams.Receive.SenderClientId;
			if (((NetworkBehaviour)this).NetworkManager.ConnectedClients.ContainsKey(senderClientId))
			{
				VoiceMessage voiceMessage = GetVoiceMessage(id);
				if (voiceMessage != null && !voiceMessage.ClientsReceivedAudioClip.Contains(senderClientId))
				{
					voiceMessage.ClientsReceivedAudioClip.Add(senderClientId);
				}
			}
		}

		private void VoiceMessageTimedout_Server(int id)
		{
			if (NetworkUtils.IsServer)
			{
				VoiceMessageTimedout_ClientRpc(id);
				VoiceMessageTimedout_Local(id);
			}
		}

		[ClientRpc]
		private void VoiceMessageTimedout_ClientRpc(int id)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3812723390u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, id);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3812723390u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				if (!NetworkUtils.IsServer)
				{
					VoiceMessageTimedout_Local(id);
				}
			}
		}

		private void VoiceMessageTimedout_Local(int id)
		{
			VoiceMessage voiceMessage = GetVoiceMessage(id);
			if (voiceMessage != null)
			{
				if (IsLocal)
				{
					string text = "TTS audio for \"" + voiceMessage.VoiceName + "\" timed out";
					LogError(text);
					Utils.DisplayMessage(text, isError: true);
				}
				_voiceMessageQueue.Remove(voiceMessage);
			}
		}

		[ClientRpc]
		private void PlayVoiceMessage_ClientRpc(int id)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(544932966u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, id);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 544932966u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.__rpc_exec_stage = (__RpcExecStage)0;
					PlayVoiceMessage_Local(id);
				}
			}
		}

		private void PlayVoiceMessage_Local(int id)
		{
			VoiceMessage voiceMessage = GetVoiceMessage(id);
			if (voiceMessage == null)
			{
				LogWarning($"Failed to play VoiceMessage. Could not find VoiceMessage. (Id: {id})", extended: true);
				return;
			}
			if ((Object)(object)voiceMessage.AudioClip == (Object)null)
			{
				LogWarning($"Failed to play VoiceMessage. AudioClip is null. {voiceMessage}", extended: true);
				_voiceMessageQueue.Remove(voiceMessage);
				return;
			}
			LogInfo($"Playing VoiceMessage. {voiceMessage}", extended: true);
			float num = ConfigManager.TTS_MasterVolume.Value;
			VoiceService service = VoiceService.Unknown;
			if (TextToSpeech.TryGetVoiceByName(voiceMessage.VoiceName, out var result))
			{
				service = result.Service;
			}
			float serviceMasterVolume = ConfigManager.GetServiceMasterVolume(service);
			float num2 = 100f;
			if (VoiceConfigManager.TryGetVoiceConfigEntry(voiceMessage.VoiceName, out var voiceConfigEntry))
			{
				num2 = voiceConfigEntry.Volume.Value;
			}
			AudioClip clip = AudioUtils.CreateAdjustedClip(voiceMessage.AudioClip, num, serviceMasterVolume, num2);
			UpdateVoiceMute();
			PlayerAudioGroup.Clip = clip;
			PlayerAudioGroup.Play();
			_voiceMessageQueue.Remove(voiceMessage);
		}

		private void ApplySettings()
		{
			if (PlayerAudioGroup != null)
			{
				UpdateVoiceMute();
				PlayerAudioGroup.MaxDistance = ConfigManager.TTS_MaxDistance.Value;
			}
		}

		public static void HandleConfigSettingsChanged()
		{
			foreach (VoiceController instance in _instances)
			{
				instance.ApplySettings();
			}
		}

		private void Log(LogLevel logLevel, object data, bool extended = false)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			string arg = (((Object)(object)PlayerScript == (Object)null) ? ("[" + ((object)this).GetType().Name + "]") : ("[" + ((object)this).GetType().Name + " : " + PlayerScript.playerUsername + "]"));
			Logger.Log(logLevel, $"{arg} {data}", extended);
		}

		private void LogInfo(object data, bool extended = false)
		{
			Log((LogLevel)16, data, extended);
		}

		private void LogWarning(object data, bool extended = false)
		{
			Log((LogLevel)4, data, extended);
		}

		private void LogError(object data, bool extended = false)
		{
			Log((LogLevel)2, data, extended);
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(2160464779u, new RpcReceiveHandler(__rpc_handler_2160464779), "CreateVoiceMessage_ServerRpc");
			((NetworkBehaviour)this).__registerRpc(1380029231u, new RpcReceiveHandler(__rpc_handler_1380029231), "CreateVoiceMessage_ClientRpc");
			((NetworkBehaviour)this).__registerRpc(4045068609u, new RpcReceiveHandler(__rpc_handler_4045068609), "DeleteVoiceMessage_ServerRpc");
			((NetworkBehaviour)this).__registerRpc(2880339731u, new RpcReceiveHandler(__rpc_handler_2880339731), "DeleteVoiceMessage_ClientRpc");
			((NetworkBehaviour)this).__registerRpc(1252295788u, new RpcReceiveHandler(__rpc_handler_1252295788), "StreamAudioChunk_ServerRpc");
			((NetworkBehaviour)this).__registerRpc(2319454299u, new RpcReceiveHandler(__rpc_handler_2319454299), "StreamAudioChunk_ClientRpc");
			((NetworkBehaviour)this).__registerRpc(3290872701u, new RpcReceiveHandler(__rpc_handler_3290872701), "StreamAudioComplete_ServerRpc");
			((NetworkBehaviour)this).__registerRpc(4122899824u, new RpcReceiveHandler(__rpc_handler_4122899824), "StreamAudioComplete_ClientRpc");
			((NetworkBehaviour)this).__registerRpc(2085373701u, new RpcReceiveHandler(__rpc_handler_2085373701), "ReceivedVoiceMessageAudioClip_ServerRpc");
			((NetworkBehaviour)this).__registerRpc(3812723390u, new RpcReceiveHandler(__rpc_handler_3812723390), "VoiceMessageTimedout_ClientRpc");
			((NetworkBehaviour)this).__registerRpc(544932966u, new RpcReceiveHandler(__rpc_handler_544932966), "PlayVoiceMessage_ClientRpc");
			((NetworkBehaviour)this).__initializeRpcs();
		}

		private static void __rpc_handler_2160464779(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
				return;
			}
			bool flag = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
			string voiceName = null;
			if (flag)
			{
				((FastBufferReader)(ref reader)).ReadValueSafe(ref voiceName, false);
			}
			bool flag2 = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives));
			string message = null;
			if (flag2)
			{
				((FastBufferReader)(ref reader)).ReadValueSafe(ref message, false);
			}
			ServerRpcParams server = rpcParams.Server;
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((VoiceController)(object)target).CreateVoiceMessage_ServerRpc(voiceName, message, server);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}

		private static void __rpc_handler_1380029231(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0042: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int id = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref id);
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string voiceName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref voiceName, false);
				}
				bool flag2 = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives));
				string message = null;
				if (flag2)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref message, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((VoiceController)(object)target).CreateVoiceMessage_ClientRpc(id, voiceName, message);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4045068609(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			//IL_0083: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
			}
			else
			{
				int id = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref id);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((VoiceController)(object)target).DeleteVoiceMessage_ServerRpc(id);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2880339731(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int id = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref id);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((VoiceController)(object)target).DeleteVoiceMessage_ClientRpc(id);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1252295788(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
				return;
			}
			int id = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref id);
			bool flag = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
			float[] chunk = null;
			if (flag)
			{
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref chunk, default(ForPrimitives));
			}
			int channels = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref channels);
			int sampleRate = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref sampleRate);
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((VoiceController)(object)target).StreamAudioChunk_ServerRpc(id, chunk, channels, sampleRate);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}

		private static void __rpc_handler_2319454299(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int id = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref id);
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				float[] chunk = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref chunk, default(ForPrimitives));
				}
				int channels = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref channels);
				int sampleRate = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref sampleRate);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((VoiceController)(object)target).StreamAudioChunk_ClientRpc(id, chunk, channels, sampleRate);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private sta