Decompiled source of VCLYSS v1.0.0

VCLYSS.dll

Decompiled 6 hours 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 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.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+dd51c6b67c3ae15f202b303bb926a1a33079baf7")]
[assembly: AssemblyProduct("VCLYSS")]
[assembly: AssemblyTitle("VCLYSS")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.0.0")]
	[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;

		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> CfgShowOverlay;

		public static ConfigEntry<bool> CfgShowHeadIcons;

		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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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();
			((MonoBehaviour)this).StartCoroutine(RegisterPacketDelayed());
			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.");
		}

		private IEnumerator RegisterPacketDelayed()
		{
			yield return (object)new WaitForSeconds(2f);
			CodeTalkerNetwork.RegisterBinaryListener<VoicePacket>(new BinaryPacketListener(OnVoicePacketReceived));
			if (CfgDebugMode.Value)
			{
				Log.LogInfo((object)"Voice packet listener registered");
			}
		}

		private void OnVoicePacketReceived(PacketHeader header, BinaryPacketBase packet)
		{
			if (!(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} ({voicePacket.VoiceData.Length} bytes)");
				}
				return;
			}
			if (CfgDebugMode.Value)
			{
				Log.LogDebug((object)$"[Flow] Recv Voice Packet | Sender: {header.SenderID} | Size: {voicePacket.VoiceData.Length}");
			}
			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
			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");
			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");
			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 and detailed status updates. 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.AddHeader("Visuals");
			modTab.AddToggle(CfgShowOverlay);
			modTab.AddToggle(CfgShowHeadIcons);
			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;

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

		private IEnumerator PlayerScanner()
		{
			WaitForSeconds wait = new WaitForSeconds(2f);
			while (true)
			{
				try
				{
					Player[] allPlayers = Object.FindObjectsOfType<Player>();
					Player[] array = allPlayers;
					foreach (Player p in array)
					{
						if ((Object)(object)p != (Object)null && (Object)(object)((Component)p).GetComponent<VoiceManager>() == (Object)null)
						{
							if (Main.CfgDebugMode.Value)
							{
								Main.Log.LogDebug((object)("[Scanner] Attaching VoiceManager to " + p._nickname));
							}
							((Component)p).gameObject.AddComponent<VoiceManager>();
						}
					}
				}
				catch (Exception ex)
				{
					Exception e = ex;
					Main.Log.LogWarning((object)("Scanner error: " + e.Message));
				}
				yield return wait;
			}
		}

		public void RoutePacket(ulong senderID, byte[] data)
		{
			if (Main.CfgEnabled.Value && !Main.CfgMuteAll.Value && IsVoiceAllowedInLobby && senderID != GetSteamIDFromPlayer(Player._mainPlayer))
			{
				VoiceManager voiceManager = FindManager(senderID);
				if ((Object)(object)voiceManager != (Object)null && voiceManager.OwnerID == senderID)
				{
					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 i = 0; i < ActiveManagers.Count; i++)
			{
				if (ActiveManagers[i].OwnerID == steamID)
				{
					return ActiveManagers[i];
				}
			}
			Player[] array = Object.FindObjectsOfType<Player>();
			Player[] array2 = array;
			foreach (Player val in array2)
			{
				if (GetSteamIDFromPlayer(val) == steamID)
				{
					VoiceManager voiceManager = ((Component)val).GetComponent<VoiceManager>();
					if ((Object)(object)voiceManager == (Object)null)
					{
						voiceManager = ((Component)val).gameObject.AddComponent<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)
			{
				activeManager.ApplyAudioSettings();
			}
		}
	}
	[HarmonyPatch]
	public class LobbyPatches
	{
		private const string LOBBY_KEY = "vclyss_version";

		[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.0.0");
				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 AudioSource _audioSource;

		private GameObject _bubbleObject;

		private SpriteRenderer _bubbleRenderer;

		private LipSync _lipSync;

		private static AudioMixerGroup _cachedVoiceMixer;

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

		private byte[] _decompressedBuffer = 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;

		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);
			}
			OwnerID = VoiceSystem.GetSteamIDFromPlayer(AttachedPlayer);
			VoiceSystem.ActiveManagers.Add(this);
			InitializeAudio();
			InitializeBubble();
			_lipSync = ((Component)this).gameObject.AddComponent<LipSync>();
			_lipSync.Initialize(AttachedPlayer);
			_audioInitialized = true;
			CheckLocalPlayerStatus();
		}

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

		private void OnDestroy()
		{
			VoiceSystem.ActiveManagers.Remove(this);
			if (IsLocalPlayer && _isRecording)
			{
				SteamUser.StopVoiceRecording();
			}
		}

		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 = true;
			_audioSource.playOnAwake = false;
			_audioSource.dopplerLevel = 0f;
			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_0043: 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)
			_bubbleObject = new GameObject("VoiceBubble");
			_bubbleObject.transform.SetParent(((Component)this).transform, false);
			_bubbleObject.transform.localPosition = new Vector3(0f, 3.8f, 0f);
			_bubbleRenderer = _bubbleObject.AddComponent<SpriteRenderer>();
			_bubbleRenderer.sprite = LoadVoiceSprite();
			_bubbleRenderer.color = Color.white;
			_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))
			{
				_audioSource.volume = 1f;
				if (IsLocalPlayer)
				{
					_audioSource.spatialBlend = 0f;
					return;
				}
				bool flag = (_spatialOverride.HasValue ? _spatialOverride.Value : Main.CfgSpatialBlending.Value);
				_audioSource.spatialBlend = (flag ? 1f : 0f);
				_audioSource.minDistance = Main.CfgMinDistance.Value;
				_audioSource.maxDistance = Main.CfgMaxDistance.Value;
				_audioSource.rolloffMode = (AudioRolloffMode)1;
			}
		}

		private void Update()
		{
			if (!Main.CfgEnabled.Value || !_audioInitialized)
			{
				return;
			}
			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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			bool flag = CheckInputKeys();
			if (flag && !_isRecording)
			{
				SteamUser.StartVoiceRecording();
				_isRecording = true;
				if (Main.CfgDebugMode.Value)
				{
					Main.Log.LogDebug((object)"Mic Recording Started");
				}
			}
			else if (!flag && _isRecording)
			{
				SteamUser.StopVoiceRecording();
				_isRecording = false;
			}
			if (!_isRecording)
			{
				return;
			}
			uint num = default(uint);
			uint num2 = 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;
				}
				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)
					{
						CodeTalkerNetwork.SendNetworkPacket(activeManager.AttachedPlayer, (BinaryPacketBase)(object)voicePacket, (CompressionType)4, CompressionLevel.Fastest);
					}
				}
				_lastVolume = Mathf.Lerp(_lastVolume, 0.8f, Time.deltaTime * 20f);
				if ((Object)(object)_lipSync != (Object)null)
				{
					_lipSync.SetSpeaking();
				}
				_lastPacketTime = Time.time;
				if (!_isPlaying)
				{
					_isPlaying = 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)
		{
			if (length > rawBytes.Length)
			{
				length = rawBytes.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);
			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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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);
				if ((Object)(object)Camera.main != (Object)null)
				{
					_bubbleObject.transform.LookAt(((Component)Camera.main).transform);
				}
				_bubbleObject.transform.Rotate(Vector3.up, 180f * Time.deltaTime);
				float num = 0.5f + _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 void OnGUI()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_00ad: Expected O, but got Unknown
			//IL_00c6: 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;
			}
			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 text = (activeManager.IsLocalPlayer ? "Me" : (((Object)(object)activeManager.AttachedPlayer != (Object)null) ? activeManager.AttachedPlayer._nickname : "Unknown"));
					GUILayout.Box(text, _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.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}