Decompiled source of MelaniesVoice v1.2.0

com.github.zehsteam.MelaniesVoice.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using 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.Data;
using com.github.zehsteam.MelaniesVoice.Dependencies;
using com.github.zehsteam.MelaniesVoice.MonoBehaviours;
using com.github.zehsteam.MelaniesVoice.NetcodePatcher;
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("Allows players to talk through Text-To-Speech (TTS) by using the in-game chat.")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+68a0fd940d2c935af366ba080ee55e604cc02723")]
[assembly: AssemblyProduct("MelaniesVoice")]
[assembly: AssemblyTitle("com.github.zehsteam.MelaniesVoice")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.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 ConfigHelper
	{
		public static void SkipAutoGen()
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.SkipAutoGen();
			}
		}

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

		public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, bool requiresRestart, string description, AcceptableValueBase acceptableValues = null, Action<T> settingChanged = null, ConfigFile configFile = null)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if (configFile == null)
			{
				configFile = Plugin.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;
		}

		public static Dictionary<ConfigDefinition, string> GetOrphanedConfigEntries(ConfigFile configFile = null)
		{
			if (configFile == null)
			{
				configFile = Plugin.Config;
			}
			PropertyInfo property = ((object)configFile).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			return (Dictionary<ConfigDefinition, string>)property.GetValue(configFile, null);
		}

		public static void SetConfigEntryValue<T>(ConfigEntry<T> configEntry, string value)
		{
			if (typeof(T) == typeof(int) && int.TryParse(value, out var result))
			{
				configEntry.Value = (T)(object)result;
				return;
			}
			if (typeof(T) == typeof(float) && float.TryParse(value, out var result2))
			{
				configEntry.Value = (T)(object)result2;
				return;
			}
			if (typeof(T) == typeof(double) && double.TryParse(value, out var result3))
			{
				configEntry.Value = (T)(object)result3;
				return;
			}
			if (typeof(T) == typeof(bool) && bool.TryParse(value, out var result4))
			{
				configEntry.Value = (T)(object)result4;
				return;
			}
			if (typeof(T) == typeof(string))
			{
				configEntry.Value = (T)(object)value;
				return;
			}
			throw new InvalidOperationException($"Unsupported type: {typeof(T)}");
		}

		public static void ClearUnusedEntries(ConfigFile configFile = null)
		{
			if (configFile == null)
			{
				configFile = Plugin.Config;
			}
			Dictionary<ConfigDefinition, string> orphanedConfigEntries = GetOrphanedConfigEntries(configFile);
			if (orphanedConfigEntries != null)
			{
				orphanedConfigEntries.Clear();
				configFile.Save();
			}
		}
	}
	internal class ConfigManager
	{
		public ConfigEntry<bool> ExtendedLogging { get; private set; }

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

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

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

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

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

		public ConfigManager()
		{
			BindConfigs();
			ConfigHelper.ClearUnusedEntries();
		}

		private void BindConfigs()
		{
			ConfigHelper.SkipAutoGen();
			ExtendedLogging = ConfigHelper.Bind("General", "ExtendedLogging", defaultValue: false, requiresRestart: false, "Enable extended logging.");
			TTS_DisableMyVoice = ConfigHelper.Bind("Text-To-Speech", "DisableMyVoice", defaultValue: false, requiresRestart: false, "If enabled, your chat messages won't trigger your text-to-speech voice.");
			TTS_Voice = ConfigHelper.Bind("Text-To-Speech", "Voice", TextToSpeech.Voices[0], requiresRestart: false, "Your text-to-speech voice.", (AcceptableValueBase)(object)new AcceptableValueList<string>(TextToSpeech.Voices));
			TTS_MasterVolume = ConfigHelper.Bind("Text-To-Speech", "MasterVolume", 100f, requiresRestart: false, "The master volume for all voices.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f));
			TTS_HearMyself = ConfigHelper.Bind("Text-To-Speech", "HearMyself", defaultValue: true, requiresRestart: false, "If enabled, you will hear your own voice.");
			TTS_MaxDistance = ConfigHelper.Bind("Text-To-Speech", "MaxDistance", 40f, requiresRestart: false, "The max distance you will hear other players voice.");
			TTS_HearMyself.SettingChanged += VoiceController.OnSettingsChanged;
			TTS_MaxDistance.SettingChanged += VoiceController.OnSettingsChanged;
			VoiceDataManager.BindConfigs();
		}
	}
	internal static class Content
	{
		public static GameObject VoiceControllerPrefab;

		public static void Load()
		{
			LoadAssetsFromAssetBundle();
		}

		private static void LoadAssetsFromAssetBundle()
		{
			try
			{
				AssetBundle val = LoadAssetBundle("melaniesvoice_assets");
				VoiceControllerPrefab = val.LoadAsset<GameObject>("VoiceController");
				Plugin.Logger.LogInfo((object)"Successfully loaded assets from AssetBundle!");
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to load assets from AssetBundle.\n\n{arg}");
			}
		}

		private static AssetBundle LoadAssetBundle(string fileName)
		{
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location);
			string text = Path.Combine(directoryName, fileName);
			return AssetBundle.LoadFromFile(text);
		}
	}
	internal static class NetworkUtils
	{
		public static bool IsServer
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton == (Object)null)
				{
					return false;
				}
				return NetworkManager.Singleton.IsServer;
			}
		}

		public static bool IsHost
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton == (Object)null)
				{
					return false;
				}
				return NetworkManager.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()
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return null;
			}
			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];
		}
	}
	[BepInPlugin("com.github.zehsteam.MelaniesVoice", "MelaniesVoice", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("com.github.zehsteam.MelaniesVoice");

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static ConfigFile Config { get; private set; }

		internal static ConfigManager ConfigManager { get; private set; }

		private void Awake()
		{
			Instance = this;
			Logger = Logger.CreateLogSource("com.github.zehsteam.MelaniesVoice");
			Logger.LogInfo((object)"MelaniesVoice has awoken!");
			Config = Utils.CreateGlobalConfigFile();
			_harmony.PatchAll(typeof(GameNetworkManagerPatch));
			_harmony.PatchAll(typeof(HUDManagerPatch));
			_harmony.PatchAll(typeof(PlayerControllerBPatch));
			Content.Load();
			ConfigManager = new ConfigManager();
			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)
								{
									Logger.LogWarning((object)("Failed to invoke method " + methodInfo.Name + ": " + ex.Message));
								}
							}
						}
						catch (Exception ex2)
						{
							Logger.LogWarning((object)("Error processing method " + methodInfo.Name + " in type " + type.Name + ": " + ex2.Message));
						}
					}
				}
			}
			catch (Exception ex3)
			{
				Logger.LogError((object)("An error occurred in NetcodePatcherAwake: " + ex3.Message));
			}
		}

		public void LogInfoExtended(object data)
		{
			LogExtended((LogLevel)16, data);
		}

		public void LogWarningExtended(object data)
		{
			LogExtended((LogLevel)4, data);
		}

		public void LogExtended(LogLevel level, object data)
		{
			//IL_0018: 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)
			if (ConfigManager == null || ConfigManager.ExtendedLogging == null)
			{
				Logger.Log(level, data);
			}
			else if (ConfigManager.ExtendedLogging.Value)
			{
				Logger.Log(level, data);
			}
		}
	}
	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_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Invalid comparison between Unknown and I4
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: 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);
						Plugin.Instance.LogInfoExtended("[TextToSpeech] Sending GET request to " + text);
						<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)
						{
							Plugin.Logger.LogError((object)("[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)
		{
			Utils.StartCoroutine(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 Utils
	{
		public static ConfigFile CreateConfigFile(string path, string name = null, bool saveOnInit = false)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			BepInPlugin metadata = MetadataHelper.GetMetadata((object)Plugin.Instance);
			if (name == null)
			{
				name = metadata.GUID;
			}
			name += ".cfg";
			return new ConfigFile(Path.Combine(path, name), saveOnInit, metadata);
		}

		public static ConfigFile CreateLocalConfigFile(string name = null, bool saveOnInit = false)
		{
			BepInPlugin metadata = MetadataHelper.GetMetadata((object)Plugin.Instance);
			if (name == null)
			{
				name = metadata.GUID + "-" + name;
			}
			return CreateConfigFile(Paths.ConfigPath, name, saveOnInit);
		}

		public static ConfigFile CreateGlobalConfigFile(string name = null, bool saveOnInit = false)
		{
			BepInPlugin metadata = MetadataHelper.GetMetadata((object)Plugin.Instance);
			string path = Path.Combine(Application.persistentDataPath, metadata.Name);
			if (name == null)
			{
				name = "global";
			}
			return CreateConfigFile(path, name, saveOnInit);
		}

		public static bool RemoveByValue<TKey, TValue>(Dictionary<TKey, TValue> dictionary, TValue value)
		{
			foreach (KeyValuePair<TKey, TValue> item in dictionary)
			{
				if (EqualityComparer<TValue>.Default.Equals(item.Value, value))
				{
					dictionary.Remove(item.Key);
					return true;
				}
			}
			return false;
		}

		public static Coroutine StartCoroutine(IEnumerator routine)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				return ((MonoBehaviour)Plugin.Instance).StartCoroutine(routine);
			}
			if ((Object)(object)GameNetworkManager.Instance != (Object)null)
			{
				return ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(routine);
			}
			Plugin.Logger.LogError((object)("Failed to start coroutine. " + routine));
			return null;
		}

		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 VoiceDataManager
	{
		public static List<VoiceConfigData> VoiceDataList { get; private set; } = new List<VoiceConfigData>();


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

		public static VoiceConfigData GetVoiceData(string voice)
		{
			foreach (VoiceConfigData voiceData in VoiceDataList)
			{
				if (voiceData.Voice == voice)
				{
					return voiceData;
				}
			}
			return null;
		}

		public static bool TryGetVoiceData(string voice, out VoiceConfigData voiceConfigData)
		{
			voiceConfigData = GetVoiceData(voice);
			return voiceConfigData != null;
		}
	}
	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.2.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(Content.VoiceControllerPrefab);
		}

		private static void AddNetworkPrefab(GameObject prefab)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				Plugin.Logger.LogError((object)"Failed to register network prefab. GameObject is null.");
				return;
			}
			NetworkManager.Singleton.AddNetworkPrefab(prefab);
			Plugin.Logger.LogInfo((object)("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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (playerId == -1 || Plugin.ConfigManager.TTS_DisableMyVoice.Value)
			{
				return;
			}
			PlayerControllerB localPlayerScript = PlayerUtils.GetLocalPlayerScript();
			if (!((Object)(object)localPlayerScript == (Object)null))
			{
				VoiceController componentInChildren = ((Component)localPlayerScript).GetComponentInChildren<VoiceController>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					componentInChildren.CreateVoiceMessageServerRpc(chatMessage, Plugin.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>(Content.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.MonoBehaviours
{
	public class VoiceController : NetworkBehaviour
	{
		[SerializeField]
		public AudioSource _audioSource;

		[SerializeField]
		public AudioSource _deadAudioSource;

		public VoiceAudioSource VoiceAudioSource;

		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 PlayerControllerB PlayerScript { get; private set; }

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

		private void Start()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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);
				VoiceAudioSource = new VoiceAudioSource(_audioSource, _deadAudioSource);
				UpdateSettings();
				LogInfoExtended("Initialized.");
			}
		}

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

		private void VoiceMessageTick()
		{
			if (!NetworkUtils.IsServer || VoiceAudioSource == null || VoiceAudioSource.IsPlaying || _voiceMessageQueue.Count == 0)
			{
				return;
			}
			VoiceMessage voiceMessage = _voiceMessageQueue[0];
			if (voiceMessage == null)
			{
				_voiceMessageQueue.RemoveAt(0);
				return;
			}
			if (voiceMessage.IsReady)
			{
				PlayVoiceMessageClientRpc(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 && VoiceAudioSource != null && VoiceAudioSource.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 (VoiceAudioSource != null)
			{
				UpdateVoiceMute();
				VoiceAudioSource.MaxDistance = Plugin.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 = Plugin.ConfigManager.TTS_MasterVolume.Value;
			float num = 100f;
			if (VoiceDataManager.TryGetVoiceData(voice, out var voiceConfigData))
			{
				num = voiceConfigData.Volume.Value;
			}
			float num2 = value / 100f;
			return num * num2;
		}

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

		private void UpdateVoiceMute()
		{
			if ((Object)(object)PlayerScript == (Object)null || VoiceAudioSource == null)
			{
				return;
			}
			if (IsLocal)
			{
				VoiceAudioSource.Mute = !Plugin.ConfigManager.TTS_HearMyself.Value;
				if (!VoiceAudioSource.Mute)
				{
					VoiceAudioSource.AudioSource.mute = PlayerScript.isPlayerDead;
					VoiceAudioSource.DeadAudioSource.mute = !PlayerScript.isPlayerDead;
				}
			}
			else
			{
				VoiceAudioSource.AudioSource.mute = PlayerScript.isPlayerDead;
				PlayerControllerB localPlayerScript = PlayerUtils.GetLocalPlayerScript();
				if ((Object)(object)localPlayerScript == (Object)null || !localPlayerScript.isPlayerDead)
				{
					VoiceAudioSource.DeadAudioSource.mute = true;
				}
				else
				{
					VoiceAudioSource.DeadAudioSource.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 Utils.AmplifyClipByDecibels(audioClip, decibelChange);
		}

		private VoiceMessage GetVoiceMessage(int id)
		{
			foreach (VoiceMessage item in _voiceMessageQueue)
			{
				if (item.Id == id)
				{
					return item;
				}
			}
			return null;
		}

		[ServerRpc(RequireOwnership = false)]
		public void CreateVoiceMessageServerRpc(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(2570117490u, 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, 2570117490u, 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);
					CreateVoiceMessageClientRpc(id, message, voice);
				}
			}
		}

		[ClientRpc]
		private void CreateVoiceMessageClientRpc(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(2612776477u, 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, 2612776477u, 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);
				LogInfoExtended($"Created VoiceMessage. (Id: {voiceMessage.Id}, Message: \"{voiceMessage.Message}\", Voice: {voiceMessage.Voice})");
				if (!NetworkUtils.IsServer && IsLocal && !Plugin.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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)audioClip == (Object)null)
			{
				LogInfoExtended($"OnReceivedVoiceMessageAudioClip(); AudioClip is null! Id: {id}");
			}
			VoiceMessage voiceMessage = GetVoiceMessage(id);
			if (voiceMessage != null)
			{
				voiceMessage.AudioClip = audioClip;
				ReceivedVoiceMessageAudioClipServerRpc(voiceMessage.Id);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void ReceivedVoiceMessageAudioClipServerRpc(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(1527114313u, serverRpcParams, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, id);
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 1527114313u, 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 PlayVoiceMessageClientRpc(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(3972401569u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, id);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3972401569u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				VoiceMessage voiceMessage = GetVoiceMessage(id);
				if (voiceMessage == null)
				{
					LogWarningExtended($"Failed to play VoiceMessage. Could not find VoiceMessage. (Id: {id})");
					return;
				}
				if ((Object)(object)voiceMessage.AudioClip == (Object)null)
				{
					LogWarningExtended($"Failed to play VoiceMessage. AudioClip is null. (Id: {voiceMessage.Id}, Message: \"{voiceMessage.Message}\", Voice: {voiceMessage.Voice})");
					_voiceMessageQueue.Remove(voiceMessage);
					return;
				}
				LogInfoExtended($"Playing VoiceMessage. (Id: {voiceMessage.Id}, Message: \"{voiceMessage.Message}\", Voice: {voiceMessage.Voice})");
				UpdateVoiceVolume(voiceMessage.Voice);
				UpdateVoiceMute();
				VoiceAudioSource.Clip = GetAmplifiedAudioClip(voiceMessage.AudioClip, voiceMessage.Voice);
				VoiceAudioSource.Play();
				_voiceMessageQueue.Remove(voiceMessage);
			}
		}

		private void LogInfoExtended(object data)
		{
			Plugin.Instance.LogInfoExtended(GetLogHeader() + " " + data);
		}

		private void LogWarningExtended(object data)
		{
			Plugin.Instance.LogWarningExtended(GetLogHeader() + " " + data);
		}

		private void LogWarning(object data)
		{
			Plugin.Logger.LogWarning((object)(GetLogHeader() + " " + data));
		}

		private void LogError(object data)
		{
			Plugin.Logger.LogError((object)(GetLogHeader() + " " + data));
		}

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

		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(2570117490u, new RpcReceiveHandler(__rpc_handler_2570117490), "CreateVoiceMessageServerRpc");
			((NetworkBehaviour)this).__registerRpc(2612776477u, new RpcReceiveHandler(__rpc_handler_2612776477), "CreateVoiceMessageClientRpc");
			((NetworkBehaviour)this).__registerRpc(1527114313u, new RpcReceiveHandler(__rpc_handler_1527114313), "ReceivedVoiceMessageAudioClipServerRpc");
			((NetworkBehaviour)this).__registerRpc(3972401569u, new RpcReceiveHandler(__rpc_handler_3972401569), "PlayVoiceMessageClientRpc");
			((NetworkBehaviour)this).__initializeRpcs();
		}

		private static void __rpc_handler_2570117490(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).CreateVoiceMessageServerRpc(message, voice, server);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2612776477(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).CreateVoiceMessageClientRpc(id, message, voice);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1527114313(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).ReceivedVoiceMessageAudioClipServerRpc(id, server);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

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

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "VoiceController";
		}
	}
}
namespace com.github.zehsteam.MelaniesVoice.Dependencies
{
	internal static class LethalConfigProxy
	{
		public const string PLUGIN_GUID = "ainavt.lc.lethalconfig";

		public static bool Enabled => Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig");

		[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 description, string buttonText, 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 com.github.zehsteam.MelaniesVoice.Data
{
	public class VoiceAudioSource
	{
		public AudioSource AudioSource;

		public AudioSource DeadAudioSource;

		public bool IsPlaying => AudioSource.isPlaying;

		public float Volume
		{
			get
			{
				return AudioSource.volume;
			}
			set
			{
				AudioSource.volume = value;
				DeadAudioSource.volume = value;
			}
		}

		public float MaxDistance
		{
			get
			{
				return AudioSource.maxDistance;
			}
			set
			{
				AudioSource.maxDistance = value;
				DeadAudioSource.maxDistance = value;
			}
		}

		public AudioClip Clip
		{
			get
			{
				return AudioSource.clip;
			}
			set
			{
				AudioSource.clip = value;
				DeadAudioSource.clip = value;
			}
		}

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

		public VoiceAudioSource(AudioSource audioSource, AudioSource deadAudioSource)
		{
			AudioSource = audioSource;
			DeadAudioSource = deadAudioSource;
		}

		public void Play()
		{
			AudioSource.Play();
			DeadAudioSource.Play();
		}

		public void Pause()
		{
			AudioSource.Pause();
			DeadAudioSource.Pause();
		}

		public void Stop()
		{
			AudioSource.Stop();
			DeadAudioSource.Stop();
		}
	}
	public class VoiceConfigData
	{
		public string Voice { get; private set; }

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

		public VoiceConfigData(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, requiresRestart: false, "The volume of the voice.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f));
		}
	}
	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 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
	{
	}
}