Decompiled source of VCLYSS v1.2.3

VCLYSS.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CodeTalker;
using CodeTalker.Networking;
using CodeTalker.Packets;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Nessie.ATLYSS.EasySettings;
using Steamworks;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.VCLYSS.sftwre")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.3.0")]
[assembly: AssemblyInformationalVersion("1.2.3+af76d67a00bc29684d758cad335051c9064f2071")]
[assembly: AssemblyProduct("VCLYSS")]
[assembly: AssemblyTitle("VCLYSS")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 VCLYSS
{
	[BepInPlugin("com.VCLYSS.sftwre", "VCLYSS", "1.2.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		public enum MicMode
		{
			PushToTalk,
			Toggle,
			AlwaysOn
		}

		public static Main Instance;

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private bool _packetsRegistered = false;

		public static ConfigEntry<bool> CfgEnabled;

		public static ConfigEntry<float> CfgMasterVolume;

		public static ConfigEntry<bool> CfgMuteAll;

		public static ConfigEntry<MicMode> CfgMicMode;

		public static ConfigEntry<KeyCode> CfgPushToTalk;

		public static ConfigEntry<float> CfgMicThreshold;

		public static ConfigEntry<bool> CfgMicTest;

		public static ConfigEntry<float> CfgMinDistance;

		public static ConfigEntry<float> CfgMaxDistance;

		public static ConfigEntry<bool> CfgSpatialBlending;

		public static ConfigEntry<bool> CfgRetroMode;

		public static ConfigEntry<bool> CfgShowOverlay;

		public static ConfigEntry<bool> CfgShowHeadIcons;

		public static ConfigEntry<float> CfgBubbleScale;

		public static ConfigEntry<bool> CfgLipSync;

		public static ConfigEntry<bool> CfgDebugMode;

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			InitConfig();
			Settings.OnInitialized.AddListener(new UnityAction(AddSettings));
			Settings.OnApplySettings.AddListener((UnityAction)delegate
			{
				((BaseUnityPlugin)this).Config.Save();
				VoiceSystem.ApplySettingsToAll();
			});
			_harmony = new Harmony("com.VCLYSS.sftwre");
			_harmony.PatchAll();
			GameObject val = new GameObject("VCLYSS_System");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<VoiceSystem>();
			val.AddComponent<VoiceOverlay>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[VCLYSS] Loaded. Voice System Started.");
		}

		public void RegisterPackets()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!_packetsRegistered)
			{
				CodeTalkerNetwork.RegisterBinaryListener<VoicePacket>(new BinaryPacketListener(OnVoicePacketReceived));
				_packetsRegistered = true;
				if (CfgDebugMode.Value)
				{
					Log.LogDebug((object)"Packet Listener Registered.");
				}
			}
		}

		private void OnVoicePacketReceived(PacketHeader header, BinaryPacketBase packet)
		{
			if (!Object.op_Implicit((Object)(object)VoiceSystem.Instance) || !VoiceSystem.Instance.IsSessionReady || !(packet is VoicePacket voicePacket) || voicePacket.VoiceData == null || voicePacket.VoiceData.Length == 0)
			{
				return;
			}
			if (voicePacket.VoiceData.Length > 65535)
			{
				if (CfgDebugMode.Value)
				{
					Log.LogWarning((object)$"[Security] Dropped oversized packet from {header.SenderID}");
				}
			}
			else
			{
				VoiceSystem.Instance.RoutePacket(header.SenderID, voicePacket.VoiceData);
			}
		}

		private void InitConfig()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Expected O, but got Unknown
			CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Voice Chat Active", true, "Master Switch");
			CfgMasterVolume = ((BaseUnityPlugin)this).Config.Bind<float>("1. General", "Master Volume", 1f, new ConfigDescription("Incoming Voice Volume Boost (0 = Mute)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			CfgMuteAll = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Mute Everyone (Panic)", false, "Panic button to silence all incoming voice");
			CfgMicMode = ((BaseUnityPlugin)this).Config.Bind<MicMode>("2. Input", "Input Mode", MicMode.PushToTalk, "Input Method");
			CfgPushToTalk = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Input", "Push To Talk Key", (KeyCode)116, "Bind for PTT/Toggle");
			CfgMicThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("2. Input", "Mic Activation Threshold", 0.05f, new ConfigDescription("Gate threshold", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>()));
			CfgMicTest = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Input", "Mic Test (Loopback)", false, "Hear your own voice to test settings");
			CfgMinDistance = ((BaseUnityPlugin)this).Config.Bind<float>("3. Spatial", "Min Distance", 5f, new ConfigDescription("Distance where audio is 100% volume", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>()));
			CfgMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("3. Spatial", "Max Distance", 40f, new ConfigDescription("Distance where audio becomes silent", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 256f), Array.Empty<object>()));
			CfgSpatialBlending = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Spatial", "3D Spatial Audio", true, "Enable 3D Directional Audio");
			CfgRetroMode = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Spatial", "COD Lobby Quality", false, "Degrades audio quality to simulate an Xbox 360 mic");
			CfgShowOverlay = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Visuals", "Show Voice Overlay", true, "Show list of speakers in top right");
			CfgShowHeadIcons = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Visuals", "Show Head Icons (Bubble)", true, "Show GMod-style bubble");
			CfgBubbleScale = ((BaseUnityPlugin)this).Config.Bind<float>("4. Visuals", "Bubble Scale", 0.2f, new ConfigDescription("Size of the speech bubble", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f), Array.Empty<object>()));
			CfgLipSync = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Visuals", "Enable Lip Sync", true, "Animate mouths when talking");
			CfgDebugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Advanced", "Debug Mode (Verbose)", false, "Enable traffic flow logs. Warning: Spams console.");
		}

		private void AddSettings()
		{
			SettingsTab modTab = Settings.ModTab;
			modTab.AddHeader("General");
			modTab.AddToggle(CfgEnabled);
			modTab.AddToggle(CfgMuteAll);
			modTab.AddSlider(CfgMasterVolume, false);
			modTab.AddHeader("Microphone");
			modTab.AddDropdown<MicMode>(CfgMicMode);
			modTab.AddKeyButton(CfgPushToTalk);
			modTab.AddSlider(CfgMicThreshold, false);
			modTab.AddToggle(CfgMicTest);
			modTab.AddHeader("Spatial / Earmuffs");
			modTab.AddToggle(CfgSpatialBlending);
			modTab.AddSlider(CfgMinDistance, false);
			modTab.AddSlider(CfgMaxDistance, false);
			modTab.AddToggle(CfgRetroMode);
			modTab.AddHeader("Visuals");
			modTab.AddToggle(CfgShowOverlay);
			modTab.AddToggle(CfgShowHeadIcons);
			modTab.AddSlider(CfgBubbleScale, false);
			modTab.AddToggle(CfgLipSync);
			modTab.AddHeader("Advanced");
			modTab.AddToggle(CfgDebugMode);
		}
	}
	public static class VoiceAPI
	{
		public static event Action<Player> OnPlayerStartSpeaking;

		public static event Action<Player> OnPlayerStopSpeaking;

		public static bool IsPlayerSpeaking(Player player)
		{
			VoiceManager managerForPlayer = VoiceSystem.Instance.GetManagerForPlayer(player);
			return (Object)(object)managerForPlayer != (Object)null && managerForPlayer.IsSpeaking();
		}

		public static void SetPlayerMute(Player player, bool isMuted)
		{
			VoiceManager managerForPlayer = VoiceSystem.Instance.GetManagerForPlayer(player);
			if ((Object)(object)managerForPlayer != (Object)null)
			{
				managerForPlayer.SetExternalMute(isMuted);
			}
		}

		public static void SetPlayerVolume(Player player, float volumeMultiplier)
		{
			VoiceManager managerForPlayer = VoiceSystem.Instance.GetManagerForPlayer(player);
			if ((Object)(object)managerForPlayer != (Object)null)
			{
				managerForPlayer.SetExternalGain(volumeMultiplier);
			}
		}

		public static void SetPlayerSpatialOverride(Player player, bool? forceSpatial)
		{
			VoiceManager managerForPlayer = VoiceSystem.Instance.GetManagerForPlayer(player);
			if ((Object)(object)managerForPlayer != (Object)null)
			{
				managerForPlayer.SetSpatialOverride(forceSpatial);
			}
		}

		internal static void TriggerStartSpeaking(Player p)
		{
			VoiceAPI.OnPlayerStartSpeaking?.Invoke(p);
		}

		internal static void TriggerStopSpeaking(Player p)
		{
			VoiceAPI.OnPlayerStopSpeaking?.Invoke(p);
		}
	}
	public class VoicePacket : BinaryPacketBase
	{
		public byte[] VoiceData;

		public override string PacketSignature => "VCLYSS_VOICE";

		public VoicePacket()
		{
		}

		public VoicePacket(byte[] data)
		{
			VoiceData = data;
		}

		public override byte[] Serialize()
		{
			return VoiceData ?? new byte[0];
		}

		public override void Deserialize(byte[] data)
		{
			VoiceData = data;
		}
	}
	public class VoiceSystem : MonoBehaviour
	{
		public static VoiceSystem Instance;

		public static List<VoiceManager> ActiveManagers = new List<VoiceManager>();

		public static bool IsVoiceAllowedInLobby = false;

		public bool IsSessionReady = false;

		private void Awake()
		{
			Instance = this;
			((MonoBehaviour)this).StartCoroutine(PlayerScanner());
		}

		public void SetSessionReady(bool ready)
		{
			if (ready)
			{
				((MonoBehaviour)this).StartCoroutine(WaitForAssetsAndEnable());
				return;
			}
			IsSessionReady = false;
			ActiveManagers.Clear();
			if (Main.CfgDebugMode.Value)
			{
				Main.Log.LogDebug((object)"VCLYSS Paused: Player left game.");
			}
		}

		public void ResyncPlayer(Player p)
		{
			if ((Object)(object)p == (Object)null)
			{
				return;
			}
			if (Main.CfgDebugMode.Value)
			{
				Main.Log.LogDebug((object)("[Resync] Resetting voice for " + p._nickname));
			}
			VoiceManager[] components = ((Component)p).GetComponents<VoiceManager>();
			if (components.Length > 1)
			{
				for (int i = 1; i < components.Length; i++)
				{
					Object.Destroy((Object)(object)components[i]);
				}
			}
			if (components.Length != 0)
			{
				components[0].FullReset();
				if (!ActiveManagers.Contains(components[0]))
				{
					ActiveManagers.Add(components[0]);
				}
			}
			else
			{
				VoiceManager item = ((Component)p).gameObject.AddComponent<VoiceManager>();
				ActiveManagers.Add(item);
			}
		}

		public void ResyncAll()
		{
			if (Main.CfgDebugMode.Value)
			{
				Main.Log.LogDebug((object)"[Resync] Local Map Change Detected. Resetting ALL audio.");
			}
			ActiveManagers.RemoveAll((VoiceManager vm) => (Object)(object)vm == (Object)null);
			foreach (VoiceManager activeManager in ActiveManagers)
			{
				activeManager.FullReset();
			}
		}

		private IEnumerator WaitForAssetsAndEnable()
		{
			while ((Object)(object)Player._mainPlayer == (Object)null || (Object)(object)Player._mainPlayer._pVisual == (Object)null)
			{
				yield return (object)new WaitForSeconds(0.5f);
			}
			yield return (object)new WaitForSeconds(5f);
			IsSessionReady = true;
			Main.Instance.RegisterPackets();
			if (Main.CfgDebugMode.Value)
			{
				Main.Log.LogDebug((object)"VCLYSS Ready: Player IN_GAME and Assets Loaded.");
			}
		}

		private IEnumerator PlayerScanner()
		{
			WaitForSeconds wait = new WaitForSeconds(1f);
			while (true)
			{
				try
				{
					if (IsSessionReady)
					{
						ActiveManagers.RemoveAll((VoiceManager vm) => (Object)(object)vm == (Object)null);
						Player[] allPlayers = Object.FindObjectsOfType<Player>();
						if ((Object)(object)Player._mainPlayer != (Object)null)
						{
							string localMap = Player._mainPlayer._mapName;
							Player[] array = allPlayers;
							foreach (Player p in array)
							{
								if ((Object)(object)p == (Object)(object)Player._mainPlayer)
								{
									VoiceManager localVM = ((Component)p).GetComponent<VoiceManager>();
									if ((Object)(object)localVM == (Object)null)
									{
										localVM = ((Component)p).gameObject.AddComponent<VoiceManager>();
										if (Main.CfgDebugMode.Value)
										{
											Main.Log.LogDebug((object)"[Scanner] Added Local Manager");
										}
									}
									if (!ActiveManagers.Contains(localVM))
									{
										ActiveManagers.Add(localVM);
									}
									continue;
								}
								bool sameMap = string.Equals(p._mapName, localMap);
								if (!sameMap)
								{
									float dist = Vector3.Distance(((Component)p).transform.position, ((Component)Player._mainPlayer).transform.position);
									if (dist < 100f)
									{
										sameMap = true;
									}
								}
								VoiceManager vm2 = ((Component)p).GetComponent<VoiceManager>();
								if (sameMap)
								{
									if ((Object)(object)vm2 == (Object)null)
									{
										if (Main.CfgDebugMode.Value)
										{
											Main.Log.LogDebug((object)("[Scanner] Adding Manager for " + p._nickname + " (Same Map/Close)"));
										}
										vm2 = ((Component)p).gameObject.AddComponent<VoiceManager>();
									}
									if (!ActiveManagers.Contains(vm2))
									{
										ActiveManagers.Add(vm2);
									}
								}
								else if ((Object)(object)vm2 != (Object)null)
								{
									if (Main.CfgDebugMode.Value)
									{
										Main.Log.LogDebug((object)("[Scanner] Removing Manager for " + p._nickname + " (Different Map)"));
									}
									ActiveManagers.Remove(vm2);
									Object.Destroy((Object)(object)vm2);
								}
							}
						}
					}
				}
				catch (Exception ex)
				{
					Exception e = ex;
					Main.Log.LogWarning((object)("Scanner error: " + e.Message));
				}
				yield return wait;
			}
		}

		public void RoutePacket(ulong senderID, byte[] data)
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			if (!Main.CfgEnabled.Value || Main.CfgMuteAll.Value || !IsVoiceAllowedInLobby || senderID == GetSteamIDFromPlayer(Player._mainPlayer))
			{
				return;
			}
			VoiceManager voiceManager = FindManager(senderID);
			if ((Object)(object)voiceManager == (Object)null)
			{
				voiceManager = TryRecoverManager(senderID);
			}
			if (!((Object)(object)voiceManager != (Object)null) || voiceManager.OwnerID != senderID)
			{
				return;
			}
			bool flag = false;
			if ((Object)(object)voiceManager.AttachedPlayer != (Object)null && (Object)(object)Player._mainPlayer != (Object)null)
			{
				string mapName = Player._mainPlayer._mapName;
				string mapName2 = voiceManager.AttachedPlayer._mapName;
				if (string.Equals(mapName, mapName2))
				{
					flag = true;
				}
				else
				{
					float num = Vector3.Distance(((Component)voiceManager.AttachedPlayer).transform.position, ((Component)Player._mainPlayer).transform.position);
					if (num < 100f)
					{
						flag = true;
					}
				}
			}
			if (flag)
			{
				voiceManager.ReceiveNetworkData(data);
			}
		}

		public VoiceManager GetManagerForPlayer(Player p)
		{
			if ((Object)(object)p == (Object)null)
			{
				return null;
			}
			return ((Component)p).GetComponent<VoiceManager>();
		}

		private VoiceManager FindManager(ulong steamID)
		{
			for (int num = ActiveManagers.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)ActiveManagers[num] == (Object)null || (Object)(object)ActiveManagers[num].AttachedPlayer == (Object)null)
				{
					ActiveManagers.RemoveAt(num);
				}
				else if (ActiveManagers[num].OwnerID == steamID)
				{
					return ActiveManagers[num];
				}
			}
			return null;
		}

		private VoiceManager TryRecoverManager(ulong steamID)
		{
			Player[] array = Object.FindObjectsOfType<Player>();
			Player[] array2 = array;
			foreach (Player val in array2)
			{
				if (GetSteamIDFromPlayer(val) != steamID)
				{
					continue;
				}
				VoiceManager voiceManager = ((Component)val).GetComponent<VoiceManager>();
				if ((Object)(object)voiceManager == (Object)null)
				{
					if (Main.CfgDebugMode.Value)
					{
						Main.Log.LogDebug((object)("[RoutePacket] Lazy initializing VoiceManager for " + val._nickname));
					}
					voiceManager = ((Component)val).gameObject.AddComponent<VoiceManager>();
				}
				if (!ActiveManagers.Contains(voiceManager))
				{
					ActiveManagers.Add(voiceManager);
				}
				return voiceManager;
			}
			return null;
		}

		public static ulong GetSteamIDFromPlayer(Player p)
		{
			if ((Object)(object)p == (Object)null)
			{
				return 0uL;
			}
			if (ulong.TryParse(p._steamID, out var result))
			{
				return result;
			}
			return 0uL;
		}

		public static void ApplySettingsToAll()
		{
			foreach (VoiceManager activeManager in ActiveManagers)
			{
				if ((Object)(object)activeManager != (Object)null)
				{
					activeManager.ApplyAudioSettings();
				}
			}
		}
	}
	[HarmonyPatch]
	public class GameStatePatches
	{
		private const string LOBBY_KEY = "vclyss_version";

		[HarmonyPatch(typeof(Player), "OnGameConditionChange")]
		[HarmonyPostfix]
		public static void OnGameConditionChange(ref Player __instance, GameCondition _newCondition)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Invalid comparison between Unknown and I4
			if ((int)__instance._currentGameCondition == 1 && ((NetworkBehaviour)__instance).isLocalPlayer)
			{
				Main.Log.LogInfo((object)("[VCLYSS] Player " + ((Object)((Component)__instance).gameObject).name + " entered game. Initializing..."));
				if ((Object)(object)VoiceSystem.Instance != (Object)null)
				{
					VoiceSystem.Instance.SetSessionReady(ready: true);
				}
			}
			else if (((NetworkBehaviour)__instance).isLocalPlayer && (int)_newCondition != 1 && (Object)(object)VoiceSystem.Instance != (Object)null)
			{
				VoiceSystem.Instance.SetSessionReady(ready: false);
			}
		}

		[HarmonyPatch(typeof(Player), "OnPlayerMapInstanceChange")]
		[HarmonyPostfix]
		public static void OnPlayerMapInstanceChange(Player __instance, MapInstance _old, MapInstance _new)
		{
			try
			{
				if ((Object)(object)__instance != (Object)null && (Object)(object)VoiceSystem.Instance != (Object)null)
				{
					if (((NetworkBehaviour)__instance).isLocalPlayer)
					{
						VoiceSystem.Instance.ResyncAll();
					}
					else
					{
						VoiceSystem.Instance.ResyncPlayer(__instance);
					}
				}
			}
			catch (Exception ex)
			{
				if (Main.CfgDebugMode.Value)
				{
					Main.Log.LogWarning((object)("[VCLYSS] MapChange Error: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(SteamMatchmaking), "JoinLobby")]
		[HarmonyPostfix]
		public static void OnJoinLobby(CSteamID steamIDLobby)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)Main.Instance).StartCoroutine(CheckLobbyStatus(steamIDLobby));
		}

		[HarmonyPatch(typeof(SteamMatchmaking), "CreateLobby")]
		[HarmonyPostfix]
		public static void OnCreateLobby()
		{
			((MonoBehaviour)Main.Instance).StartCoroutine(SetLobbyStatus());
		}

		private static IEnumerator SetLobbyStatus()
		{
			yield return (object)new WaitForSeconds(1f);
			CSteamID currentLobby = new CSteamID(SteamLobby._current._currentLobbyID);
			if (currentLobby.m_SteamID != 0L && Main.CfgEnabled.Value)
			{
				SteamMatchmaking.SetLobbyData(currentLobby, "vclyss_version", "1.2.3");
				VoiceSystem.IsVoiceAllowedInLobby = true;
				Main.Log.LogInfo((object)"Host Lobby Created: Voice Chat ENABLED.");
			}
		}

		private static IEnumerator CheckLobbyStatus(CSteamID lobbyId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			yield return (object)new WaitForSeconds(2f);
			string value = SteamMatchmaking.GetLobbyData(lobbyId, "vclyss_version");
			if (!string.IsNullOrEmpty(value) && Main.CfgEnabled.Value)
			{
				VoiceSystem.IsVoiceAllowedInLobby = true;
				Main.Log.LogInfo((object)("Joined Modded Lobby (Host Ver: " + value + "): Voice Chat ENABLED."));
			}
			else
			{
				VoiceSystem.IsVoiceAllowedInLobby = false;
				SteamUser.StopVoiceRecording();
				Main.Log.LogInfo((object)"Voice Chat DISABLED (Host does not have the mod).");
			}
		}
	}
	public class VoiceManager : MonoBehaviour
	{
		public Player AttachedPlayer;

		public ulong OwnerID;

		public bool IsLocalPlayer = false;

		private float _externalGain = 1f;

		private bool _externalMute = false;

		private bool? _spatialOverride = null;

		private string _lastMapName = "";

		private AudioSource _audioSource;

		private GameObject _bubbleObject;

		private SpriteRenderer _bubbleRenderer;

		private LipSync _lipSync;

		private AudioDistortionFilter _distortion;

		private AudioHighPassFilter _highPass;

		private AudioLowPassFilter _lowPass;

		private Vector3 _baseScale = Vector3.one;

		private static AudioMixerGroup _cachedVoiceMixer;

		private byte[] _compressedBuffer = new byte[8192];

		private byte[] _decompressedBuffer = new byte[65536];

		private byte[] _tempDecompressBuffer = new byte[65536];

		private float[] _floatBuffer;

		private int _writePos = 0;

		private int _bufferLength;

		private AudioClip _streamingClip;

		private int _sampleRate;

		private bool _isRecording = false;

		private float _lastVolume = 0f;

		private bool _isToggleOn = false;

		private bool _wasKeyDown = false;

		private float _lastPacketTime = 0f;

		private bool _isPlaying = false;

		private bool _audioInitialized = false;

		private bool _eventIsSpeaking = false;

		public bool IsInputActive { get; private set; } = false;


		private void Awake()
		{
			AttachedPlayer = ((Component)this).GetComponent<Player>();
			if ((Object)(object)AttachedPlayer == (Object)null)
			{
				Object.Destroy((Object)(object)this);
			}
			else
			{
				((MonoBehaviour)this).StartCoroutine(WaitForSteamID());
			}
		}

		private IEnumerator WaitForSteamID()
		{
			while (VoiceSystem.GetSteamIDFromPlayer(AttachedPlayer) == 0)
			{
				yield return (object)new WaitForSeconds(0.5f);
			}
			while (!VoiceSystem.Instance.IsSessionReady)
			{
				yield return (object)new WaitForSeconds(0.5f);
			}
			OwnerID = VoiceSystem.GetSteamIDFromPlayer(AttachedPlayer);
			VoiceSystem.ActiveManagers.Add(this);
			InitializeAudio();
			InitializeBubble();
			_lipSync = ((Component)this).gameObject.AddComponent<LipSync>();
			_lipSync.Initialize(AttachedPlayer);
			_audioInitialized = true;
			CheckLocalPlayerStatus();
			if ((Object)(object)AttachedPlayer != (Object)null)
			{
				_lastMapName = AttachedPlayer._mapName;
			}
			if (Main.CfgDebugMode.Value)
			{
				Main.Log.LogDebug((object)("[Manager] Initialized for " + AttachedPlayer._nickname));
			}
		}

		private void Start()
		{
			if (_audioInitialized)
			{
				CheckLocalPlayerStatus();
			}
		}

		private void OnDestroy()
		{
			VoiceSystem.ActiveManagers.Remove(this);
			if (IsLocalPlayer && _isRecording)
			{
				SteamUser.StopVoiceRecording();
			}
			if ((Object)(object)_bubbleObject != (Object)null)
			{
				Object.Destroy((Object)(object)_bubbleObject);
			}
			if ((Object)(object)_audioSource != (Object)null && (Object)(object)((Component)_audioSource).gameObject != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_audioSource).gameObject);
			}
			if ((Object)(object)_lipSync != (Object)null)
			{
				Object.Destroy((Object)(object)_lipSync);
			}
		}

		public void FullReset()
		{
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			if (Main.CfgDebugMode.Value)
			{
				Main.Log.LogDebug((object)("[VoiceManager] Full Reset for " + AttachedPlayer?._nickname));
			}
			if ((Object)(object)_audioSource != (Object)null)
			{
				_audioSource.Stop();
				_audioSource.timeSamples = 0;
				_audioSource.loop = false;
			}
			if (_floatBuffer != null)
			{
				Array.Clear(_floatBuffer, 0, _floatBuffer.Length);
			}
			_writePos = 0;
			if ((Object)(object)_streamingClip != (Object)null && _floatBuffer != null)
			{
				_streamingClip.SetData(_floatBuffer, 0);
			}
			_lastVolume = 0f;
			_isPlaying = false;
			_lastPacketTime = Time.time;
			if (IsLocalPlayer && _isRecording)
			{
				SteamUser.StopVoiceRecording();
				_isRecording = false;
			}
			if ((Object)(object)AttachedPlayer != (Object)null && (Object)(object)_bubbleObject != (Object)null)
			{
				Transform val = ((Component)AttachedPlayer).transform.Find("_playerEffects");
				Transform val2 = ((Component)AttachedPlayer).transform.Find("_playerEffects/_effect_chatBubble");
				if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
				{
					_bubbleObject.transform.SetParent(val, false);
					_bubbleObject.transform.localPosition = val2.localPosition;
				}
			}
		}

		public void SetExternalGain(float gain)
		{
			_externalGain = gain;
		}

		public void SetExternalMute(bool mute)
		{
			_externalMute = mute;
		}

		public void SetSpatialOverride(bool? spatial)
		{
			_spatialOverride = spatial;
			ApplyAudioSettings();
		}

		private void InitializeAudio()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("VoiceEmitter");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = new Vector3(0f, 1.7f, 0f);
			_audioSource = val.AddComponent<AudioSource>();
			_audioSource.loop = false;
			_audioSource.playOnAwake = false;
			_audioSource.dopplerLevel = 0f;
			_distortion = val.AddComponent<AudioDistortionFilter>();
			_distortion.distortionLevel = 0.6f;
			((Behaviour)_distortion).enabled = false;
			_highPass = val.AddComponent<AudioHighPassFilter>();
			_highPass.cutoffFrequency = 1500f;
			((Behaviour)_highPass).enabled = false;
			_lowPass = val.AddComponent<AudioLowPassFilter>();
			_lowPass.cutoffFrequency = 4000f;
			((Behaviour)_lowPass).enabled = false;
			if ((Object)(object)_cachedVoiceMixer == (Object)null)
			{
				AudioMixerGroup[] array = Resources.FindObjectsOfTypeAll<AudioMixerGroup>();
				AudioMixerGroup[] array2 = array;
				foreach (AudioMixerGroup val2 in array2)
				{
					if (((Object)val2).name.IndexOf("Voice", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						_cachedVoiceMixer = val2;
						break;
					}
				}
			}
			if ((Object)(object)_cachedVoiceMixer != (Object)null)
			{
				_audioSource.outputAudioMixerGroup = _cachedVoiceMixer;
			}
			_sampleRate = (int)SteamUser.GetVoiceOptimalSampleRate();
			int num = 88200;
			_floatBuffer = new float[num];
			_bufferLength = num;
			_streamingClip = AudioClip.Create($"Voice_{OwnerID}", num, 1, _sampleRate, false);
			_streamingClip.SetData(_floatBuffer, 0);
			_audioSource.clip = _streamingClip;
			_audioSource.Play();
			ApplyAudioSettings();
		}

		private void InitializeBubble()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_00b5: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			_bubbleObject = new GameObject("VoiceBubble");
			Transform val = ((Component)AttachedPlayer).transform.Find("_playerEffects");
			Transform val2 = ((Component)AttachedPlayer).transform.Find("_playerEffects/_effect_chatBubble");
			if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
			{
				_bubbleObject.transform.SetParent(val, false);
				_bubbleObject.transform.localPosition = val2.localPosition;
			}
			else
			{
				_bubbleObject.transform.SetParent(((Component)this).transform, false);
				_bubbleObject.transform.localPosition = new Vector3(0f, 4.5f, 0f);
			}
			_bubbleRenderer = _bubbleObject.AddComponent<SpriteRenderer>();
			_bubbleRenderer.sprite = LoadVoiceSprite();
			_bubbleRenderer.color = Color.white;
			RotateObject val3 = _bubbleObject.AddComponent<RotateObject>();
			Traverse.Create((object)val3).Field("_rotY").SetValue((object)3f);
			Traverse.Create((object)val3).Field("_alwaysRun").SetValue((object)true);
			_bubbleObject.SetActive(false);
		}

		private Sprite LoadVoiceSprite()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string name = "VCLYSS.Icons.Voice.png";
				using Stream stream = executingAssembly.GetManifestResourceStream(name);
				if (stream != null)
				{
					byte[] array = new byte[stream.Length];
					stream.Read(array, 0, array.Length);
					Texture2D val = new Texture2D(2, 2);
					if (ImageConversion.LoadImage(val, array))
					{
						return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
					}
				}
			}
			catch (Exception)
			{
			}
			return CreateCircleSprite();
		}

		public void ApplyAudioSettings()
		{
			if ((Object)(object)_audioSource == (Object)null)
			{
				return;
			}
			_audioSource.volume = 1f;
			bool value = Main.CfgRetroMode.Value;
			if ((Object)(object)_distortion != (Object)null)
			{
				((Behaviour)_distortion).enabled = value;
			}
			if ((Object)(object)_highPass != (Object)null)
			{
				((Behaviour)_highPass).enabled = value;
			}
			if ((Object)(object)_lowPass != (Object)null)
			{
				((Behaviour)_lowPass).enabled = value;
			}
			if (IsLocalPlayer)
			{
				_audioSource.spatialBlend = 0f;
				return;
			}
			bool flag = true;
			if ((!_spatialOverride.HasValue) ? Main.CfgSpatialBlending.Value : _spatialOverride.Value)
			{
				_audioSource.spatialBlend = 1f;
				_audioSource.minDistance = Main.CfgMinDistance.Value;
				_audioSource.maxDistance = Main.CfgMaxDistance.Value;
				_audioSource.rolloffMode = (AudioRolloffMode)1;
			}
			else
			{
				_audioSource.spatialBlend = 0f;
				_audioSource.minDistance = 10000f;
				_audioSource.maxDistance = 100000f;
				_audioSource.rolloffMode = (AudioRolloffMode)1;
			}
		}

		private void Update()
		{
			if (!Main.CfgEnabled.Value || !_audioInitialized || !VoiceSystem.Instance.IsSessionReady)
			{
				return;
			}
			if ((Object)(object)_audioSource == (Object)null)
			{
				InitializeAudio();
			}
			if ((Object)(object)AttachedPlayer != (Object)null && AttachedPlayer._mapName != _lastMapName)
			{
				_lastMapName = AttachedPlayer._mapName;
				FullReset();
			}
			if (!IsLocalPlayer)
			{
				CheckLocalPlayerStatus();
			}
			if (!VoiceSystem.IsVoiceAllowedInLobby && !Main.CfgMicTest.Value)
			{
				return;
			}
			if (IsLocalPlayer)
			{
				HandleMicInput();
			}
			if (_isPlaying && Time.time - _lastPacketTime > 0.3f)
			{
				_audioSource.Stop();
				FlushBuffer();
				_isPlaying = false;
				_lastVolume = 0f;
			}
			bool flag = IsSpeaking();
			if (flag != _eventIsSpeaking)
			{
				_eventIsSpeaking = flag;
				if (flag)
				{
					VoiceAPI.TriggerStartSpeaking(AttachedPlayer);
				}
				else
				{
					VoiceAPI.TriggerStopSpeaking(AttachedPlayer);
				}
			}
			UpdateVisuals();
		}

		private void FlushBuffer()
		{
			Array.Clear(_floatBuffer, 0, _floatBuffer.Length);
			_streamingClip.SetData(_floatBuffer, 0);
			_writePos = 0;
		}

		private void HandleMicInput()
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			bool flag2 = (IsInputActive = CheckInputKeys());
			if (flag2 && !_isRecording)
			{
				SteamUser.StartVoiceRecording();
				_isRecording = true;
				if (Main.CfgDebugMode.Value)
				{
					Main.Log.LogDebug((object)"Mic Recording Started");
				}
			}
			else if (!flag2 && _isRecording)
			{
				SteamUser.StopVoiceRecording();
				_isRecording = false;
				_lastVolume = 0f;
			}
			if (!_isRecording)
			{
				return;
			}
			uint num = default(uint);
			uint num2 = default(uint);
			uint num3 = default(uint);
			while (true)
			{
				SteamUser.GetAvailableVoice(ref num);
				if (num == 0)
				{
					break;
				}
				EVoiceResult voice = SteamUser.GetVoice(true, _compressedBuffer, (uint)_compressedBuffer.Length, ref num2);
				if ((int)voice != 0 || num2 == 0)
				{
					continue;
				}
				EVoiceResult val = SteamUser.DecompressVoice(_compressedBuffer, num2, _tempDecompressBuffer, (uint)_tempDecompressBuffer.Length, ref num3, (uint)_sampleRate);
				float num4 = 0f;
				if ((int)val == 0 && num3 != 0)
				{
					for (int i = 0; i < num3 / 2; i++)
					{
						short num5 = BitConverter.ToInt16(_tempDecompressBuffer, i * 2);
						float num6 = (float)num5 / 32768f;
						if (Mathf.Abs(num6) > num4)
						{
							num4 = Mathf.Abs(num6);
						}
					}
				}
				if (num4 >= Main.CfgMicThreshold.Value)
				{
					byte[] array = new byte[num2];
					Array.Copy(_compressedBuffer, array, num2);
					if (Main.CfgMicTest.Value)
					{
						ReceiveNetworkData(array);
						continue;
					}
					VoicePacket voicePacket = new VoicePacket(array);
					foreach (VoiceManager activeManager in VoiceSystem.ActiveManagers)
					{
						if ((Object)(object)activeManager != (Object)(object)this && (Object)(object)activeManager.AttachedPlayer != (Object)null && IsPlayerLoaded(activeManager.AttachedPlayer))
						{
							CodeTalkerNetwork.SendNetworkPacket(activeManager.AttachedPlayer, (BinaryPacketBase)(object)voicePacket, (CompressionType)0, CompressionLevel.Fastest);
						}
					}
					_lastVolume = Mathf.Lerp(_lastVolume, num4, Time.deltaTime * 20f);
					if ((Object)(object)_lipSync != (Object)null)
					{
						_lipSync.SetSpeaking();
					}
					_lastPacketTime = Time.time;
					if (!_isPlaying)
					{
						_isPlaying = true;
					}
				}
				else
				{
					_lastVolume = Mathf.Lerp(_lastVolume, 0f, Time.deltaTime * 20f);
				}
			}
		}

		private bool IsPlayerLoaded(Player p)
		{
			if ((Object)(object)p == (Object)null)
			{
				return false;
			}
			if ((Object)(object)p._pVisual == (Object)null)
			{
				return false;
			}
			return true;
		}

		public void ReceiveNetworkData(byte[] compressedData)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (_externalMute || (IsLocalPlayer && !Main.CfgMicTest.Value))
			{
				return;
			}
			try
			{
				uint num = default(uint);
				EVoiceResult val = SteamUser.DecompressVoice(compressedData, (uint)compressedData.Length, _decompressedBuffer, (uint)_decompressedBuffer.Length, ref num, (uint)_sampleRate);
				if ((int)val == 0 && num != 0)
				{
					ProcessPCMData(_decompressedBuffer, (int)num);
					if ((Object)(object)_lipSync != (Object)null)
					{
						_lipSync.SetSpeaking();
					}
					_lastPacketTime = Time.time;
				}
			}
			catch (Exception ex)
			{
				if (Main.CfgDebugMode.Value)
				{
					Main.Log.LogWarning((object)$"[Security] Error processing voice packet for {OwnerID}: {ex.Message}");
				}
			}
		}

		private void ProcessPCMData(byte[] rawBytes, int length)
		{
			int num = length / 2;
			float num2 = 0f;
			float num3 = Main.CfgMasterVolume.Value * _externalGain;
			for (int i = 0; i < num; i++)
			{
				short num4 = BitConverter.ToInt16(rawBytes, i * 2);
				float num5 = (float)num4 / 32768f * num3;
				if (num5 > 1f)
				{
					num5 = 1f;
				}
				if (num5 < -1f)
				{
					num5 = -1f;
				}
				_floatBuffer[_writePos] = num5;
				_writePos = (_writePos + 1) % _bufferLength;
				float num6 = Mathf.Abs(num5);
				if (num6 > num2)
				{
					num2 = num6;
				}
			}
			int num7 = _sampleRate / 2;
			int writePos = _writePos;
			for (int j = 0; j < num7; j++)
			{
				_floatBuffer[(writePos + j) % _bufferLength] = 0f;
			}
			_lastVolume = Mathf.Lerp(_lastVolume, num2, Time.deltaTime * 10f);
			_streamingClip.SetData(_floatBuffer, 0);
			_audioSource.loop = false;
			if (!_audioSource.isPlaying)
			{
				_audioSource.Play();
				_isPlaying = true;
			}
			int timeSamples = _audioSource.timeSamples;
			int num8 = (_writePos - timeSamples + _bufferLength) % _bufferLength;
			if (num8 > _sampleRate / 5)
			{
				int num9 = _writePos - _sampleRate / 20;
				if (num9 < 0)
				{
					num9 += _bufferLength;
				}
				_audioSource.timeSamples = num9;
			}
		}

		private void UpdateVisuals()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_bubbleObject == (Object)null)
			{
				return;
			}
			if (!Main.CfgShowHeadIcons.Value)
			{
				_bubbleObject.SetActive(false);
				return;
			}
			_lastVolume = Mathf.Lerp(_lastVolume, 0f, Time.deltaTime * 5f);
			if (_lastVolume > 0.01f)
			{
				_bubbleObject.SetActive(true);
				float value = Main.CfgBubbleScale.Value;
				float num = value + value * _lastVolume * 0.5f;
				_bubbleObject.transform.localScale = Vector3.one * num;
			}
			else
			{
				_bubbleObject.SetActive(false);
			}
		}

		public bool IsSpeaking()
		{
			return _lastVolume > 0.01f;
		}

		private void CheckLocalPlayerStatus()
		{
			if (!IsLocalPlayer && (Object)(object)Player._mainPlayer != (Object)null && (Object)(object)AttachedPlayer == (Object)(object)Player._mainPlayer)
			{
				IsLocalPlayer = true;
				ApplyAudioSettings();
			}
		}

		private bool CheckInputKeys()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (Main.CfgMicTest.Value)
			{
				return true;
			}
			if (Main.CfgMicMode.Value == Main.MicMode.AlwaysOn)
			{
				return true;
			}
			if (Main.CfgMicMode.Value == Main.MicMode.PushToTalk)
			{
				return Input.GetKey(Main.CfgPushToTalk.Value);
			}
			if (Main.CfgMicMode.Value == Main.MicMode.Toggle)
			{
				bool key = Input.GetKey(Main.CfgPushToTalk.Value);
				if (key && !_wasKeyDown)
				{
					_isToggleOn = !_isToggleOn;
				}
				_wasKeyDown = key;
				return _isToggleOn;
			}
			return false;
		}

		private Sprite CreateCircleSprite()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			int num = 64;
			Texture2D val = new Texture2D(num, num);
			Color[] array = (Color[])(object)new Color[num * num];
			float num2 = (float)num / 2f;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(num2, num2);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num3 = Vector2.Distance(new Vector2((float)j, (float)i), val2);
					array[i * num + j] = ((num3 < num2) ? Color.white : Color.clear);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f));
		}
	}
	public class LipSync : MonoBehaviour
	{
		public enum MouthCondition
		{
			Closed,
			Open
		}

		private PlayerRaceModel _playerRaceModel;

		private bool _initialized = false;

		private Coroutine _mouthResetCoroutine;

		public void Initialize(Player player)
		{
			try
			{
				if (!((Object)(object)player == (Object)null))
				{
					_playerRaceModel = ((Component)player).GetComponentInChildren<PlayerRaceModel>(true);
					if ((Object)(object)_playerRaceModel == (Object)null && (Object)(object)player._pVisual != (Object)null)
					{
						_playerRaceModel = player._pVisual._playerRaceModel;
					}
					if (!((Object)(object)_playerRaceModel == (Object)null))
					{
						_initialized = true;
					}
				}
			}
			catch (Exception)
			{
			}
		}

		public void SetSpeaking()
		{
			if (!Main.CfgLipSync.Value || !_initialized || (Object)(object)_playerRaceModel == (Object)null)
			{
				return;
			}
			try
			{
				_playerRaceModel.Set_MouthCondition((MouthCondition)1, 0.15f);
				if (_mouthResetCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_mouthResetCoroutine);
				}
				_mouthResetCoroutine = ((MonoBehaviour)this).StartCoroutine(ResetMouthAfterDelay());
			}
			catch
			{
			}
		}

		private IEnumerator ResetMouthAfterDelay()
		{
			yield return (object)new WaitForSeconds(0.2f);
			if ((Object)(object)_playerRaceModel != (Object)null)
			{
				_playerRaceModel.Set_MouthCondition((MouthCondition)0, 0f);
			}
		}
	}
	public class VoiceOverlay : MonoBehaviour
	{
		private GUIStyle _style;

		private GUIStyle _statusStyle;

		private GUIStyle _micStyle;

		private void OnGUI()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_004a: Expected O, but got Unknown
			//IL_0051: 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)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			if (!Main.CfgShowOverlay.Value)
			{
				return;
			}
			if (Main.CfgMicTest.Value)
			{
				GUIStyle val = new GUIStyle
				{
					fontSize = 20,
					alignment = (TextAnchor)5,
					fontStyle = (FontStyle)1
				};
				val.normal.textColor = Color.yellow;
				GUI.Label(new Rect((float)(Screen.width - 320), 100f, 300f, 40f), "MIC TEST ACTIVE", val);
			}
			if (_style == null)
			{
				_style = new GUIStyle(GUI.skin.label);
				_style.fontSize = 20;
				_style.normal.textColor = Color.white;
				_style.alignment = (TextAnchor)5;
				_style.fontStyle = (FontStyle)1;
			}
			if (_statusStyle == null)
			{
				_statusStyle = new GUIStyle(GUI.skin.label);
				_statusStyle.fontSize = 16;
				_statusStyle.alignment = (TextAnchor)5;
				_statusStyle.fontStyle = (FontStyle)0;
			}
			if (_micStyle == null)
			{
				_micStyle = new GUIStyle(GUI.skin.label);
				_micStyle.fontSize = 16;
				_micStyle.alignment = (TextAnchor)5;
				_micStyle.fontStyle = (FontStyle)1;
			}
			bool flag = (Object)(object)VoiceSystem.Instance != (Object)null && VoiceSystem.Instance.IsSessionReady;
			_statusStyle.normal.textColor = (flag ? Color.green : Color.red);
			string text = (flag ? "VCLYSS: READY" : "VCLYSS: LOADING");
			GUI.Label(new Rect((float)(Screen.width - 270), (float)(Screen.height - 40), 250f, 30f), text, _statusStyle);
			if (flag && (Object)(object)Player._mainPlayer != (Object)null)
			{
				VoiceManager component = ((Component)Player._mainPlayer).GetComponent<VoiceManager>();
				if ((Object)(object)component != (Object)null)
				{
					bool isInputActive = component.IsInputActive;
					_micStyle.normal.textColor = (isInputActive ? Color.green : Color.red);
					string text2 = (isInputActive ? "[MIC OPEN]" : "[MIC CLOSED]");
					GUI.Label(new Rect((float)(Screen.width - 270), (float)(Screen.height - 65), 250f, 30f), text2, _micStyle);
				}
			}
			float num = 30f;
			float num2 = (float)Screen.width - 270f;
			float num3 = 20f;
			GUILayout.BeginArea(new Rect(num2, num3, 250f, (float)Screen.height));
			foreach (VoiceManager activeManager in VoiceSystem.ActiveManagers)
			{
				if (activeManager.IsSpeaking())
				{
					string text3 = (activeManager.IsLocalPlayer ? "Me" : (((Object)(object)activeManager.AttachedPlayer != (Object)null) ? activeManager.AttachedPlayer._nickname : "Unknown"));
					GUILayout.Box(text3, _style, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num) });
				}
			}
			GUILayout.EndArea();
		}
	}
	internal static class ModInfo
	{
		public const string GUID = "com.VCLYSS.sftwre";

		public const string NAME = "VCLYSS";

		public const string VERSION = "1.2.3";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}