Decompiled source of MelaniesVoice v1.3.0

com.github.zehsteam.MelaniesVoice.dll

Decompiled 2 weeks 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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
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.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("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.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+8a14eece50ef9e62c61128d889ea7e74f86157c4")]
[assembly: AssemblyProduct("MelaniesVoice")]
[assembly: AssemblyTitle("com.github.zehsteam.MelaniesVoice")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.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
	{
		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);
		}
	}
	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.3.0")]
	[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(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.3.0";
	}
}
namespace com.github.zehsteam.MelaniesVoice.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal static class GameNetworkManagerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch()
		{
			AddNetworkPrefabs();
		}

		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(chatMessage, ConfigManager.TTS_Voice.Value);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerBPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch(ref PlayerControllerB __instance)
		{
			if (NetworkUtils.IsServer)
			{
				GameObject val = Object.Instantiate<GameObject>(Assets.VoiceControllerPrefab, ((Component)__instance).transform);
				val.GetComponent<NetworkObject>().Spawn(false);
				val.transform.SetParent(((Component)__instance).transform);
			}
		}

		[HarmonyPatch("OnDestroy")]
		[HarmonyPrefix]
		private static void OnDestroyPatch(ref 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);
				}
			}
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Objects
{
	public class PlayerAudioGroup
	{
		public AudioSource VoiceAudio;

		public AudioSource DeadAudio;

		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 class VoiceMessage
	{
		private float _timer;

		public int Id { get; private set; }

		public string Message { get; private set; }

		public string Voice { get; private set; }

		public AudioClip AudioClip { get; set; }

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


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

		public bool IsTimedout => _timer >= 15f;

		public VoiceMessage(int id, string message, string voice)
		{
			Id = id;
			Message = message;
			Voice = voice;
		}

		public void Tick()
		{
			_timer += Time.deltaTime;
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Objects.Config
{
	public class VoiceConfigEntry
	{
		public string Voice { get; private set; }

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

		public VoiceConfigEntry(string voice, float defaultVolume)
		{
			Bind(voice, defaultVolume);
		}

		private void Bind(string voice, float defaultVolume)
		{
			Voice = voice;
			string section = Voice + " Voice";
			Volume = ConfigHelper.Bind(section, "Volume", defaultVolume, "The volume of the voice.", requiresRestart: false, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f));
		}
	}
}
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
	{
		[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;

		public PlayerAudioGroup PlayerAudioGroup { get; private set; }

		public PlayerControllerB PlayerScript { get; private set; }

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

		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);
				UpdateSettings();
				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)
			{
				_voiceMessageQueue.RemoveAt(0);
			}
		}

		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 UpdateSettings()
		{
			if (PlayerAudioGroup != null)
			{
				UpdateVoiceMute();
				PlayerAudioGroup.MaxDistance = ConfigManager.TTS_MaxDistance.Value;
			}
		}

		public static void OnSettingsChanged(object sender, EventArgs e)
		{
			VoiceController[] array = Object.FindObjectsByType<VoiceController>((FindObjectsSortMode)0);
			foreach (VoiceController voiceController in array)
			{
				voiceController.UpdateSettings();
			}
		}

		private float GetVoiceVolume(string voice)
		{
			float value = ConfigManager.TTS_MasterVolume.Value;
			float num = 100f;
			if (VoiceConfigManager.TryGetVoiceConfigEntry(voice, out var voiceConfigEntry))
			{
				num = voiceConfigEntry.Volume.Value;
			}
			float num2 = value / 100f;
			return num * num2;
		}

		private void UpdateVoiceVolume(string voice)
		{
			if (PlayerAudioGroup != null)
			{
				float num = Mathf.Clamp(GetVoiceVolume(voice), 0f, 100f);
				PlayerAudioGroup.Volume = num * 0.01f;
			}
		}

		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 AudioClip GetAmplifiedAudioClip(AudioClip audioClip, string voice)
		{
			if ((Object)(object)audioClip == (Object)null)
			{
				return null;
			}
			float voiceVolume = GetVoiceVolume(voice);
			float num = voiceVolume - 100f;
			if (num <= 0f)
			{
				return audioClip;
			}
			float decibelChange = Mathf.Clamp(num / 10f, 0f, 20f);
			return AudioUtils.AmplifyClipByDecibels(audioClip, decibelChange);
		}

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

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

		[ServerRpc(RequireOwnership = false)]
		public void CreateVoiceMessage_ServerRpc(string message, string voice, 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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(2160464779u, serverRpcParams, (RpcDelivery)0);
				bool flag = message != null;
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val)).WriteValueSafe(message, false);
				}
				bool flag2 = voice != null;
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
				if (flag2)
				{
					((FastBufferWriter)(ref val)).WriteValueSafe(voice, 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, message, voice);
				}
			}
		}

		[ClientRpc]
		private void CreateVoiceMessage_ClientRpc(int id, string message, string voice)
		{
			//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 = message != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(message, false);
				}
				bool flag2 = voice != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
				if (flag2)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(voice, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1380029231u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				VoiceMessage voiceMessage = new VoiceMessage(id, message, voice);
				_voiceMessageQueue.Add(voiceMessage);
				LogInfo($"Created VoiceMessage. (Id: {voiceMessage.Id}, Message: \"{voiceMessage.Message}\", Voice: {voiceMessage.Voice})", extended: true);
				if (!NetworkUtils.IsServer && IsLocal && !ConfigManager.TTS_HearMyself.Value)
				{
					OnReceivedVoiceMessageAudioClip(voiceMessage.Id, null);
				}
				else
				{
					TextToSpeech.GetAudioClip(voiceMessage.Id, voiceMessage.Message, voiceMessage.Voice, OnReceivedVoiceMessageAudioClip);
				}
			}
		}

		private void OnReceivedVoiceMessageAudioClip(int id, AudioClip audioClip)
		{
			//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)
			if ((Object)(object)audioClip == (Object)null)
			{
				LogInfo($"OnReceivedVoiceMessageAudioClip(); AudioClip is null! Id: {id}", extended: true);
			}
			VoiceMessage voiceMessage = GetVoiceMessage(id);
			if (voiceMessage != null)
			{
				voiceMessage.AudioClip = audioClip;
				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);
				}
			}
		}

		[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. (Id: {voiceMessage.Id}, Message: \"{voiceMessage.Message}\", Voice: {voiceMessage.Voice})", extended: true);
				_voiceMessageQueue.Remove(voiceMessage);
				return;
			}
			LogInfo($"Playing VoiceMessage. (Id: {voiceMessage.Id}, Message: \"{voiceMessage.Message}\", Voice: {voiceMessage.Voice})", extended: true);
			UpdateVoiceVolume(voiceMessage.Voice);
			UpdateVoiceMute();
			AudioClip amplifiedAudioClip = GetAmplifiedAudioClip(voiceMessage.AudioClip, voiceMessage.Voice);
			PlayVoiceMessageAudioClip(amplifiedAudioClip);
			_voiceMessageQueue.Remove(voiceMessage);
		}

		private void PlayVoiceMessageAudioClip(AudioClip audioClip)
		{
			PlayerAudioGroup.Clip = audioClip;
			PlayerAudioGroup.Play();
		}

		private void LogInfo(object data, bool extended = false)
		{
			Logger.LogInfo(GetLogHeader() + " " + data, extended);
		}

		private void LogWarning(object data, bool extended = false)
		{
			Logger.LogWarning(GetLogHeader() + " " + data, extended);
		}

		private void LogError(object data, bool extended = false)
		{
			Logger.LogError(GetLogHeader() + " " + data, extended);
		}

		private string GetLogHeader()
		{
			if (!((Object)(object)PlayerScript == (Object)null))
			{
				return "[VoiceController : " + PlayerScript.playerUsername + "]";
			}
			return "[VoiceController]";
		}

		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
			((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(2085373701u, new RpcReceiveHandler(__rpc_handler_2085373701), "ReceivedVoiceMessageAudioClip_ServerRpc");
			((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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string message = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref message, false);
				}
				bool flag2 = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives));
				string voice = null;
				if (flag2)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref voice, false);
				}
				ServerRpcParams server = rpcParams.Server;
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((VoiceController)(object)target).CreateVoiceMessage_ServerRpc(message, voice, 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 message = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref message, false);
				}
				bool flag2 = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives));
				string voice = null;
				if (flag2)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref voice, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((VoiceController)(object)target).CreateVoiceMessage_ClientRpc(id, message, voice);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

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

		private static void __rpc_handler_544932966(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).PlayVoiceMessage_ClientRpc(id);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "VoiceController";
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Managers
{
	internal static class ConfigManager
	{
		public static ConfigFile ConfigFile { get; private set; }

		public static ConfigEntry<bool> ExtendedLogging { get; private set; }

		public static ConfigEntry<bool> TTS_DisableMyVoice { get; private set; }

		public static ConfigEntry<string> TTS_IgnorePefixes { get; private set; }

		public static ConfigEntry<string> TTS_Voice { get; private set; }

		public static ConfigEntry<float> TTS_MasterVolume { get; private set; }

		public static ConfigEntry<bool> TTS_HearMyself { get; private set; }

		public static ConfigEntry<float> TTS_MaxDistance { get; private set; }

		public static string[] TTS_IgnorePefixesArray
		{
			get
			{
				return com.github.zehsteam.MelaniesVoice.Extensions.CollectionExtensions.StringToCollection<string>(TTS_IgnorePefixes.Value).ToArray();
			}
			set
			{
				TTS_IgnorePefixes.Value = com.github.zehsteam.MelaniesVoice.Extensions.CollectionExtensions.CollectionToString(value);
			}
		}

		public static void Initialize(ConfigFile configFile)
		{
			ConfigFile = configFile;
			BindConfigs();
		}

		private static void BindConfigs()
		{
			ConfigHelper.SkipAutoGen();
			ExtendedLogging = ConfigHelper.Bind("General", "ExtendedLogging", defaultValue: false, "Enable extended logging.");
			TTS_DisableMyVoice = ConfigHelper.Bind("Text-To-Speech", "DisableMyVoice", defaultValue: false, "If enabled, your chat messages won't trigger your text-to-speech voice.");
			TTS_IgnorePefixes = ConfigHelper.Bind("Text-To-Speech", "IgnorePefixes", "/, !", "List of prefixes that won't trigger your text-to-speech voice.\nComma-separated values.");
			TTS_Voice = ConfigHelper.Bind("Text-To-Speech", "Voice", TextToSpeech.Voices[0], "Your text-to-speech voice.", requiresRestart: false, (AcceptableValueBase)(object)new AcceptableValueList<string>(TextToSpeech.Voices));
			TTS_MasterVolume = ConfigHelper.Bind("Text-To-Speech", "MasterVolume", 100f, "The master volume for all voices.", requiresRestart: false, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f));
			TTS_HearMyself = ConfigHelper.Bind("Text-To-Speech", "HearMyself", defaultValue: true, "If enabled, you will hear your own voice.");
			TTS_MaxDistance = ConfigHelper.Bind("Text-To-Speech", "MaxDistance", 40f, "The max distance you will hear other players voice.");
			TTS_HearMyself.SettingChanged += VoiceController.OnSettingsChanged;
			TTS_MaxDistance.SettingChanged += VoiceController.OnSettingsChanged;
			VoiceConfigManager.BindConfigs();
		}
	}
	internal static class TextToSpeech
	{
		[CompilerGenerated]
		private sealed class <GetAudioClipFromAPI>d__3 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string voice;

			public string text;

			public Action<int, AudioClip> onClipReady;

			public int id;

			private UnityWebRequest <www>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Invalid comparison between Unknown and I4
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Invalid comparison between Unknown and I4
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
					{
						<>1__state = -1;
						if (!Voices.Contains(voice))
						{
							voice = GetRandomVoice();
						}
						string text = "https://api.streamelements.com/kappa/v2/speech?voice=" + voice + "&text=" + UnityWebRequest.EscapeURL(this.text);
						Logger.LogInfo("[TextToSpeech] Sending GET request to " + text, extended: true);
						<www>5__2 = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)13);
						<>1__state = -3;
						<>2__current = <www>5__2.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					}
					case 1:
						<>1__state = -3;
						if ((int)<www>5__2.result == 2 || (int)<www>5__2.result == 3)
						{
							Logger.LogError("[TextToSpeech] Error fetching audio: " + <www>5__2.error);
							onClipReady(id, null);
						}
						else
						{
							AudioClip content = DownloadHandlerAudioClip.GetContent(<www>5__2);
							onClipReady(id, content);
						}
						result = false;
						<>m__Finally1();
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

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

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

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

		private const string _apiUrl = "https://api.streamelements.com/kappa/v2/speech";

		public static readonly string[] Voices = new string[3] { "Brian", "Salli", "Justin" };

		public static void GetAudioClip(int id, string text, string voice, Action<int, AudioClip> onClipReady)
		{
			CoroutineRunner.Start(GetAudioClipFromAPI(id, text, voice, onClipReady));
		}

		[IteratorStateMachine(typeof(<GetAudioClipFromAPI>d__3))]
		private static IEnumerator GetAudioClipFromAPI(int id, string text, string voice, Action<int, AudioClip> onClipReady)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetAudioClipFromAPI>d__3(0)
			{
				id = id,
				text = text,
				voice = voice,
				onClipReady = onClipReady
			};
		}

		public static string GetRandomVoice()
		{
			return Voices[Random.Range(0, Voices.Length)];
		}
	}
	internal static class VoiceConfigManager
	{
		public static List<VoiceConfigEntry> Entries { get; private set; } = new List<VoiceConfigEntry>();


		public static void BindConfigs()
		{
			string[] voices = TextToSpeech.Voices;
			foreach (string voice in voices)
			{
				Entries.Add(new VoiceConfigEntry(voice, 100f));
			}
		}

		public static VoiceConfigEntry GetVoiceConfigEntry(string voice)
		{
			return Entries.FirstOrDefault((VoiceConfigEntry x) => x.Voice.Equals(voice, StringComparison.OrdinalIgnoreCase));
		}

		public static bool TryGetVoiceConfigEntry(string voice, out VoiceConfigEntry voiceConfigEntry)
		{
			voiceConfigEntry = GetVoiceConfigEntry(voice);
			return voiceConfigEntry != null;
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Helpers
{
	internal static class AudioUtils
	{
		public static AudioClip AmplifyClipByDecibels(AudioClip originalClip, float decibelChange)
		{
			if ((Object)(object)originalClip == (Object)null)
			{
				return null;
			}
			float num = Mathf.Pow(10f, decibelChange / 20f);
			float[] array = new float[originalClip.samples * originalClip.channels];
			originalClip.GetData(array, 0);
			for (int i = 0; i < array.Length; i++)
			{
				array[i] *= num;
				array[i] = Mathf.Clamp(array[i], -1f, 1f);
			}
			AudioClip val = AudioClip.Create("AmplifiedClip", originalClip.samples, originalClip.channels, originalClip.frequency, false);
			val.SetData(array, 0);
			return val;
		}

		public static float Remap(float value, float inputMin, float inputMax, float outputMin, float outputMax)
		{
			float num = (value - inputMin) / (inputMax - inputMin);
			return outputMin + num * (outputMax - outputMin);
		}
	}
	internal static class ConfigHelper
	{
		public static void SkipAutoGen()
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.SkipAutoGen();
			}
		}

		public static void AddButton(string section, string name, string buttonText, string description, Action callback)
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.AddButton(section, name, buttonText, description, callback);
			}
		}

		public static ConfigEntry<string> Bind(string section, string key, string defaultValue, string description, bool requiresRestart = false, AcceptableValueBase acceptableValues = null, Action<string> settingChanged = null, ConfigFile configFile = null)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (configFile == null)
			{
				configFile = Plugin.Instance.Config;
			}
			ConfigEntry<string> configEntry = ((acceptableValues == null) ? configFile.Bind<string>(section, key, defaultValue, description) : configFile.Bind<string>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>())));
			if (settingChanged != null)
			{
				configEntry.SettingChanged += delegate
				{
					settingChanged?.Invoke(configEntry.Value);
				};
			}
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.AddConfig<string>(configEntry, requiresRestart);
			}
			return configEntry;
		}

		public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, bool requiresRestart = false, AcceptableValueBase acceptableValues = null, Action<T> settingChanged = null, ConfigFile configFile = null)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (configFile == null)
			{
				configFile = Plugin.Instance.Config;
			}
			ConfigEntry<T> configEntry = ((acceptableValues == null) ? configFile.Bind<T>(section, key, defaultValue, description) : configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>())));
			if (settingChanged != null)
			{
				configEntry.SettingChanged += delegate
				{
					settingChanged?.Invoke(configEntry.Value);
				};
			}
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.AddConfig<T>(configEntry, requiresRestart);
			}
			return configEntry;
		}
	}
	internal static class NetworkUtils
	{
		public static bool IsConnected
		{
			get
			{
				NetworkManager singleton = NetworkManager.Singleton;
				if (singleton == null)
				{
					return false;
				}
				return singleton.IsConnectedClient;
			}
		}

		public static bool IsServer
		{
			get
			{
				NetworkManager singleton = NetworkManager.Singleton;
				if (singleton == null)
				{
					return false;
				}
				return singleton.IsServer;
			}
		}

		public static bool IsHost
		{
			get
			{
				NetworkManager singleton = NetworkManager.Singleton;
				if (singleton == null)
				{
					return false;
				}
				return singleton.IsHost;
			}
		}

		public static ulong GetLocalClientId()
		{
			return NetworkManager.Singleton.LocalClientId;
		}

		public static bool IsLocalClientId(ulong clientId)
		{
			return clientId == GetLocalClientId();
		}
	}
	internal static class PlayerUtils
	{
		public static PlayerControllerB GetLocalPlayerScript()
		{
			return GameNetworkManager.Instance?.localPlayerController;
		}

		public static bool IsLocalPlayer(PlayerControllerB playerScript)
		{
			return (Object)(object)playerScript == (Object)(object)GetLocalPlayerScript();
		}

		public static PlayerControllerB GetPlayerScriptByClientId(ulong clientId)
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.actualClientId == clientId)
				{
					return val;
				}
			}
			return null;
		}

		public static PlayerControllerB GetPlayerScriptByPlayerId(int playerId)
		{
			if (playerId < 0 || playerId > StartOfRound.Instance.allPlayerScripts.Length - 1)
			{
				return null;
			}
			return StartOfRound.Instance.allPlayerScripts[playerId];
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Extensions
{
	internal static class CollectionExtensions
	{
		public static IEnumerable<T> StringToCollection<T>(string s, string separator = ",")
		{
			if (string.IsNullOrEmpty(s))
			{
				return Array.Empty<T>();
			}
			T result;
			return from x in s.Split(separator, StringSplitOptions.RemoveEmptyEntries)
				where !string.IsNullOrWhiteSpace(x)
				select x.Trim() into x
				select (!x.TryConvertTo<T>(out result)) ? default(T) : result into x
				where x != null
				select x;
		}

		public static string CollectionToString<T>(IEnumerable<T> value, string separator = ", ")
		{
			if (value == null || !value.Any())
			{
				return string.Empty;
			}
			return string.Join(separator, from x in value
				where x != null && !string.IsNullOrWhiteSpace(x.ToString())
				select x.ToString().Trim());
		}
	}
	internal static class StringExtensions
	{
		public static T ConvertTo<T>(this string s)
		{
			Type typeFromHandle = typeof(T);
			if ((object)typeFromHandle != null)
			{
				Type type = typeFromHandle;
				object obj;
				if (type == typeof(int) && int.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
				{
					obj = result;
				}
				else
				{
					Type type2 = typeFromHandle;
					if (type2 == typeof(float) && float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
					{
						obj = result2;
					}
					else
					{
						Type type3 = typeFromHandle;
						if (type3 == typeof(double) && double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
						{
							obj = result3;
						}
						else
						{
							Type type4 = typeFromHandle;
							if (type4 == typeof(bool) && bool.TryParse(s, out var result4))
							{
								obj = result4;
							}
							else
							{
								Type type5 = typeFromHandle;
								if (type5 == typeof(string))
								{
									obj = s;
								}
								else
								{
									Type type6 = typeFromHandle;
									if (!type6.IsEnum || !Enum.TryParse(type6, s, ignoreCase: true, out object result5))
									{
										goto IL_0121;
									}
									obj = result5;
								}
							}
						}
					}
				}
				object obj2 = obj;
				return (T)obj2;
			}
			goto IL_0121;
			IL_0121:
			throw new NotSupportedException($"Unsupported value type: {typeof(T)}");
		}

		public static bool TryConvertTo<T>(this string s, out T result)
		{
			try
			{
				result = s.ConvertTo<T>();
				return true;
			}
			catch
			{
				result = default(T);
				return false;
			}
		}

		public static bool EqualsAny(this string s, string[] values, StringComparison comparisonType = StringComparison.CurrentCulture)
		{
			return values.Any((string value) => s.Equals(value, comparisonType));
		}

		public static bool ContainsAny(this string s, string[] values, StringComparison comparisonType = StringComparison.CurrentCulture)
		{
			return values.Any((string value) => s.Contains(value, comparisonType));
		}

		public static bool StartsWithAny(this string s, string[] values, StringComparison comparisonType = StringComparison.CurrentCulture)
		{
			return values.Any((string value) => s.StartsWith(value, comparisonType));
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Dependencies
{
	internal static class LethalConfigProxy
	{
		public const string PLUGIN_GUID = "ainavt.lc.lethalconfig";

		private static bool? _enabled;

		public static bool Enabled
		{
			get
			{
				bool valueOrDefault = _enabled.GetValueOrDefault();
				if (!_enabled.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig");
					_enabled = valueOrDefault;
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SkipAutoGen()
		{
			LethalConfigManager.SkipAutoGen();
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfig<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			AcceptableValueBase acceptableValues = ((ConfigEntryBase)configEntry).Description.AcceptableValues;
			if (acceptableValues != null)
			{
				if (acceptableValues is AcceptableValueRange<float> || acceptableValues is AcceptableValueRange<int>)
				{
					AddConfigSlider<T>(configEntry, requiresRestart);
					return;
				}
				if (acceptableValues is AcceptableValueList<string>)
				{
					AddConfigDropdown<T>(configEntry, requiresRestart);
					return;
				}
			}
			if (!(configEntry is ConfigEntry<string> val))
			{
				if (!(configEntry is ConfigEntry<bool> val2))
				{
					if (!(configEntry is ConfigEntry<float> val3))
					{
						if (!(configEntry is ConfigEntry<int> val4))
						{
							throw new NotSupportedException($"Unsupported type: {typeof(T)}");
						}
						LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(val4, requiresRestart));
					}
					else
					{
						LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(val3, requiresRestart));
					}
				}
				else
				{
					LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(val2, requiresRestart));
				}
			}
			else
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(val, requiresRestart));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfigSlider<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			if (!(configEntry is ConfigEntry<float> val))
			{
				if (!(configEntry is ConfigEntry<int> val2))
				{
					throw new NotSupportedException($"Slider not supported for type: {typeof(T)}");
				}
				LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(val2, requiresRestart));
			}
			else
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(val, requiresRestart));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfigDropdown<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			if (configEntry is ConfigEntry<string> val)
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new TextDropDownConfigItem(val, requiresRestart));
				return;
			}
			throw new NotSupportedException($"Dropdown not supported for type: {typeof(T)}");
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddButton(string section, string name, string buttonText, string description, Action callback)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new GenericButtonConfigItem(section, name, description, buttonText, (GenericButtonHandler)delegate
			{
				callback?.Invoke();
			}));
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}