Decompiled source of NextChat v0.0.1

plugins/Next_Chat.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using AmongUs.Data;
using AmongUs.QuickChat;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Hazel;
using Hazel.Udp;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using InnerNet;
using Microsoft.CodeAnalysis;
using NAudio;
using NAudio.CoreAudioApi;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;
using NextResources;
using Next_Chat.Core;
using Next_Chat.Default;
using Next_Chat.Patches;
using OpusDotNet;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using WebRtcVadSharp;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Next_Chat")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+185797fe16ad6b4597fbf720365b0436223a2c61")]
[assembly: AssemblyProduct("Next_Chat")]
[assembly: AssemblyTitle("Next_Chat")]
[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 NextResources
{
	public static class Sprites
	{
		public static readonly ResourceSprite All = new ResourceSprite("Sprites.All.png", 82f);

		public static readonly ResourceSprite Impostor = new ResourceSprite("Sprites.Impostor.png", 82f);

		public static readonly ResourceSprite Jackal = new ResourceSprite("Sprites.Jackal.png", 82f);

		public static readonly ResourceSprite Lover = new ResourceSprite("Sprites.Lover.png", 82f);

		public static readonly ResourceSprite MeetingVCFrame = new ResourceSprite("Sprites.MeetingVCFrame.png", 119f);

		public static readonly ResourceSprite MicOff = new ResourceSprite("Sprites.MicOff.png", 355f);

		public static readonly ResourceSprite MicOn = new ResourceSprite("Sprites.MicOn.png", 355f);

		public static readonly ResourceSprite OverlayIcon = new ResourceSprite("Sprites.OverlayIcon.png", 100f, 2, 1);
	}
	public static class Libs
	{
		internal static readonly ResourceLib[] ResourceLibs = new ResourceLib[10]
		{
			new ResourceLib("Lib.NAudio.Asio.dll"),
			new ResourceLib("Lib.NAudio.Core.dll"),
			new ResourceLib("Lib.NAudio.dll"),
			new ResourceLib("Lib.NAudio.Midi.dll"),
			new ResourceLib("Lib.NAudio.Wasapi.dll"),
			new ResourceLib("Lib.NAudio.WinMM.dll"),
			new ResourceLib("Lib.opus.dll"),
			new ResourceLib("Lib.OpusDotNet.dll"),
			new ResourceLib("Lib.WebRtcVad.dll"),
			new ResourceLib("Lib.WebRtcVadSharp.dll")
		};
	}
	public class ResourceInfo
	{
		public static readonly string BuildTime = "2024-10-15 16:16:41";

		public static readonly string Configs = "LibConfig.json,SpriteInfos.json";

		public static readonly string Sprites = "All_82f,Impostor_82f,Jackal_82f,Lover_82f,MeetingVCFrame_119f,MicOff_355f,MicOn_355f,OverlayIcon_100f_(2,1)";

		public static readonly string AssemblyName = "Next_Chat";
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace Next_Chat
{
	public class ChatChannelManager : InstanceClass<ChatChannelManager>
	{
		public static readonly List<ChatChannel> DefaultChannels = new List<ChatChannel>(4)
		{
			new ChatChannel(Sprites.All, (PlayerControl n) => Object.op_Implicit((Object)(object)MeetingHud.Instance)),
			new ChatChannel(Sprites.Impostor, (PlayerControl n) => n.Data.Role.IsImpostor),
			new ChatChannel(Sprites.Jackal),
			new ChatChannel(Sprites.Lover)
		};

		private List<ChatChannel> _Channels;

		private List<ChatChannel> _CanUseChannels;

		public IReadOnlyList<ChatChannel> Channels => _Channels;

		public ChatChannel CurrentChannel { get; private set; }

		public int Max { get; private set; }

		public int CurrentIndex { get; private set; }

		public int CurrentChannelIndex => _Channels.IndexOf(CurrentChannel);

		public bool hasNext { get; private set; }

		private static HudManager _hudManager => DestroyableSingleton<HudManager>.Instance;

		private static ChatController _chatController => _hudManager.Chat;

		public void UpdateCanUseChannels()
		{
			if (!((Object)(object)PlayerControl.LocalPlayer == (Object)null))
			{
				_CanUseChannels = _Channels.Where((ChatChannel n) => n.CanUse?.Invoke(PlayerControl.LocalPlayer) ?? false).ToList();
			}
		}

		public void Register(ChatChannel channel)
		{
			ChatChannel channel2 = channel;
			if (!_Channels.Exists((ChatChannel n) => n == channel2))
			{
				_Channels.Add(channel2);
				Max = _CanUseChannels.Count - 1;
			}
		}

		public void NextChannel()
		{
			int currentIndex = CurrentIndex;
			if (CurrentIndex + 1 > Max)
			{
				CurrentIndex = 0;
			}
			else
			{
				CurrentIndex++;
			}
			hasNext = currentIndex != CurrentIndex;
			CurrentChannel = _Channels[CurrentIndex];
		}

		public void ChangeChannel(ChatChannel channel)
		{
			if (!_Channels.Contains(channel))
			{
				Register(channel);
			}
			UpdateCanUseChannels();
			if (_CanUseChannels.Contains(channel))
			{
				CurrentChannel = channel;
				CurrentIndex = _Channels.IndexOf(channel);
				hasNext = true;
			}
		}

		public void UnRegister(ChatChannel channel)
		{
			_CanUseChannels.Remove(channel);
			_Channels.Remove(channel);
		}

		public void UpdateChatBubbles()
		{
			foreach (ChatChannel channel2 in _Channels.Where((ChatChannel channel) => channel.Bubbles.Any()))
			{
				channel2.Bubbles.RemoveAll((ChatBubble n) => _chatController.chatBubblePool.inactiveChildren.Contains((PoolableBehavior)(object)n));
				channel2.Bubbles.ForEach(delegate(ChatBubble n)
				{
					((Component)((Component)n).transform).gameObject.SetActive(channel2 == CurrentChannel);
				});
			}
			AlignAllBubbles();
		}

		public void AddChat(PlayerControl sourcePlayer, string chatText, int channel, bool censor = true)
		{
			AddChat(sourcePlayer, chatText, _Channels[channel], censor);
		}

		public void AddChat(PlayerControl sourcePlayer, string chatText, ChatChannel channel, bool censor = true)
		{
			//IL_0097: 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)
			if (!Object.op_Implicit((Object)(object)sourcePlayer) || !Object.op_Implicit((Object)(object)PlayerControl.LocalPlayer))
			{
				return;
			}
			NetworkedPlayerInfo data = PlayerControl.LocalPlayer.Data;
			NetworkedPlayerInfo data2 = sourcePlayer.Data;
			if ((Object)(object)data2 == (Object)null || (Object)(object)data == (Object)null || (data2.IsDead && !data.IsDead))
			{
				return;
			}
			ChatBubble pooledBubble = _chatController.GetPooledBubble();
			try
			{
				((Component)pooledBubble).transform.SetParent(_chatController.scroller.Inner);
				((Component)pooledBubble).transform.localScale = Vector3.one;
				bool flag = (Object)(object)sourcePlayer == (Object)(object)PlayerControl.LocalPlayer;
				if (flag)
				{
					pooledBubble.SetRight();
				}
				else
				{
					pooledBubble.SetLeft();
				}
				bool flag2 = Object.op_Implicit((Object)(object)MeetingHud.Instance) && MeetingHud.Instance.DidVote(sourcePlayer.PlayerId);
				pooledBubble.SetCosmetics(data2);
				_chatController.SetChatBubbleName(pooledBubble, data2, data2.IsDead, flag2, PlayerNameColor.Get(data2), (GetFormattedNameFunc)null);
				if (censor && DataManager.Settings.Multiplayer.CensorChat)
				{
					chatText = BlockedWords.CensorWords(chatText, false);
				}
				pooledBubble.SetText(chatText);
				pooledBubble.AlignChildren();
				channel.Bubbles.Add(pooledBubble);
				UpdateChatBubbles();
				ChatController chatController = _chatController;
				if (chatController != null && !chatController.IsOpenOrOpening && chatController.notificationRoutine == null)
				{
					_chatController.notificationRoutine = ((MonoBehaviour)_chatController).StartCoroutine(_chatController.BounceDot());
				}
				if (!flag && _CanUseChannels.Contains(channel))
				{
					SoundManager.Instance.PlaySound(_chatController.messageSound, false, 1f, (AudioMixerGroup)null).pitch = 0.5f + (float)(int)sourcePlayer.PlayerId / 15f;
					_chatController.chatNotification.SetUp(sourcePlayer, chatText);
				}
			}
			catch
			{
				((IObjectPool)_chatController.chatBubblePool).Reclaim((PoolableBehavior)(object)pooledBubble);
			}
		}

		public void AlignAllBubbles()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			List<ChatBubble> bubbles = CurrentChannel.Bubbles;
			if (bubbles.Any())
			{
				for (int num2 = bubbles.Count - 1; num2 >= 0; num2--)
				{
					ChatBubble val = bubbles[num2];
					num += val.Background.size.y;
					Vector3 localPosition = ((Component)val).transform.localPosition;
					localPosition.y = -1.85f + num;
					((Component)val).transform.localPosition = localPosition;
					num += 0.15f;
				}
				Scroller scroller = _chatController.scroller;
				float num3 = 0f - num;
				Bounds bounds = _chatController.scroller.Hitbox.bounds;
				scroller.SetYBoundsMin(Mathf.Min(0f, num3 + ((Bounds)(ref bounds)).size.y + -0.3f));
			}
		}

		public void UpdateChatVisible()
		{
			if (_CanUseChannels.Any())
			{
				_hudManager.Chat.SetVisible(true);
			}
		}

		public ChatChannelManager()
		{
			List<ChatChannel> defaultChannels = DefaultChannels;
			List<ChatChannel> list = new List<ChatChannel>(defaultChannels.Count);
			foreach (ChatChannel item in defaultChannels)
			{
				list.Add(item);
			}
			_Channels = list;
			_CanUseChannels = new List<ChatChannel>();
			CurrentChannel = DefaultChannels[0];
			base..ctor();
		}
	}
	[BepInPlugin("Next.Voice", "Next.Voice", "1.0.0")]
	public sealed class Main : BasePlugin
	{
		public static readonly Harmony _Harmony = new Harmony("Next.Voice");

		public static string LibDir = Paths.PluginPath;

		public const string Id = "Next.Voice";

		public static ManualLogSource LogSource { get; private set; } = null;


		public static ConfigFile ConfigFile { get; private set; } = null;


		public static IOptionCreator? _OptionCreator { get; set; }

		public static string Name => "Next.Voice";

		public static string Version => "1.0.0";

		public Main()
		{
			LogSource = ((BasePlugin)this).Log;
			ConfigFile = ((BasePlugin)this).Config;
		}

		public override void Load()
		{
			if (ConsoleManager.ConsoleActive)
			{
				Console.OutputEncoding = Encoding.UTF8;
			}
			AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
			Process.GetCurrentProcess().Exited += delegate
			{
				((BasePlugin)this).Unload();
			};
			SetModStamp();
			SetWrite();
			RegisterIL2cpp();
			SetKeyBind();
			_Harmony.PatchAll();
		}

		private void RegisterIL2cpp()
		{
			ClassInjector.RegisterTypeInIl2Cpp<InputKeyBindUpdate>();
			ClassInjector.RegisterTypeInIl2Cpp<ZOrderedSortingGroup>();
			ClassInjector.RegisterTypeInIl2Cpp<PlayerIconInstance>();
			ClassInjector.RegisterTypeInIl2Cpp<VCFrame>();
		}

		private static void SetModStamp()
		{
			SceneManager.sceneLoaded += UnityAction<Scene, LoadSceneMode>.op_Implicit((Action<Scene, LoadSceneMode>)delegate
			{
				if (DestroyableSingleton<ModManager>.InstanceExists)
				{
					DestroyableSingleton<ModManager>.Instance.ShowModStamp();
				}
			});
		}

		private void SetKeyBind()
		{
			((BasePlugin)(object)this).AddComponent<InputKeyBindUpdate>();
			InputKeyBindUpdate.Register("VoiceMute", delegate
			{
				LocalPlayer.Instance?.SetMicState();
			}, (KeyCode)109);
		}

		private static void SetWrite()
		{
			LibDir = Path.Combine(Paths.GameRootPath, "Library");
			if (!Directory.Exists(LibDir))
			{
				Directory.CreateDirectory(LibDir);
			}
			ResourceLib[] resourceLibs = Libs.ResourceLibs;
			foreach (ResourceLib resourceLib in resourceLibs)
			{
				resourceLib.Write(LibDir);
			}
			NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), Resolver);
			static IntPtr Resolver(string library, Assembly assembly, DllImportSearchPath? search)
			{
				string text = Path.Combine(LibDir, library + ".dll");
				LogHelper.LogInfo($"Resolver: {library} {assembly.GetName()} " + text);
				if (File.Exists(text) && NativeLibrary.TryLoad(text, out var handle))
				{
					return handle;
				}
				return IntPtr.Zero;
			}
		}

		public override bool Unload()
		{
			AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolve;
			return ((BasePlugin)this).Unload();
		}

		private static Assembly? AssemblyResolve(object? sender, ResolveEventArgs args)
		{
			AssemblyName assemblyName = new AssemblyName(args.Name);
			string path = Path.Combine(LibDir, assemblyName.Name + ".dll");
			return File.Exists(path) ? Assembly.LoadFile(path) : null;
		}
	}
	public record VoiceComponent(string Name, int Id, object Component)
	{
		public int Channels { get; set; }

		public bool IsMic => Component is WaveInCapabilities;

		public bool IsSpeaker => Component is WaveOutCapabilities;

		public bool IsWasApi => Component is MMDevice;

		public static implicit operator WaveInCapabilities?(VoiceComponent component)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!component.IsMic)
			{
				return null;
			}
			return (WaveInCapabilities)component.Component;
		}

		public static implicit operator WaveOutCapabilities?(VoiceComponent component)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!component.IsSpeaker)
			{
				return null;
			}
			return (WaveOutCapabilities)component.Component;
		}

		public static implicit operator MMDevice?(VoiceComponent component)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!component.IsWasApi)
			{
				return null;
			}
			return (MMDevice)component.Component;
		}
	}
	public class NextVoiceManager : InstanceClass<NextVoiceManager>
	{
		private bool waveInState;

		public List<INextPlayer> Players { get; set; } = new List<INextPlayer>();


		public INetworkEndpoint? Endpoint { get; private set; }

		private List<VoiceComponent> _Components { get; set; } = new List<VoiceComponent>();


		public IReadOnlyList<VoiceComponent> Components => _Components.AsReadOnly();

		public VoiceComponent? CurrentMic { get; private set; }

		public VoiceComponent? CurrentSpeaker { get; private set; }

		public WaveTool? _WaveTool { get; private set; }

		public VoiceConfig? _Config { get; private set; }

		public int LastId { get; private set; }

		public MixingSampleProvider? MixingProvider { get; private set; }

		public IWavePlayer? CurrentOutput { get; private set; }

		public bool State
		{
			get
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				IWavePlayer? currentOutput = CurrentOutput;
				return currentOutput != null && (int)currentOutput.PlaybackState == 1;
			}
		}

		public NextVoiceManager()
		{
			InstanceClass<NextVoiceManager>._Instance = this;
			ChangeEndpoint(ConnectionMode.Rpc);
			GetAllComponents();
			ChangeConfig(VoiceConfig.CreateDefault());
			SetDefault();
		}

		public void ChangeConfig(VoiceConfig config)
		{
			_Config = config;
			if (LocalPlayer.Instance != null)
			{
				LocalPlayer.Instance.Config = _Config;
			}
			ReInitTool();
		}

		public NextAudioData? GenerateAudioData(byte[] data)
		{
			if (_WaveTool == null || _Config == null || _WaveTool.Encoder == null)
			{
				return null;
			}
			LastId++;
			return new NextAudioData
			{
				Player = LocalPlayer.Instance,
				dataId = LastId
			}.AddFormInfo(new EncodeInfo(_Config.BuffedLength, _WaveTool.Encoder, data));
		}

		public DecodeInfo? GetDecodeInfo(NextAudioData data)
		{
			if (_WaveTool == null || _Config == null || _WaveTool.Decoder == null)
			{
				return null;
			}
			data.GetDecodeByte(_WaveTool.Decoder, _Config.BuffedLength, out int length, out byte[] Data);
			return new DecodeInfo(length, Data);
		}

		public void ReInitTool()
		{
			if (_Config == null)
			{
				LogHelper.LogWarning("Config is null, not ReInitTool");
				return;
			}
			_WaveTool?.Dispose();
			_WaveTool = WaveTool.BuildFormConfig(_Config, buildInEvent: true, buildWasapiOut: true);
			_WaveTool.WaveIn.DataAvailable += LocalPlayer.OnDataReceived;
			_WaveTool.WaveIn.RecordingStopped += delegate
			{
				waveInState = false;
				LocalPlayer.Instance.IsSpeaking = false;
			};
			waveInState = false;
			MixingProvider = _Config.BuildMixingSampleProvider();
			foreach (INextPlayer player in Players)
			{
				((DefaultPlayer)player).AddProvider(_Config, MixingProvider);
			}
			CurrentOutput = (IWavePlayer?)(object)_WaveTool.WasapiWaveOut;
			SetSpeakerPlay();
		}

		public DefaultPlayer GetPlayer(byte id)
		{
			return (DefaultPlayer)Players.First((INextPlayer n) => n.player.PlayerId == id);
		}

		public bool TryGetPlayer(byte id, [MaybeNullWhen(false)] out DefaultPlayer player)
		{
			player = Players.FirstOrDefault((INextPlayer n) => n.player.PlayerId == id) as DefaultPlayer;
			return player != null;
		}

		public void SetSpeakerPlay()
		{
			if (CurrentOutput != null)
			{
				WaveExtensionMethods.Init(CurrentOutput, (ISampleProvider)(object)MixingProvider, false);
				CurrentOutput.Play();
				LogHelper.LogInfo("Set Speaker Play");
			}
		}

		public void UpdateToolState()
		{
			if (CurrentMic == null || CurrentSpeaker == null)
			{
				SetDefault();
			}
			if (_WaveTool == null)
			{
				ReInitTool();
			}
			if (!_WaveTool.BuildInEvent)
			{
				return;
			}
			if (LocalPlayer.MicEnabled)
			{
				if (waveInState)
				{
					return;
				}
				WaveTool? waveTool = _WaveTool;
				if (waveTool != null)
				{
					WaveInEvent? waveIn = waveTool.WaveIn;
					if (waveIn != null)
					{
						waveIn.StartRecording();
					}
				}
				waveInState = true;
			}
			else
			{
				if (!waveInState)
				{
					return;
				}
				WaveTool? waveTool2 = _WaveTool;
				if (waveTool2 != null)
				{
					WaveInEvent? waveIn2 = waveTool2.WaveIn;
					if (waveIn2 != null)
					{
						waveIn2.StopRecording();
					}
				}
				waveInState = false;
			}
		}

		public void ChangeComponent(VoiceComponent component)
		{
			if (component.IsSpeaker)
			{
				CurrentSpeaker = component;
				IWavePlayer? currentOutput = CurrentOutput;
				WaveOutEvent val = (WaveOutEvent)(object)((currentOutput is WaveOutEvent) ? currentOutput : null);
				if (val != null)
				{
					val.DeviceNumber = component.Id;
				}
				LogHelper.LogInfo("SetSpeaker " + component.Name);
			}
			if (component.IsMic)
			{
				CurrentMic = component;
				if (_WaveTool?.WaveIn != null)
				{
					_WaveTool.WaveIn.DeviceNumber = component.Id;
				}
				LogHelper.LogInfo("SetMic " + component.Name);
			}
			if ((object)component != null && !component.IsMic && !component.IsSpeaker)
			{
				LogHelper.LogWarning($"Unknown component name:{component.Name} Id:{component.Id} Type:{component.Component.GetType().Name}");
			}
		}

		public void GetAllComponents()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			_Components.Clear();
			int num = 0;
			foreach (WaveInCapabilities item in GetAllMic())
			{
				WaveInCapabilities current = item;
				_Components.Add(new VoiceComponent(((WaveInCapabilities)(ref current)).ProductName, num, current)
				{
					Channels = ((WaveInCapabilities)(ref current)).Channels
				});
				LogHelper.LogInfo($"Add Mic {((WaveInCapabilities)(ref current)).ProductName} {num}");
				num++;
			}
			num = 0;
			foreach (WaveOutCapabilities item2 in GetAllSpeaker())
			{
				WaveOutCapabilities current2 = item2;
				_Components.Add(new VoiceComponent(((WaveOutCapabilities)(ref current2)).ProductName, num, current2)
				{
					Channels = ((WaveOutCapabilities)(ref current2)).Channels
				});
				LogHelper.LogInfo($"Add Speaker {((WaveOutCapabilities)(ref current2)).ProductName} {num}");
				num++;
			}
			num = 0;
			foreach (MMDevice item3 in new MMDeviceEnumerator().EnumerateAudioEndPoints((DataFlow)1, (DeviceState)1))
			{
				_Components.Add(new VoiceComponent(item3.DeviceFriendlyName, num, item3));
				LogHelper.LogInfo($"Add Mic {item3.DeviceFriendlyName} {num}");
				num++;
			}
		}

		public void SetDefault()
		{
			LogHelper.LogInfo("SetDefault Components");
			VoiceComponent voiceComponent = Components.FirstOrDefault((VoiceComponent n) => n.IsMic);
			VoiceComponent voiceComponent2 = Components.FirstOrDefault((VoiceComponent n) => n.IsSpeaker);
			if (voiceComponent != null)
			{
				ChangeComponent(voiceComponent);
			}
			if (voiceComponent2 != null)
			{
				ChangeComponent(voiceComponent2);
			}
		}

		public static IEnumerable<WaveInCapabilities> GetAllMic()
		{
			for (int i = 0; i < WaveInEvent.DeviceCount; i++)
			{
				yield return WaveInEvent.GetCapabilities(i);
			}
		}

		public static IEnumerable<WaveOutCapabilities> GetAllSpeaker()
		{
			for (int j = 0; j < WaveInterop.waveOutGetNumDevs(); j++)
			{
				yield return GetCapabilities(j);
			}
			static WaveOutCapabilities GetCapabilities(int i)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: 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)
				WaveOutCapabilities val = default(WaveOutCapabilities);
				int num = Marshal.SizeOf<WaveOutCapabilities>(val);
				MmException.Try(WaveInterop.waveOutGetDevCaps((IntPtr)i, ref val, num), "WaveOutGetDevCaps");
				return val;
			}
		}

		public INextPlayer CreatePlayer(PlayerControl player)
		{
			PlayerControl player2 = player;
			Players.FirstOrDefault((INextPlayer n) => (Object)(object)n.player == (Object)(object)player2)?.Dispose();
			DefaultPlayer defaultPlayer = (((Object)(object)player2 == (Object)(object)PlayerControl.LocalPlayer) ? new LocalPlayer(player2)
			{
				Config = _Config
			} : new DefaultPlayer(player2));
			if (MixingProvider != null && _Config != null)
			{
				defaultPlayer.AddProvider(_Config, MixingProvider);
			}
			defaultPlayer.Create();
			Players.Add(defaultPlayer);
			return defaultPlayer;
		}

		public void ChangeEndpoint(ConnectionMode connectionMode)
		{
			INetworkEndpoint? endpoint = Endpoint;
			if (endpoint == null || endpoint.Mode != connectionMode)
			{
				Endpoint?.Stop();
				if (1 == 0)
				{
				}
				INetworkEndpoint endpoint2 = connectionMode switch
				{
					ConnectionMode.Rpc => new RPCNetworkEndpoint(), 
					ConnectionMode.Server => new ServerNetworkEndpoint(), 
					_ => new RPCNetworkEndpoint(), 
				};
				if (1 == 0)
				{
				}
				Endpoint = endpoint2;
				Endpoint.Start();
			}
		}
	}
}
namespace Next_Chat.Patches
{
	[Harmony]
	internal static class ChatChannelPatch
	{
		public static GameObject? ChatChannelButton { get; internal set; }

		public static PassiveButton? ChatChannelPassiveButton { get; internal set; }

		public static SpriteRenderer? ChatChannelButtonSpriteRenderer { get; internal set; }

		internal static void UpdateChannelButton()
		{
			if (Object.op_Implicit((Object)(object)ChatChannelButtonSpriteRenderer))
			{
				ChatChannelButtonSpriteRenderer.sprite = InstanceClass<ChatChannelManager>.Instance.CurrentChannel;
			}
			if (InstanceClass<ChatChannelManager>.Instance.hasNext)
			{
				InstanceClass<ChatChannelManager>.Instance.UpdateChatBubbles();
			}
		}

		[HarmonyPatch(typeof(ChatController), "Toggle")]
		[HarmonyPostfix]
		private static void ChatControllerAwake(ChatController __instance)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)ChatChannelButton))
			{
				GameObject gameObject = ((Component)((Component)__instance.banButton).transform.parent.Find("BanMenuButton")).gameObject;
				ChatChannelButton = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent, true);
				((Object)ChatChannelButton).name = "ChatChannelButton";
				Transform transform = ChatChannelButton.transform;
				transform.localPosition += new Vector3(0f, 0.7f, 0f);
				ChatChannelPassiveButton = ChatChannelButton.GetComponent<PassiveButton>();
				((Object)(object)((Component)ChatChannelButton.transform.GetChild(1)).gameObject).Destroy();
				GameObject gameObject2 = ((Component)ChatChannelButton.transform.GetChild(0)).gameObject;
				Transform transform2 = gameObject2.transform;
				transform2.localPosition += new Vector3(0f, 0.06f, 0f);
				ChatChannelButtonSpriteRenderer = gameObject2.GetComponent<SpriteRenderer>();
				ChatChannelPassiveButton.OnClick = new ButtonClickedEvent();
				((UnityEvent)(object)ChatChannelPassiveButton.OnClick).AddListener(delegate
				{
					InstanceClass<ChatChannelManager>.Instance.NextChannel();
					UpdateChannelButton();
				});
				UpdateChannelButton();
			}
		}

		[HarmonyPatch(typeof(PlayerControl), "RpcSendChat")]
		[HarmonyPrefix]
		private static bool SendChatPrefix(PlayerControl __instance, string chatText, ref bool __result)
		{
			chatText = Regex.Replace(chatText, "<.*?>", string.Empty);
			if (string.IsNullOrWhiteSpace(chatText))
			{
				__result = false;
				return false;
			}
			if (((InnerNetClient)AmongUsClient.Instance).AmClient && Object.op_Implicit((Object)(object)DestroyableSingleton<HudManager>.Instance))
			{
				InstanceClass<ChatChannelManager>.Instance.AddChat(__instance, chatText, InstanceClass<ChatChannelManager>.Instance.CurrentChannel);
			}
			MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpc(((InnerNetObject)__instance).NetId, (byte)13, (SendOption)1);
			val.Write(chatText);
			val.Write(InstanceClass<ChatChannelManager>.Instance.CurrentChannelIndex);
			val.EndMessage();
			__result = true;
			return false;
		}

		[HarmonyPatch(typeof(PlayerControl), "RpcSendQuickChat")]
		[HarmonyPrefix]
		private static bool SendQuickChatPrefix(PlayerControl __instance, QuickChatPhraseBuilderResult data, ref bool __result)
		{
			string text = data.ToChatText();
			if (string.IsNullOrWhiteSpace(text) || !data.IsValid())
			{
				__result = false;
			}
			if (((InnerNetClient)AmongUsClient.Instance).AmClient && Object.op_Implicit((Object)(object)DestroyableSingleton<HudManager>.Instance))
			{
				InstanceClass<ChatChannelManager>.Instance.AddChat(__instance, text, InstanceClass<ChatChannelManager>.Instance.CurrentChannel, censor: false);
			}
			MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpc(((InnerNetObject)__instance).NetId, (byte)33, (SendOption)1);
			QuickChatNetData.Serialize(data, val);
			val.Write(InstanceClass<ChatChannelManager>.Instance.CurrentChannelIndex);
			val.EndMessage();
			return true;
		}

		[HarmonyPatch(typeof(PlayerControl), "HandleRpc")]
		[HarmonyPrefix]
		private static bool ChatPRCPrefix(PlayerControl __instance, byte callId, MessageReader reader)
		{
			if (callId != 11 && callId != 33)
			{
				return true;
			}
			if (callId == 11)
			{
				string chatText = reader.ReadString();
				int channel = reader.ReadInt32();
				if (Object.op_Implicit((Object)(object)DestroyableSingleton<HudManager>.Instance))
				{
					InstanceClass<ChatChannelManager>.Instance.AddChat(__instance, chatText, channel);
				}
			}
			if (callId == 33)
			{
				QuickChatPhraseBuilderResult val = QuickChatNetData.Deserialize(reader);
				int channel2 = reader.ReadInt32();
				if (Object.op_Implicit((Object)(object)DestroyableSingleton<HudManager>.Instance))
				{
					InstanceClass<ChatChannelManager>.Instance.AddChat(__instance, val.ToChatText(), channel2, censor: false);
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(ChatController), "AlignAllBubbles")]
		[HarmonyPrefix]
		private static bool AlignAllBubblesPrefix(ChatController __instance)
		{
			InstanceClass<ChatChannelManager>.Instance.UpdateChatBubbles();
			return false;
		}

		[HarmonyPatch(typeof(HudManager), "OnGameStart")]
		[HarmonyPatch(typeof(MeetingHud), "Close")]
		[HarmonyPostfix]
		private static void ChatSetVisible()
		{
			InstanceClass<ChatChannelManager>.Instance.UpdateChatVisible();
		}

		[HarmonyPatch(typeof(MeetingHud), "ServerStart")]
		[HarmonyPostfix]
		private static void OnMeetingHudStart()
		{
			InstanceClass<ChatChannelManager>.Instance.UpdateCanUseChannels();
		}
	}
	public sealed class InputKeyBindUpdate : MonoBehaviour
	{
		public record KeyBind(string name, Action OnInput, params KeyCode[] KeyCodes)
		{
			public bool IsPressed()
			{
				return ((IEnumerable<KeyCode>)KeyCodes).All((Func<KeyCode, bool>)Input.GetKeyDown);
			}
		}

		private static readonly List<KeyBind> AllBind = new List<KeyBind>();

		public static void Register(string name, Action onInput, params KeyCode[] keyCodes)
		{
			Register(new KeyBind(name, onInput, keyCodes));
		}

		public static void Register(string name, Action onInput, KeyCode key)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			Register(name, onInput, (KeyCode[])(object)new KeyCode[1] { (KeyCode)(int)key });
		}

		public static void Register(KeyBind bind)
		{
			KeyBind bind2 = bind;
			if (bind2.KeyCodes.Length != 0 && !AllBind.Any((KeyBind n) => n.name == bind2.name))
			{
				AllBind.Add(bind2);
			}
		}

		public void Update()
		{
			foreach (KeyBind item in AllBind.Where((KeyBind n) => n.IsPressed()))
			{
				LogHelper.LogInfo("Input " + item.name + " " + string.Join(',', item.KeyCodes.Select((KeyCode n) => ((object)(KeyCode)(ref n)).ToString())));
				item.OnInput();
			}
		}

		public void FixedUpdate()
		{
			foreach (INextPlayer player in InstanceClass<NextVoiceManager>.Instance.Players)
			{
				player.OnUpdate();
			}
			PlayersOverlay.Instance?.OnUpdate();
		}
	}
	[Harmony]
	public static class OptionPatch
	{
	}
	[Harmony]
	public class PlayerPatch
	{
		public static PlayersOverlay? Overlay { get; set; }

		[HarmonyPatch(typeof(AmongUsClient), "OnPlayerJoined")]
		[HarmonyPostfix]
		private static void OnPlayerJoinedPatch(ClientData data)
		{
			InstanceClass<NextVoiceManager>.Instance.CreatePlayer(data.Character);
		}

		[HarmonyPatch(typeof(HudManager), "Update")]
		[HarmonyPostfix]
		private static void UpdatePatch()
		{
			if (Overlay == null)
			{
				Overlay = new PlayersOverlay((PlayerIconInstance n) => InstanceClass<NextVoiceManager>.Instance.GetPlayer(n.player.PlayerId).IsSpeaking);
			}
		}

		[HarmonyPatch(typeof(AmongUsClient), "OnPlayerJoined")]
		[HarmonyPostfix]
		private static void OnPlayerCreate(ClientData data)
		{
			RPCFlag.HasInstall.SendRpcToAll((SendOption)0, delegate(MessageWriter writer)
			{
				writer.Write(LocalPlayer.Instance.player.PlayerId);
			});
		}

		[HarmonyPatch(typeof(PlayerControl), "OnDestroy")]
		[HarmonyPrefix]
		private static void OnPlayerDestroy(PlayerControl __instance)
		{
			PlayerControl __instance2 = __instance;
			foreach (INextPlayer item in InstanceClass<NextVoiceManager>.Instance.Players.Where((INextPlayer n) => (Object)(object)n.player == (Object)(object)__instance2).ToList())
			{
				item.Dispose();
			}
			PlayerIconInstance playerIconInstance = PlayersOverlay.Instance?._AllInstance.FirstOrDefault((PlayerIconInstance n) => (Object)(object)n.player == (Object)(object)__instance2);
			if (playerIconInstance != null)
			{
				playerIconInstance.player = null;
			}
		}

		[HarmonyPatch(typeof(PlayerVoteArea), "SetTargetPlayerId")]
		[HarmonyPostfix]
		private static void MeetingVCFramePatch(PlayerVoteArea __instance)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (!InstanceClass<NextVoiceManager>.Instance.TryGetPlayer(__instance.TargetPlayerId, out DefaultPlayer player))
			{
				return;
			}
			try
			{
				player.Frame = UnityHelper.CreateObject<VCFrame>("VCFrame", ((Component)__instance).transform, new Vector3(0f, 0f, -0.5f), (int?)null);
				VCFrame frame = player.Frame;
				VCFrame vCFrame = frame;
				if (vCFrame.Renderer == null)
				{
					vCFrame.Renderer = UnityHelper.CreateObject<SpriteRenderer>("VCFrameSprite", ((Component)__instance).transform, new Vector3(0f, 0f, -0.5f), (int?)null);
				}
				frame.Renderer.sprite = Sprites.MeetingVCFrame;
				frame.Renderer.color = Color.clear;
				frame.Player = player;
				frame.SetPlayer(__instance);
			}
			catch
			{
				LogHelper.LogWarning($"Create VCFrame failed Id:{__instance.TargetPlayerId}");
			}
		}

		[HarmonyPatch(typeof(PlayerVoteArea), "OnDestroy")]
		[HarmonyPrefix]
		private static void MeetingVCFrameDestroyPatch(PlayerVoteArea __instance)
		{
			DefaultPlayer player = InstanceClass<NextVoiceManager>.Instance.GetPlayer(__instance.TargetPlayerId);
			if (player.Frame != null)
			{
				((Object)(object)player.Frame).Destroy();
				player.Frame = null;
			}
		}
	}
	[Harmony]
	public static class RPCPatch
	{
		public static readonly byte[] RpcIds = (from n in Enum.GetValues<RPCFlag>()
			select (byte)n).ToArray();

		public static Dictionary<RPCFlag, Action<MessageReader>> rpcHandlers = new Dictionary<RPCFlag, Action<MessageReader>>();

		[HarmonyPatch(typeof(_HandleGameDataInner_d__41), "MoveNext")]
		public static bool Prefix(_HandleGameDataInner_d__41 __instance, ref bool __result)
		{
			if (__instance.reader.Tag != 2 || __instance.__1__state != 0)
			{
				return true;
			}
			MessageReader val = MessageReader.Get(__instance.reader);
			val.ReadPackedUInt32();
			byte b = val.ReadByte();
			if (!RpcIds.Contains(b))
			{
				val.Recycle();
				return true;
			}
			if (rpcHandlers.TryGetValue((RPCFlag)b, out Action<MessageReader> value))
			{
				value(val);
			}
			val.Recycle();
			__result = false;
			return false;
		}

		public static byte ToByte(this RPCFlag flag)
		{
			return (byte)flag;
		}

		public static void SendRpcToAll(this RPCFlag flag, SendOption option, Action<MessageWriter> write, uint netId = 25u)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			SendRpcToAll(flag.ToByte(), option, write, netId);
		}

		public static void SendRpcToPlayer(this RPCFlag flag, SendOption option, Action<MessageWriter> write, int playerId, uint netId = 25u)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			SendRpcToPlayer(flag.ToByte(), option, write, playerId, netId);
		}

		public static void SendRpcToAll(byte rpc, SendOption option, Action<MessageWriter> write, uint netId = 25u)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			MessageWriter val = MessageWriter.Get(option);
			val.StartMessage((byte)5);
			val.Write(((InnerNetClient)AmongUsClient.Instance).GameId);
			val.StartMessage((byte)2);
			val.WritePacked(netId);
			val.Write(rpc);
			write(val);
			val.EndMessage();
			val.EndMessage();
			((InnerNetClient)AmongUsClient.Instance).SendOrDisconnect(val);
			val.Recycle();
		}

		public static void SendRpcToPlayer(byte rpc, SendOption option, Action<MessageWriter> write, int playerId, uint netId = 25u)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			MessageWriter val = MessageWriter.Get(option);
			val.StartMessage((byte)6);
			val.Write(((InnerNetClient)AmongUsClient.Instance).GameId);
			val.WritePacked(playerId);
			val.StartMessage((byte)2);
			val.WritePacked(netId);
			val.Write(rpc);
			write(val);
			val.EndMessage();
			val.EndMessage();
			((InnerNetClient)AmongUsClient.Instance).SendOrDisconnect(val);
			val.Recycle();
		}
	}
	[Harmony]
	public class VoicePatch
	{
		public static GameObject? MicButton { get; internal set; }

		public static PassiveButton? MicPassiveButton { get; internal set; }

		public static SpriteRenderer? MicButtonSpriteRenderer { get; internal set; }

		public static TextMeshPro? MicButtonText { get; internal set; }

		[HarmonyPatch(typeof(HudManager), "ToggleUseAndPetButton")]
		[HarmonyPostfix]
		private static void VoiceButtonPatch(HudManager __instance)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)MicButton))
			{
				return;
			}
			KillButton killButton = __instance.KillButton;
			if (Object.op_Implicit((Object)(object)killButton))
			{
				MicButton = Object.Instantiate<GameObject>(((Component)killButton).gameObject, ((Component)killButton).transform.parent);
				((Object)MicButton).name = "MicButton";
				MicButtonSpriteRenderer = MicButton.GetComponent<SpriteRenderer>();
				((Object)(object)MicButton.GetComponent<KillButton>()).Destroy();
				Transform child = MicButton.transform.GetChild(2);
				MicButtonText = ((Component)child).GetComponent<TextMeshPro>();
				MicButton.DestroyAllChildren<TextTranslatorTMP>();
				MicPassiveButton = MicButton.GetComponent<PassiveButton>();
				MicPassiveButton.OnClick = new ButtonClickedEvent();
				((UnityEvent)(object)MicPassiveButton.OnClick).AddListener(delegate
				{
					LocalPlayer.Instance?.SetMicState();
				});
				MicButton.SetActive(true);
				MicButton.GetComponent<BoxCollider2D>().size = MicButtonSpriteRenderer.size;
				UpdateSprite();
			}
		}

		public static void UpdateSprite()
		{
			if (!((Object)(object)MicButtonSpriteRenderer == (Object)null) && !((Object)(object)MicButtonText == (Object)null))
			{
				MicButtonSpriteRenderer.sprite = (LocalPlayer.MicEnabled ? Sprites.MicOn : Sprites.MicOff);
				((TMP_Text)MicButtonText).text = (LocalPlayer.MicEnabled ? "开麦" : "闭麦");
				LogHelper.LogInfo("UpdateMicSprite");
			}
		}

		[HarmonyPatch(typeof(AmongUsClient), "OnPlayerJoined")]
		[HarmonyPostfix]
		private static void OnPlayerJoinedPatch(AmongUsClient __instance, ClientData data)
		{
			if (LocalPlayer.Instance != null)
			{
				RPCFlag.SyncConfig.SendRpcToPlayer((SendOption)0, delegate(MessageWriter write)
				{
					write.Write(LocalPlayer.Instance.player.PlayerId);
					InstanceClass<NextVoiceManager>.Instance._Config.RpcWrite(write);
				}, data.Id);
			}
		}

		[HarmonyPatch(typeof(AmongUsClient), "OnGameJoined")]
		[HarmonyPostfix]
		private static void OnGameJoinedPatch(AmongUsClient __instance)
		{
			if (LocalPlayer.Instance != null)
			{
				RPCFlag.SyncConfig.SendRpcToAll((SendOption)0, delegate(MessageWriter write)
				{
					write.Write(LocalPlayer.Instance.player.PlayerId);
					InstanceClass<NextVoiceManager>.Instance._Config.RpcWrite(write);
				});
			}
		}
	}
}
namespace Next_Chat.Default
{
	public class DefaultOptionCreator : IOptionCreator
	{
		public void CreateBoolOption(string Title, bool value, Action<bool> Set)
		{
		}

		public void CreateIntOption(string Title, int value, Action<int> Set, params int[] Values)
		{
		}
	}
	public class DefaultPlayer : PlayerVCInstance, INextPlayer, IDisposable
	{
		private readonly List<NextAudioData> AllKeepData;

		internal readonly List<NextAudioData> _allData;

		public PlayerControl player { get; set; }

		public PlayerStates state { get; set; }

		public bool IsSpeaking { get; set; }

		public bool HasInstall { get; set; }

		public int LastDataId { get; set; }

		public BufferedWaveProvider? BufferedProvider { get; set; }

		public Wave16ToFloatProvider? _FloatProvider { get; set; }

		public SampleProviderConverterBase? SampleProvider { get; set; }

		public VolumeSampleProvider? VolumeProvider { get; set; }

		public VoiceConfig? Config { get; set; }

		public float Volume { get; private set; }

		protected override INextPlayer _player => this;

		public DefaultPlayer(PlayerControl player)
		{
			this.player = player;
			state = PlayerStates.Play;
			AllKeepData = new List<NextAudioData>();
			_allData = new List<NextAudioData>();
			base..ctor();
		}

		public void AddLocalData(byte[] bytes, int length)
		{
			BufferedWaveProvider? bufferedProvider = BufferedProvider;
			if (bufferedProvider != null)
			{
				bufferedProvider.AddSamples(bytes, 0, length);
			}
			IsSpeaking = true;
			LogHelper.LogInfo($"BufferedProvider AddSamples {length}");
		}

		public virtual void OnUpdate()
		{
			if (InstanceClass<NextVoiceManager>.Instance._WaveTool != null && InstanceClass<NextVoiceManager>.Instance._WaveTool.Decoder != null)
			{
				if (AllKeepData.Count != 0 && AllKeepData[0].dataId == LastDataId + 1)
				{
					PushData(AllKeepData[0]);
				}
				if (_allData.Count == 0)
				{
					BufferedWaveProvider? bufferedProvider = BufferedProvider;
					IsSpeaking = bufferedProvider == null || bufferedProvider.BufferedBytes / 2 != 0;
					return;
				}
				if (state.HasFlag(PlayerStates.Ban))
				{
					_allData[0].Dispose();
					_allData.RemoveAt(0);
					IsSpeaking = false;
					return;
				}
				NextAudioData nextAudioData = _allData[0];
				AddDataToProvider(nextAudioData);
				nextAudioData.Dispose();
				_allData.RemoveAt(0);
				BufferedWaveProvider? bufferedProvider2 = BufferedProvider;
				IsSpeaking = bufferedProvider2 == null || bufferedProvider2.BufferedBytes / 2 != 0;
			}
		}

		public virtual void AddDataToProvider(NextAudioData data)
		{
			DecodeInfo decodeInfo = InstanceClass<NextVoiceManager>.Instance.GetDecodeInfo(data);
			if (!(decodeInfo == null))
			{
				BufferedWaveProvider? bufferedProvider = BufferedProvider;
				if (bufferedProvider != null)
				{
					bufferedProvider.AddSamples(decodeInfo.Data, 0, decodeInfo.buffedLength);
				}
				LogHelper.LogInfo($"AddData dataId:{data.dataId} length:{decodeInfo.buffedLength}");
			}
		}

		public void AddData(NextAudioData data)
		{
			NextAudioData data2 = data;
			if (!_allData.Exists((NextAudioData n) => n.dataId == data2.dataId))
			{
				if (data2.dataId > LastDataId + 1 && data2.dataId < LastDataId + 10)
				{
					KeepData(data2);
				}
				else
				{
					PushData(data2);
				}
			}
		}

		public void PushData(NextAudioData data)
		{
			NextAudioData data2 = data;
			AllKeepData.RemoveAll((NextAudioData n) => n.dataId == data2.dataId);
			_allData.Add(data2);
			LastDataId = data2.dataId;
			LogHelper.LogInfo($"push data {data2.dataId}");
		}

		public void KeepData(NextAudioData data)
		{
			AllKeepData.Add(data);
			AllKeepData.Sort((NextAudioData x, NextAudioData y) => x.dataId.CompareTo(y.dataId));
		}

		public virtual void Dispose()
		{
			InstanceClass<NextVoiceManager>.Instance.Players.Remove(this);
			if (InstanceClass<NextVoiceManager>.Instance.MixingProvider != null)
			{
				InstanceClass<NextVoiceManager>.Instance.MixingProvider.RemoveMixerInput((ISampleProvider)(object)VolumeProvider);
			}
		}

		public void Ban()
		{
			state |= PlayerStates.Ban;
		}

		public void UnBan()
		{
			state &= ~PlayerStates.Ban;
		}

		public void Silence()
		{
			state |= PlayerStates.Silence;
		}

		public void UnSilence()
		{
			state &= ~PlayerStates.Silence;
		}

		static DefaultPlayer()
		{
			RPCPatch.rpcHandlers.Add(RPCFlag.HasInstall, delegate(MessageReader reader)
			{
				DefaultPlayer defaultPlayer = InstanceClass<NextVoiceManager>.Instance.GetPlayer(reader.ReadByte());
				defaultPlayer.HasInstall = true;
			});
		}
	}
	public class LocalPlayer : DefaultPlayer
	{
		public static bool MicEnabled { get; set; } = true;


		public static bool SpeakerEnabled { get; set; } = true;


		public static LocalPlayer? Instance
		{
			get
			{
				if ((Object)(object)PlayerControl.LocalPlayer == (Object)null)
				{
					return null;
				}
				INextPlayer nextPlayer = InstanceClass<NextVoiceManager>.Instance.Players.FirstOrDefault((INextPlayer n) => (Object)(object)n.player == (Object)(object)PlayerControl.LocalPlayer);
				if (nextPlayer != null)
				{
					return nextPlayer as LocalPlayer;
				}
				return InstanceClass<NextVoiceManager>.Instance.CreatePlayer(PlayerControl.LocalPlayer) as LocalPlayer;
			}
		}

		private static WaveTool? Tool => InstanceClass<NextVoiceManager>.Instance._WaveTool;

		public LocalPlayer(PlayerControl player)
			: base(player)
		{
		}

		public override void Dispose()
		{
			WaveTool tool = Tool;
			if (tool != null && tool.WaveIn != null)
			{
				Tool.WaveIn.DataAvailable -= OnDataReceived;
			}
			base.Dispose();
		}

		public void SetMicState()
		{
			SetMicState(!MicEnabled);
		}

		public void SetMicState(bool _state)
		{
			MicEnabled = _state;
			if (_state)
			{
				base.state |= PlayerStates.Play;
				base.state &= (PlayerStates)(-1);
			}
			else
			{
				base.state &= PlayerStates.Play;
				base.state |= (PlayerStates)(-1);
			}
			LogHelper.LogInfo("mic: " + MicEnabled);
			VoicePatch.UpdateSprite();
			InstanceClass<NextVoiceManager>.Instance.UpdateToolState();
		}

		public void SetSpeakerState(bool _state)
		{
			SpeakerEnabled = _state;
			InstanceClass<NextVoiceManager>.Instance.UpdateToolState();
		}

		public static void OnDataReceived(object? sender, WaveInEventArgs e)
		{
			if (Tool == null || !Tool.BuildVad || !Tool.Vad.HasSpeech(e.Buffer))
			{
				return;
			}
			if (InstanceClass<NextVoiceManager>.Instance.Players.Count <= 1)
			{
				Instance?.AddLocalData(e.Buffer, e.BytesRecorded);
				LogHelper.LogInfo($"Add LocalDataLength {e.BytesRecorded}");
				return;
			}
			NextAudioData nextAudioData = InstanceClass<NextVoiceManager>.Instance.GenerateAudioData(e.Buffer);
			if (nextAudioData != null)
			{
				LogHelper.LogInfo($"GenerateAudioData: {nextAudioData.dataId} : {e.BytesRecorded} : {nextAudioData.Length}");
				InstanceClass<NextVoiceManager>.Instance.Endpoint?.Send(nextAudioData);
			}
		}
	}
	internal class RPCNetworkEndpoint : INetworkEndpoint
	{
		public bool Starting;

		public ConnectionMode Mode { get; init; } = ConnectionMode.Rpc;


		public void Start()
		{
			if (!Starting)
			{
				RPCPatch.rpcHandlers.Add(RPCFlag.Send, delegate(MessageReader reader)
				{
					NextAudioData nextAudioData = new NextAudioData();
					nextAudioData.RpcRead(reader);
					LogHelper.LogInfo($"receive AudioDar Id:{nextAudioData.dataId} Length:{nextAudioData.Length} sender:{((Object)nextAudioData.Player.player).name}");
					nextAudioData.Player.AddData(nextAudioData);
				});
				Starting = true;
			}
		}

		public void Send(NextAudioData data)
		{
			if (Starting)
			{
				RPCFlag.Send.SendRpcToAll((SendOption)0, data.RpcWrite);
				LogHelper.LogInfo($"send AudioDar Id:{data.dataId} Length:{data.Length}");
			}
		}

		public void Stop()
		{
			RPCPatch.rpcHandlers.Remove(RPCFlag.Send);
			Starting = false;
		}
	}
	public class ServerNetworkEndpoint : INetworkEndpoint
	{
		private bool started = false;

		public ConnectionMode Mode { get; init; }

		public string address { get; set; } = string.Empty;


		public int port { get; set; } = 0;


		private HttpClient? _client { get; set; }

		private UnityUdpClientConnection? _udpClient { get; set; }

		private string udpAddress { get; set; } = string.Empty;


		private int udpPort { get; set; } = 0;


		public void Start()
		{
			if (!(address == string.Empty) && port != 0)
			{
				if (_client == null)
				{
					HttpClient httpClient2 = (_client = new HttpClient());
				}
				started = true;
			}
		}

		public void Send(NextAudioData data)
		{
			if (started)
			{
			}
		}

		public void Stop()
		{
			_client?.Dispose();
			_client = null;
			started = false;
		}
	}
}
namespace Next_Chat.Core
{
	public class ActiveManager : InstanceClass<ActiveManager>
	{
		private readonly List<IActive> _activeList = new List<IActive>();

		public int MaxActive { get; set; } = 10;


		public void OnUpdate()
		{
			if (_activeList.Count < MaxActive)
			{
				return;
			}
			foreach (IActive item in _activeList.Where((IActive active) => !active._active).ToList())
			{
				item.Dispose();
				_activeList.Remove(item);
			}
		}

		public T? GetActive<T>(int id) where T : class, IActive
		{
			return _activeList.FirstOrDefault((IActive n) => n is T && n._Id == id) as T;
		}
	}
	public class ChatChannel
	{
		public Sprite Icon { get; }

		public List<ChatBubble> Bubbles { get; }

		public Func<PlayerControl, bool>? CanUse { get; set; }

		public ChatBubble this[Index index]
		{
			get
			{
				List<ChatBubble> bubbles = Bubbles;
				return bubbles[index.GetOffset(bubbles.Count)];
			}
		}

		public ChatBubble this[int index] => Bubbles[index];

		public ChatChannel(Sprite sprite, Func<PlayerControl, bool>? canUse = null)
		{
			Icon = sprite;
			Bubbles = new List<ChatBubble>();
			CanUse = canUse;
			base..ctor();
		}

		public static implicit operator Sprite(ChatChannel channel)
		{
			return channel.Icon;
		}
	}
	public enum ConnectionMode
	{
		Rpc,
		Server
	}
	public static class Extension
	{
		public static void AddProvider(this DefaultPlayer player, VoiceConfig config, MixingSampleProvider provider)
		{
			if (player.VolumeProvider != null)
			{
				provider.RemoveMixerInput((ISampleProvider)(object)player.VolumeProvider);
			}
			player.BufferedProvider = null;
			player._FloatProvider = null;
			player.SampleProvider = null;
			player.VolumeProvider = null;
			player.CreateProvider(config);
			provider.AddMixerInput((ISampleProvider)(object)player.VolumeProvider);
		}

		public static DefaultPlayer CreateProvider(this DefaultPlayer player, VoiceConfig config)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			player.BufferedProvider = config.BuildBufferedWaveProvider();
			player._FloatProvider = config.Build16ToFloatProvider((IWaveProvider)(object)player.BufferedProvider);
			player.SampleProvider = ((IWaveProvider)(object)player._FloatProvider).GetConverter();
			player.VolumeProvider = new VolumeSampleProvider((ISampleProvider)(object)player.SampleProvider);
			return player;
		}

		public static SampleProviderConverterBase GetConverter(this IWaveProvider provider)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Invalid comparison between Unknown and I4
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			WaveFormat waveFormat = provider.WaveFormat;
			if ((int)waveFormat.Encoding == 1)
			{
				int bitsPerSample = waveFormat.BitsPerSample;
				if (1 == 0)
				{
				}
				SampleProviderConverterBase result = (SampleProviderConverterBase)(bitsPerSample switch
				{
					8 => (object)new Pcm8BitToSampleProvider(provider), 
					16 => (object)new Pcm16BitToSampleProvider(provider), 
					24 => (object)new Pcm24BitToSampleProvider(provider), 
					32 => (object)new Pcm32BitToSampleProvider(provider), 
					_ => throw new Exception("No PCM bit SampleProviderConverterBase converter"), 
				});
				if (1 == 0)
				{
				}
				return result;
			}
			if ((int)waveFormat.Encoding != 3)
			{
				throw new Exception("provider No PCM and IEEE Float");
			}
			if (waveFormat.BitsPerSample == 64)
			{
				return (SampleProviderConverterBase)new WaveToSampleProvider64(provider);
			}
			return (SampleProviderConverterBase)new WaveToSampleProvider(provider);
		}

		public static T AddComponent<T>(this BasePlugin plugin) where T : MonoBehaviour
		{
			if (!ClassInjector.IsTypeRegisteredInIl2Cpp(typeof(T)))
			{
				ClassInjector.RegisterTypeInIl2Cpp<T>();
			}
			return plugin.AddComponent<T>().Dont<T>();
		}
	}
	public interface IActive : IDisposable
	{
		bool _active { get; set; }

		int _Id { get; set; }
	}
	public interface INetworkEndpoint
	{
		ConnectionMode Mode { get; init; }

		void Start();

		void Send(NextAudioData data);

		void Stop();
	}
	public interface INextPlayer : IDisposable
	{
		PlayerControl player { get; set; }

		PlayerStates state { get; set; }

		bool IsSpeaking { get; set; }

		bool HasInstall { get; set; }

		void AddData(NextAudioData data);

		void OnUpdate();
	}
	public class InstanceClass<T> where T : InstanceClass<T>, new()
	{
		protected static T? _Instance;

		public static T Instance => _Instance ?? (_Instance = new T());
	}
	public interface IOnUpdate
	{
	}
	public interface IOptionCreator
	{
		void CreateBoolOption(string Title, bool DefaultValue, Action<bool> Set);

		void CreateIntOption(string Title, int DefaultValue, Action<int> Set, params int[] Values);
	}
	public interface IRpcInfo
	{
		void RpcWrite(MessageWriter writer);

		void RpcRead(MessageReader reader);
	}
	public static class LogHelper
	{
		public static void LogError(string message)
		{
			Main.LogSource.LogError((object)message);
		}

		public static void LogInfo(string message)
		{
			Main.LogSource.LogInfo((object)message);
		}

		public static void LogWarning(string message)
		{
			Main.LogSource.LogWarning((object)message);
		}

		public static void LogDebug(string message)
		{
			Main.LogSource.LogDebug((object)message);
		}

		public static void LogFatal(string message)
		{
			Main.LogSource.LogFatal((object)message);
		}

		public static void LogMessage(string message)
		{
			Main.LogSource.LogMessage((object)message);
		}

		public static void LogException(Exception ex)
		{
			Main.LogSource.LogError((object)("Exception Error:\n" + ex));
		}
	}
	public class NextAudioData : IRpcInfo
	{
		public int dataId { get; set; }

		public INextPlayer Player { get; set; } = null;


		public int Length { get; set; }

		private byte[] DataBytes { get; set; } = Array.Empty<byte>();


		public NextAudioData AddFormInfo(EncodeInfo info)
		{
			OpusEncoder encoder = info.Encoder;
			byte[] data = info.Data;
			int buffedLength = info.buffedLength;
			int num = buffedLength / 4;
			byte[] array = new byte[num];
			int num2 = encoder.Encode(data, buffedLength, array, num);
			DataBytes = array.Take(num2).ToArray();
			Length = num2;
			return this;
		}

		public void Dispose()
		{
		}

		public void RpcWrite(MessageWriter writer)
		{
			writer.Write(dataId);
			writer.Write(Player.player.PlayerId);
			writer.Write(Length);
			writer.Write(Il2CppStructArray<byte>.op_Implicit(DataBytes));
		}

		public void RpcRead(MessageReader reader)
		{
			dataId = reader.ReadInt32();
			Player = InstanceClass<NextVoiceManager>.Instance.GetPlayer(reader.ReadByte());
			Length = reader.ReadInt32();
			DataBytes = Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)reader.ReadBytes(Length));
		}

		public void GetDecodeByte(OpusDecoder decoder, int buffedLength, out int length, out byte[] Data)
		{
			byte[] array = new byte[buffedLength];
			Data = array.Take(length = decoder.Decode(DataBytes, Length, array, buffedLength)).ToArray();
		}
	}
	public record EncodeInfo(int buffedLength, OpusEncoder Encoder, byte[] Data);
	public record DecodeInfo(int buffedLength, byte[] Data);
	public class PlayerIconInstance : MonoBehaviour
	{
		public SpriteRenderer? Back;

		public SpriteRenderer? Front;

		public SpriteMask? SpriteMask;

		public SortingGroup? SortingGroup;

		public Func<PlayerIconInstance, bool> IsEnable = null;

		public PlayerControl? player { get; set; }

		public PoolablePlayer? Poolable { get; set; }
	}
	public class PlayersOverlay
	{
		public readonly List<PlayerIconInstance> _AllInstance = new List<PlayerIconInstance>();

		private readonly GameObject IconHolder;

		public static PlayersOverlay? Instance { get; private set; }

		public static PlayerIconInstance? IcoPrefab { get; private set; }

		public Func<PlayerIconInstance, bool> IsEnable { get; set; }

		public static PoolablePlayer Prefab => DestroyableSingleton<HudManager>.Instance.IntroPrefab.PlayerPrefab;

		public PlayerIconInstance GetOrCreate(INextPlayer _player)
		{
			INextPlayer _player2 = _player;
			PlayerIconInstance playerIconInstance = _AllInstance.FirstOrDefault((PlayerIconInstance n) => (Object)(object)n.player == (Object)(object)_player2.player) ?? CreateIcon(_player2);
			((Component)playerIconInstance).gameObject.SetActive(true);
			return playerIconInstance;
		}

		public PlayerIconInstance CreateIcon(INextPlayer _player)
		{
			if (IcoPrefab == null)
			{
				IcoPrefab = CreatePrefab();
			}
			PlayerIconInstance playerIconInstance = _AllInstance.FirstOrDefault((PlayerIconInstance n) => n.player == null);
			if (playerIconInstance == null)
			{
				PlayerIconInstance playerIconInstance2 = Object.Instantiate<PlayerIconInstance>(IcoPrefab, IconHolder.transform, true);
				((Object)playerIconInstance2).name = "Icon:" + ((Object)_player.player).name;
				CreatePoolable(playerIconInstance2, _player.player);
				playerIconInstance2.player = _player.player;
				playerIconInstance2.IsEnable = IsEnable;
				_AllInstance.Add(playerIconInstance2);
				return playerIconInstance2;
			}
			CreatePoolable(playerIconInstance, _player.player);
			((Component)playerIconInstance).transform.SetParent(IconHolder.transform);
			((Object)((Component)playerIconInstance).gameObject).name = "Icon:" + ((Object)_player.player).name;
			playerIconInstance.IsEnable = IsEnable;
			playerIconInstance.player = _player.player;
			return playerIconInstance;
		}

		private static PlayerIconInstance CreatePrefab()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			PlayerIconInstance playerIconInstance = UnityHelper.CreateObject<PlayerIconInstance>("IconPrefab", (Transform?)null, Vector3.zero, (int?)null);
			playerIconInstance.SortingGroup = ((Component)playerIconInstance).gameObject.AddComponent<SortingGroup>();
			playerIconInstance.Back = UnityHelper.CreateObject<SpriteRenderer>("Back", ((Component)playerIconInstance).transform, new Vector3(0f, 0f, 0.1f), (int?)null);
			playerIconInstance.Back.sprite = Sprites.OverlayIcon.GetSprite(0);
			playerIconInstance.Back.color = new Color(0.45f, 0.45f, 0.45f);
			playerIconInstance.Front = UnityHelper.CreateObject<SpriteRenderer>("Front", ((Component)playerIconInstance).transform, new Vector3(0f, 0f, 0.05f), (int?)null);
			playerIconInstance.Front.sprite = Sprites.OverlayIcon.GetSprite(1);
			playerIconInstance.Front.color = new Color(0.23f, 0.23f, 0.23f);
			playerIconInstance.SpriteMask = UnityHelper.CreateObject<SpriteMask>("Mask", ((Component)playerIconInstance).transform, Vector3.zero, (int?)null);
			playerIconInstance.SpriteMask.sprite = Sprites.OverlayIcon.GetSprite(1);
			((Component)playerIconInstance).transform.localScale = new Vector3(0.4f, 0.4f, 0.4f);
			((Component)playerIconInstance).gameObject.SetActive(false);
			return playerIconInstance.DontDestroyOnLoad<PlayerIconInstance>();
		}

		public PlayersOverlay(Func<PlayerIconInstance, bool> isEnable)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			IsEnable = isEnable;
			Instance = this;
			IconHolder = UnityHelper.CreateObject("IconHolder", ((Component)DestroyableSingleton<HudManager>.Instance).transform, new Vector3(0f, 2.7f, -120f)).Dont<GameObject>();
			IconHolder.SetActive(true);
		}

		internal void OnUpdate()
		{
			//IL_00f9: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)IconHolder))
			{
				return;
			}
			if ((Object.op_Implicit((Object)(object)MeetingHud.Instance) && !Object.op_Implicit((Object)(object)ExileController.Instance)) || Object.op_Implicit((Object)(object)PlayerCustomizationMenu.Instance) || Object.op_Implicit((Object)(object)GameSettingMenu.Instance))
			{
				IconHolder.gameObject.SetActive(false);
				return;
			}
			IconHolder.gameObject.SetActive(true);
			int num = 0;
			foreach (PlayerIconInstance item in _AllInstance.Where((PlayerIconInstance i) => ((Component)i).gameObject.active))
			{
				PoolablePlayer? poolable = item.Poolable;
				if (poolable != null)
				{
					PlayerControl? player = item.player;
					poolable.UpdateFromPlayerOutfit((player != null) ? player.CurrentOutfit : null, (MaskType)2, false, false, (Action)null, false);
				}
				((Component)item).gameObject.transform.localPosition = new Vector3(0.45f * (float)num, 0f) - new Vector3(0.225f * (float)(num - 1), 0f, 0f);
				num++;
			}
		}

		public static PoolablePlayer GetPlayerIcon(PlayerOutfit? outfit, Transform? parent, Vector3 position, Vector3 scale, bool flip = false, bool includePet = true)
		{
			//IL_0030: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			PoolablePlayer val = Object.Instantiate<PoolablePlayer>(Prefab);
			if (parent != null)
			{
				((Component)val).transform.SetParent(parent);
			}
			val.SetFlipX(flip);
			((Component)val).transform.localPosition = position;
			((Component)val).transform.localScale = scale;
			val.ToggleName(false);
			val.SetNameColor(Color.white);
			if (outfit == null)
			{
				return val;
			}
			((Object)val).name = outfit.PlayerName;
			val.UpdateFromPlayerOutfit(outfit, (MaskType)0, false, includePet, (Action)null, false);
			return val;
		}

		internal static void AddSortingGroup(params GameObject[] objects)
		{
			ZOrderedSortingGroup zOrderedSortingGroup = default(ZOrderedSortingGroup);
			foreach (GameObject val in objects)
			{
				if (!val.TryGetComponent<ZOrderedSortingGroup>(ref zOrderedSortingGroup))
				{
					val.AddComponent<ZOrderedSortingGroup>();
				}
			}
		}

		public void CreatePoolable(PlayerIconInstance instance, PlayerControl _player)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			PlayerOutfit currentOutfit = _player.CurrentOutfit;
			SpriteMask? spriteMask = instance.SpriteMask;
			instance.Poolable = GetPlayerIcon(currentOutfit, (spriteMask != null) ? ((Component)spriteMask).transform : null, new Vector3(0f, -0.3f, -1f), Vector3.one);
			instance.Poolable.TogglePet(false);
			instance.Poolable.cosmetics.SetMaskType((MaskType)2);
			((Component)instance.Poolable).transform.localScale = new Vector3(0.65f, 0.65f, 0.65f);
			AddSortingGroup(((Component)instance.Poolable.cosmetics.skin.layer).gameObject, ((Component)instance.Poolable.cosmetics.hat.FrontLayer).gameObject, ((Component)instance.Poolable.cosmetics.visor.Image).gameObject, ((Component)instance.Poolable.cosmetics.currentBodySprite.BodySprite).gameObject);
		}
	}
	[Flags]
	public enum PlayerStates
	{
		Mute = 0,
		Play = 1,
		Silence = 2,
		Ban = 3
	}
	public abstract class PlayerVCInstance
	{
		public PlayerIconInstance? Icon { get; set; }

		protected abstract INextPlayer _player { get; }

		public VCFrame? Frame { get; set; }

		public void Create()
		{
			Icon = PlayersOverlay.Instance?.GetOrCreate(_player);
		}
	}
	public class ResourceLib
	{
		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private string <name>P;

		private static readonly Assembly assembly = Assembly.GetExecutingAssembly();

		private static readonly string ResourcePath = ResourceInfo.AssemblyName + ".Resource.";

		public readonly string Name;

		public ResourceLib(string name)
		{
			<name>P = name;
			Name = GetName(<name>P);
			base..ctor();
		}

		public static string GetName(string path)
		{
			string text = path;
			int num = path.IndexOf('.') + 1;
			path = text.Substring(num, text.Length - num);
			path = path.Substring(0, path.LastIndexOf('.'));
			return path;
		}

		public string GetPath()
		{
			if (assembly.GetManifestResourceNames().Contains(ResourcePath + <name>P))
			{
				return ResourcePath + <name>P;
			}
			return <name>P;
		}

		public void Write(string dir)
		{
			LogHelper.LogInfo("Write Path Form Resources: " + GetPath() + " : " + ResourcePath + <name>P);
			string text = Path.Combine(dir, Name + ".dll");
			if (File.Exists(text) && new FileInfo(text).Length != 0)
			{
				return;
			}
			using Stream input = assembly.GetManifestResourceStream(GetPath());
			File.WriteAllBytes(text, input.ReadFully());
		}
	}
	public class ResourceSprite
	{
		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private int <x>P;

		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private int <y>P;

		private static readonly Assembly assembly = Assembly.GetExecutingAssembly();

		private static readonly string ResourcePath = ResourceInfo.AssemblyName + ".Resource.";

		public readonly bool _cache;

		public readonly string _pathName;

		public float _pixel;

		private Sprite? _sprite;

		public Sprite[]? Sprites;

		public string Path => GetPath();

		public ResourceSprite(string pathName = "", float pixel = 115f, int x = 0, int y = 0, bool cache = true)
		{
			<x>P = x;
			<y>P = y;
			_cache = cache;
			_pathName = pathName;
			_pixel = pixel;
			base..ctor();
		}

		public static implicit operator Sprite(ResourceSprite rs)
		{
			return rs.GetSprite();
		}

		public Sprite GetSprite(int index)
		{
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if (<x>P == 0 && <y>P == 0)
			{
				return GetSprite();
			}
			Texture2D val = UnityHelper.loadTextureFromResources(GetPath());
			if (Sprites == null || Sprites.Length - 1 < index)
			{
				Tuple<int, int> tuple = new Tuple<int, int>(<x>P, <y>P);
				Tuple<int, int> tuple2 = new Tuple<int, int>(((Texture)val).width / tuple.Item1, ((Texture)val).height / tuple.Item2);
				Sprites = (Sprite[]?)(object)new Sprite[tuple.Item1 * tuple.Item2];
				int num = index % tuple.Item1;
				int num2 = index / tuple.Item1;
				Rect value = default(Rect);
				((Rect)(ref value))..ctor((float)(num * tuple2.Item1), (float)((tuple.Item2 - num2 - 1) * tuple2.Item2), (float)tuple2.Item1, (float)tuple2.Item2);
				Sprites[index] = UnityHelper.loadSprite(val, _pixel, value, cache: false);
			}
			return Sprites[index];
		}

		public Sprite GetSprite()
		{
			if ((Object)(object)_sprite != (Object)null && _sprite.pixelsPerUnit == _pixel)
			{
				return _sprite;
			}
			LogHelper.LogInfo("Load Path Form Resources: " + GetPath() + " : " + ResourcePath + _pathName);
			_sprite = UnityHelper.loadSpriteFromResources(GetPath(), _pixel);
			return _sprite;
		}

		private string GetPath()
		{
			if (assembly.GetManifestResourceNames().Contains(ResourcePath + _pathName))
			{
				return ResourcePath + _pathName;
			}
			return _pathName;
		}

		internal void Destroy()
		{
			((Object)(object)_sprite)?.Destroy();
			CollectionExtensions.Do<Sprite>((IEnumerable<Sprite>)Sprites, (Action<Sprite>)UnityHelper.Destroy);
		}
	}
	public enum RPCFlag : byte
	{
		SyncPlayer = 225,
		HasInstall,
		SyncConfig,
		Send
	}
	public static class UnityHelper
	{
		public static readonly List<Sprite?> CacheSprite = new List<Sprite>();

		public static IRegionInfo CurrentServer => DestroyableSingleton<ServerManager>.Instance.CurrentRegion;

		public static bool IsCustomServer => (int)CurrentServer.TranslateName == 1003 || ((int)CurrentServer.TranslateName != 291 && (int)CurrentServer.TranslateName != 290 && (int)CurrentServer.TranslateName != 289);

		public static T Dont<T>(this T obj) where T : Object
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			((Object)obj).hideFlags = (HideFlags)(((Object)obj).hideFlags | 0x3D);
			return obj;
		}

		public static T DontDestroyOnLoad<T>(this T obj) where T : Object
		{
			Object.DontDestroyOnLoad((Object)(object)obj);
			return obj;
		}

		public static Sprite? loadSpriteFromResources(string path, float pixelsPerUnit, Rect? _rect = null, bool cache = true)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string fileName = Path.GetFileName(path) + $"_{pixelsPerUnit}";
				if (cache && CacheSprite.Exists((Sprite? n) => ((n != null) ? ((Object)n).name : null) == fileName))
				{
					return ((IEnumerable<Sprite>)CacheSprite).FirstOrDefault((Func<Sprite, bool>)((Sprite n) => ((n != null) ? ((Object)n).name : null) == fileName));
				}
				Texture2D val = loadTextureFromResources(path);
				Sprite val2 = Sprite.Create(val, (Rect)(((??)_rect) ?? new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height)), new Vector2(0.5f, 0.5f), pixelsPerUnit);
				((Object)val2).name = fileName;
				if (cache)
				{
					val2.Dont<Sprite>();
					CacheSprite.Add(val2);
					return val2;
				}
				return val2;
			}
			catch
			{
				LogHelper.LogError("loading sprite from path: " + path);
			}
			return null;
		}

		public static Sprite? loadSprite(Texture2D texture, float pixelsPerUnit, Rect? _rect = null, bool cache = true)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string name = ((Object)texture).name + $"_{pixelsPerUnit}";
				Sprite val = Sprite.Create(texture, (Rect)(((??)_rect) ?? new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height)), new Vector2(0.5f, 0.5f), pixelsPerUnit);
				((Object)val).name = name;
				if (cache)
				{
					val.Dont<Sprite>();
					CacheSprite.Add(val);
					return val;
				}
				return val;
			}
			catch
			{
				LogHelper.LogError("texture: " + ((Object)texture).name);
			}
			return null;
		}

		public unsafe static Texture2D? loadTextureFromResources(string path)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			try
			{
				Texture2D val = new Texture2D(2, 2, (TextureFormat)5, true)
				{
					name = Path.GetFileName(path)
				};
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(path);
				long length = manifestResourceStream.Length;
				Il2CppStructArray<byte> val2 = new Il2CppStructArray<byte>(length);
				manifestResourceStream.Read(new Span<byte>(IntPtr.Add(((Il2CppObjectBase)val2).Pointer, IntPtr.Size * 4).ToPointer(), (int)length));
				ImageConversion.LoadImage(val, val2, false);
				return val;
			}
			catch
			{
				LogHelper.LogError("loading texture from resources: " + path);
			}
			return null;
		}

		public static Sprite LoadSprite(this Stream stream, bool DontUnload, Vector2 pivot, float pixelsPerUnit)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = stream.LoadTexture(DontUnload);
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), pivot, pixelsPerUnit);
			if (DontUnload)
			{
				val2.Dont<Sprite>();
			}
			return val2;
		}

		public static Texture2D LoadTexture(this Stream stream, bool DontUnload)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)5, true);
			byte[] array = stream.ReadFully();
			ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array), false);
			if (DontUnload)
			{
				val.Dont<Texture2D>();
			}
			return val;
		}

		public static byte[] ReadFully(this Stream? input)
		{
			using MemoryStream memoryStream = new MemoryStream();
			input?.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		public static void Destroy(this Object obj)
		{
			Object.Destroy(obj);
		}

		public static void AddListener(this UnityEvent @event, Action action)
		{
			@event.AddListener(UnityAction.op_Implicit(action));
		}

		public static void AddListener<T>(this UnityEvent<T> @event, Action<T> action)
		{
			@event.AddListener(UnityAction<T>.op_Implicit(action));
		}

		public static GameObject DestroyAllChildren<T>(this GameObject obj) where T : MonoBehaviour
		{
			Il2CppArrayBase<T> componentsInChildren = obj.GetComponentsInChildren<T>();
			CollectionExtensions.Do<T>((IEnumerable<T>)componentsInChildren, (Action<T>)Object.Destroy);
			return obj;
		}

		public static IRegionInfo CreateHttpRegion(string name, string ip, ushort port)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return ((Il2CppObjectBase)new StaticHttpRegionInfo(name, (StringNames)1003, ip, new Il2CppReferenceArray<ServerInfo>((ServerInfo[])(object)new ServerInfo[1]
			{
				new ServerInfo(name, ip, port, false)
			}), (string)null)).Cast<IRegionInfo>();
		}

		public static bool TryGet<T>(this IEnumerable<T> enumerable, Func<T, bool> predicate, [MaybeNullWhen(false)] out T item) where T : class
		{
			item = null;
			T val = enumerable.ToList().FirstOrDefault(predicate);
			return val != null;
		}

		public static GameObject CreateObject(string objName, Transform? parent, Vector3 localPosition, int? layer = null)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objName);
			val.transform.SetParent(parent);
			val.transform.localPosition = localPosition;
			val.transform.localScale = new Vector3(1f, 1f, 1f);
			if (layer.HasValue)
			{
				val.layer = layer.Value;
			}
			else if (Object.op_Implicit((Object)(object)parent))
			{
				val.layer = ((Component)parent).gameObject.layer;
			}
			return val;
		}

		public static T CreateObject<T>(string objName, Transform? parent, Vector3 localPosition, int? layer = null) where T : Component
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateObject(objName, parent, localPosition, layer);
			return val.AddComponent<T>();
		}

		public static List<T> ToSystemList<T>(this List<T> list)
		{
			List<T> list2 = new List<T>();
			Enumerator<T> enumerator = list.GetEnumerator();
			while (enumerator.MoveNext())
			{
				T current = enumerator.Current;
				list2.Add(current);
			}
			return list2;
		}

		public static IEnumerable<T> GetFastEnumerator<T>(this List<T> list) where T : Object
		{
			return new Il2CppListEnumerable<T>(list);
		}
	}
	public class Il2CppListEnumerable<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IEnumerator, IDisposable where T : Object
	{
		private struct Il2CppListStruct
		{
			private IntPtr _unusedPtr1;

			private IntPtr _unusedPtr2;

			public IntPtr _items;

			public int _size;
		}

		private static readonly int _elemSize;

		private static readonly int _offset;

		private static readonly Func<IntPtr, T> _objFactory;

		private readonly IntPtr _arrayPointer;

		private readonly int _count;

		private int _index = -1;

		object IEnumerator.Current => Current;

		public T Current { get; private set; } = default(T);


		static Il2CppListEnumerable()
		{
			_elemSize = IntPtr.Size;
			_offset = 4 * IntPtr.Size;
			ConstructorInfo constructor = typeof(T).GetConstructor(new Type[1] { typeof(IntPtr) });
			ParameterExpression parameterExpression = Expression.Parameter(typeof(IntPtr));
			NewExpression body = Expression.New(constructor, parameterExpression);
			Expression<Func<IntPtr, T>> expression = Expression.Lambda<Func<IntPtr, T>>(body, new ParameterExpression[1] { parameterExpression });
			_objFactory = expression.Compile();
		}

		public unsafe Il2CppListEnumerable(List<T> list)
		{
			Il2CppListStruct* ptr = (Il2CppListStruct*)(void*)((Il2CppObjectBase)list).Pointer;
			_count = ptr->_size;
			_arrayPointer = ptr->_items;
		}

		public unsafe bool MoveNext()
		{
			if (++_index >= _count)
			{
				return false;
			}
			IntPtr arg = *(IntPtr*)(void*)IntPtr.Add(IntPtr.Add(_arrayPointer, _offset), _index * _elemSize);
			Current = _objFactory(arg);
			return true;
		}

		public void Reset()
		{
			_index = -1;
		}

		public IEnumerator<T> GetEnumerator()
		{
			return this;
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this;
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
		}
	}
	public class VCFrame : MonoBehaviour
	{
		public SpriteRenderer? Renderer;

		public INextPlayer? Player;

		public float alpha;

		public Color col;

		public void SetPlayer(PlayerVoteArea area)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			col = Color32.op_Implicit(((Il2CppArrayBase<Color32>)(object)Palette.PlayerColors)[(int)area.TargetPlayerId]);
			if (Mathf.Max(new float[3] { col.r, col.g, col.b }) < 100f)
			{
				col = Color.Lerp(col, Color.white, 0.4f);
			}
		}

		public void Update()
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (Renderer != null && Player != null)
			{
				alpha = (Player.IsSpeaking ? Mathf.Clamp(alpha + Time.deltaTime * 4f, 0f, 1f) : Mathf.Clamp(alpha - Time.deltaTime * 4f, 0f, 1f));
				col.a = (int)(byte)(alpha * 255f);
				Renderer.color = col;
			}
		}
	}
	public class VoiceConfig : IRpcInfo
	{
		public int SampleRateInt { get; set; }

		public int FrameLengthInt { get; set; }

		public int Channels { get; set; }

		public int Bits { get; set; }

		public int BufferOfNumber { get; set; }

		public int DesiredLatency { get; set; }

		public OperatingMode OperatingMode { get; set; }

		public bool ReadFully { get; set; }

		public bool convertTo16Bit { get; set; }

		public int BuffedLength => SampleRateInt * Bits / 8 * Channels * (FrameLengthInt / 1000);

		public static implicit operator OperatingMode(VoiceConfig config)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return config.OperatingMode;
		}

		public static implicit operator FrameLength(VoiceConfig config)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return config.GetFrameLengthType();
		}

		public static implicit operator SampleRate(VoiceConfig config)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return config.GetSampleRateType();
		}

		static VoiceConfig()
		{
			RPCPatch.rpcHandlers.Add(RPCFlag.SyncConfig, delegate(MessageReader reader)
			{
				DefaultPlayer player = InstanceClass<NextVoiceManager>.Instance.GetPlayer(reader.ReadByte());
				if (player is LocalPlayer)
				{
					VoiceConfig voiceConfig = new VoiceConfig();
					voiceConfig.RpcRead(reader);
					InstanceClass<NextVoiceManager>.Instance.ChangeConfig(voiceConfig);
				}
				else
				{
					DefaultPlayer defaultPlayer = player;
					if (defaultPlayer.Config == null)
					{
						VoiceConfig voiceConfig3 = (defaultPlayer.Config = new VoiceConfig());
					}
					player.Config.RpcRead(reader);
				}
			});
		}

		public static VoiceConfig CreateDefault()
		{
			return new VoiceConfig
			{
				SampleRateInt = 48000,
				FrameLengthInt = 30,
				Channels = 2,
				Bits = 16,
				BufferOfNumber = 3,
				DesiredLatency = 300,
				OperatingMode = (OperatingMode)0,
				ReadFully = true
			};
		}

		public WaveFormat BuildFloatWaveFormat()
		{
			return WaveFormat.CreateIeeeFloatWaveFormat(SampleRateInt, Channels);
		}

		public Wave16ToFloatProvider Build16ToFloatProvider(IWaveProvider provider)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			return new Wave16ToFloatProvider(provider);
		}

		public MixingSampleProvider BuildMixingSampleProvider()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			return new MixingSampleProvider(BuildFloatWaveFormat())
			{
				ReadFully = ReadFully
			};
		}

		public BufferedWaveProvider BuildBufferedWaveProvider()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			return new BufferedWaveProvider(BuildWaveFormat())
			{
				ReadFully = ReadFully
			};
		}

		public WaveFormat BuildWaveFormat()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return new WaveFormat(SampleRateInt, Bits, Channels);
		}

		public OpusEncoder BuildEncoder()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			return new OpusEncoder((Application)2048);
		}

		public OpusDecoder BuildDecoder()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			return new OpusDecoder(SampleRateInt, Channels);
		}

		public WebRtcVad BuildVad()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			return new WebRtcVad
			{
				FrameLength = this,
				SampleRate = this,
				OperatingMode = this
			};
		}

		public WaveInEvent BuildWaveIn()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0024: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			return new WaveInEvent
			{
				WaveFormat = new WaveFormat(SampleRateInt, Bits, Channels),
				BufferMilliseconds = FrameLengthInt,
				DeviceNumber = (InstanceClass<NextVoiceManager>.Instance.CurrentMic?.Id ?? (-1)),
				NumberOfBuffers = BufferOfNumber
			};
		}

		public WasapiOut BuildWasapiOut()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			return new WasapiOut
			{
				Volume = 1f
			};
		}

		public WaveOutEvent BuildWaveOut()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//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_003e: Expected O, but got Unknown
			return new WaveOutEvent
			{
				DeviceNumber = (InstanceClass<NextVoiceManager>.Instance.CurrentSpeaker?.Id ?? (-1)),
				NumberOfBuffers = BufferOfNumber,
				DesiredLatency = DesiredLatency
			};
		}

		public FrameLength GetFrameLengthType()
		{
			//IL_0025: 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_002b: 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)
			while (true)
			{
				switch (FrameLengthInt)
				{
				case 10:
					return (FrameLength)10;
				case 20:
					return (FrameLength)20;
				case 30:
					return (FrameLength)30;
				}
				LogHelper.LogWarning("No Supped ReSet FrameLength");
				SetFrameLength(FrameLengthInt);
			}
		}

		public SampleRate GetSampleRateType()
		{
			//IL_0052: 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_007b: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			while (true)
			{
				switch (SampleRateInt)
				{
				case 8000:
					return (SampleRate)8000;
				case 16000:
					return (SampleRate)16000;
				case 32000:
					return (SampleRate)32000;
				case 48000:
					return (SampleRate)48000;
				}
				LogHelper.LogWarning("No Supped ReSet SampleRate");
				SetRate(SampleRateInt);
			}
		}

		public void SetFrameLength(int frameLength)
		{
			List<int> source = new List<int>(3) { 10, 20, 30 };
			FrameLengthInt = source.MinBy((int n) => Math.Abs(n - frameLength));
		}

		public void SetRate(int rate)
		{
			List<int> source = new List<int>(4) { 8000, 16000, 32000, 48000 };
			SampleRateInt = source.MinBy((int n) => Math.Abs(n - rate));
		}

		public void RpcWrite(MessageWriter writer)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			writer.Write(SampleRateInt);
			writer.Write(FrameLengthInt);
			writer.Write(Channels);
			writer.Write(Bits);
			writer.Write(BufferOfNumber);
			writer.Write(DesiredLatency);
			writer.Write((byte)OperatingMode);
			writer.Write(ReadFully);
			writer.Write(convertTo16Bit);
		}

		public void RpcRead(MessageReader reader)
		{
			SampleRateInt = reader.ReadInt32();
			FrameLengthInt = reader.ReadInt32();
			Channels = reader.ReadInt32();
			Bits = reader.ReadInt32();
			BufferOfNumber = reader.ReadInt32();
			DesiredLatency = reader.ReadInt32();
			OperatingMode = (OperatingMode)reader.ReadByte();
			ReadFully = reader.ReadBoolean();
			convertTo16Bit = reader.ReadBoolean();
		}
	}
	public class WaveTool : IDisposable
	{
		private WaveInEvent? _waveIn;

		private WaveOutEvent? _waveOut;

		private WasapiOut? _wasapiOut;

		private OpusEncoder? _encoder;

		private OpusDecoder? _decoder;

		private WebRtcVad? _vad;

		public VoiceConfig? Config { get; set; }

		public bool BuildInEvent { get; set; }

		public bool BuildOutEvent { get; set; }

		public bool BuildWasapiOut { get; set; }

		public bool BuildEncoder { get; set; }

		public bool BuildDecoder { get; set; }

		public bool BuildVad { get; set; }

		public WaveInEvent? WaveIn
		{
			get
			{
				if (!BuildInEvent)
				{
					return null;
				}
				return _waveIn ?? (_waveIn = Config?.BuildWaveIn());
			}
		}

		public WasapiOut? WasapiWaveOut
		{
			get
			{
				if (!BuildWasapiOut)
				{
					return null;
				}
				return _wasapiOut ?? (_wasapiOut = Config?.BuildWasapiOut());
			}
		}

		public WaveOutEvent? WaveOut
		{
			get
			{
				if (!BuildOutEvent)
				{
					return null;
				}
				return _waveOut ?? (_waveOut = Config?.BuildWaveOut());
			}
		}

		public OpusEncoder? Encoder
		{
			get
			{
				if (!BuildEncoder)
				{
					return null;
				}
				return _encoder ?? (_encoder = Config?.BuildEncoder());
			}
		}

		public OpusDecoder? Decoder
		{
			get
			{
				if (!BuildDecoder)
				{
					return null;
				}
				return _decoder ?? (_decoder = Config?.BuildDecoder());
			}
		}

		public WebRtcVad? Vad
		{
			get
			{
				if (!BuildVad)
				{
					return null;
				}
				return _vad ?? (_vad = Config?.BuildVad());
			}
		}

		public void Dispose()
		{
			Config = null;
			WaveInEvent? waveIn = _waveIn;
			if (waveIn != null)
			{
				waveIn.Dispose();
			}
			WaveOutEvent? waveOut = _waveOut;
			if (waveOut != null)
			{
				waveOut.Dispose();
			}
			OpusEncoder? encoder = _encoder;
			if (encoder != null)
			{
				encoder.Dispose();
			}
			OpusDecoder? decoder = _decoder;
			if (decoder != null)
			{
				decoder.Dispose();
			}
			WebRtcVad? vad = _vad;
			if (vad != null)
			{
				vad.Dispose();
			}
		}

		public static WaveTool BuildFormConfig(VoiceConfig config, bool buildInEvent = true, bool buildWasapiOut = false, bool buildOutEvent = false, bool buildEncoder = true, bool buildDecoder = true, bool buildVad = true)
		{
			return new WaveTool
			{
				Config = config,
				BuildInEvent = buildInEvent,
				BuildOutEvent = buildOutEvent,
				BuildEncoder = buildEncoder,
				BuildDecoder = buildDecoder,
				BuildVad = buildVad,
				BuildWasapiOut = buildWasapiOut
			};
		}

		public WaveTool ReBuild(VoiceConfig? config = null, bool buildInEvent = false, bool buildOutEvent = false, bool buildEncoder = false, bool buildDecoder = false, bool buildVad = false)
		{
			if (config != null)
			{
				Config = config;
			}
			BuildInEvent = buildInEvent;
			BuildOutEvent = buildOutEvent;
			BuildEncoder = buildEncoder;
			BuildDecoder = buildDecoder;
			BuildVad = buildVad;
			return this;
		}

		public WaveTool Check()
		{
			if (BuildInEvent && _waveIn == null)
			{
				_waveIn = Config?.BuildWaveIn();
			}
			if (BuildOutEvent && _waveOut == null)
			{
				_waveOut = Config?.BuildWaveOut();
			}
			if (BuildVad && _vad == null)
			{
				_vad = Config?.BuildVad();
			}
			if (BuildEncoder && _encoder == null)
			{
				_encoder = Config?.BuildEncoder();
			}
			if (BuildDecoder && _decoder == null)
			{
				_decoder = Config?.BuildDecoder();
			}
			if (!BuildDecoder && _decoder != null)
			{
				_decoder.Dispose();
				_decoder = null;
			}
			if (!BuildEncoder && _encoder != null)
			{
				_encoder.Dispose();
				_encoder = null;
			}
			if (!BuildVad && _vad != null)
			{
				_vad.Dispose();
				_vad = null;
			}
			if (!BuildInEvent && _waveIn != null)
			{
				_waveIn.Dispose();
				_waveIn = null;
			}
			if (!BuildOutEvent && _waveOut != null)
			{
				_waveOut.Dispose();
				_waveOut = null;
			}
			return this;
		}
	}
	public class ZOrderedSortingGroup : MonoBehaviour
	{
		private SortingGroup? group;

		private Renderer? renderer;

		public int ConsiderParents;

		private const float rate = 20000f;

		private const int baseValue = 5;

		public void SetConsiderParentsTo(Transform parent)
		{
			int num = 0;
			Transform val = ((Component)this).transform;
			while (!((Object)(object)val == (Object)(object)parent) && !((Object)(object)val == (Object)null))
			{
				num++;
				val = val.parent;
			}
			ConsiderParents = num;
		}

		public void Start()
		{
			if (!((Component)this).gameObject.TryGetComponent<Renderer>(ref renderer))
			{
				group = ((Component)this).gameObject.AddComponent<SortingGroup>();
			}
		}

		public void Update()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Component)this).transform.localPosition.z;
			Transform val = ((Component)this).transform;
			for (int i = 0; i < ConsiderParents; i++)
			{
				val = val.parent;
				num += val.localPosition.z;
			}
			int sortingOrder = 5 - (int)(20000f * num);
			if (group != null)
			{
				group.sortingOrder = sortingOrder;
			}
			if (renderer != null)
			{
				renderer.sortingOrder = sortingOrder;
			}
		}
	}
}