Decompiled source of All City Network v0.4.1

BombRushMP.BunchOfEmotes.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx.Bootstrap;
using BombRushMP.Common;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BombRushMP.BunchOfEmotes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BombRushMP.BunchOfEmotes")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2ce33301-b400-41be-9513-ff280c53a5a1")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BombRushMP.BunchOfEmotes
{
	public static class BunchOfEmotesSupport
	{
		private static object BoEPluginInstance = null;

		private static Type BoEPluginType = null;

		private static FieldInfo CustomAnimsField = null;

		private static bool Cached = false;

		private static Dictionary<int, int> GameAnimationByCustomAnimationHash = new Dictionary<int, int>();

		private static Dictionary<int, int> CustomAnimationHashByGameAnimation = new Dictionary<int, int>();

		public static bool Installed { get; private set; } = false;


		public static void Initialize()
		{
			Installed = true;
			BoEPluginInstance = Chainloader.PluginInfos["com.Dragsun.BunchOfEmotes"].Instance;
			BoEPluginType = ReflectionUtility.GetTypeByName("BunchOfEmotes.BunchOfEmotesPlugin");
			CustomAnimsField = BoEPluginType.GetField("myCustomAnims2");
		}

		public static void CacheAnimationsIfNecessary()
		{
			if (Cached)
			{
				return;
			}
			Cached = true;
			foreach (KeyValuePair<int, string> item in CustomAnimsField.GetValue(BoEPluginInstance) as Dictionary<int, string>)
			{
				int key = item.Key;
				int num = Compression.HashString(item.Value);
				GameAnimationByCustomAnimationHash[num] = key;
				CustomAnimationHashByGameAnimation[key] = num;
			}
		}

		public static bool TryGetGameAnimationForCustomAnimationHash(int hash, out int gameAnim)
		{
			if (!Installed)
			{
				gameAnim = 0;
				return false;
			}
			CacheAnimationsIfNecessary();
			if (GameAnimationByCustomAnimationHash.TryGetValue(hash, out gameAnim))
			{
				return true;
			}
			return false;
		}

		public static bool TryGetCustomAnimationHashByGameAnimation(int gameAnim, out int hash)
		{
			if (!Installed)
			{
				hash = 0;
				return false;
			}
			CacheAnimationsIfNecessary();
			if (CustomAnimationHashByGameAnimation.TryGetValue(gameAnim, out hash))
			{
				return true;
			}
			return false;
		}
	}
}

BombRushMP.Common.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using BombRushMP.Common.Networking;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BombRushMP.Common
{
	public class AuthUser
	{
		[JsonProperty("Description")]
		private string _description = "";

		[JsonProperty("UserKind")]
		private string _userKind = UserKinds.Player.ToString();

		public string[] Tags = Array.Empty<string>();

		public int[] Badges = Array.Empty<int>();

		[JsonIgnore]
		public bool CanLurk
		{
			get
			{
				if (!IsModerator)
				{
					return HasTag("elite");
				}
				return true;
			}
		}

		[JsonIgnore]
		public bool IsAdmin => UserKind == UserKinds.Admin;

		[JsonIgnore]
		public bool IsModerator
		{
			get
			{
				if (UserKind != UserKinds.Mod)
				{
					return UserKind == UserKinds.Admin;
				}
				return true;
			}
		}

		[JsonIgnore]
		public UserKinds UserKind
		{
			get
			{
				if (Enum.TryParse<UserKinds>(_userKind, out var result))
				{
					return result;
				}
				return UserKinds.Player;
			}
			set
			{
				_userKind = value.ToString();
			}
		}

		public AuthUser(UserKinds userKind = UserKinds.Player, string[] tags = null, int[] badges = null, string description = "")
		{
			UserKind = userKind;
			Tags = tags;
			if (Tags == null)
			{
				Tags = Array.Empty<string>();
			}
			Badges = badges;
			if (Badges == null)
			{
				Badges = Array.Empty<int>();
			}
			_description = description;
		}

		public AuthUser()
		{
		}

		public bool HasTag(string tag)
		{
			return Tags.Contains(tag);
		}

		public void Write(BinaryWriter writer)
		{
			writer.Write((int)UserKind);
			writer.Write(Tags.Length);
			string[] tags = Tags;
			foreach (string value in tags)
			{
				writer.Write(value);
			}
			writer.Write(Badges.Length);
			int[] badges = Badges;
			foreach (int value2 in badges)
			{
				writer.Write(value2);
			}
		}

		public void Read(BinaryReader reader)
		{
			UserKind = (UserKinds)reader.ReadInt32();
			int num = reader.ReadInt32();
			Tags = new string[num];
			for (int i = 0; i < num; i++)
			{
				Tags[i] = reader.ReadString();
			}
			int num2 = reader.ReadInt32();
			Badges = new int[num2];
			for (int j = 0; j < num2; j++)
			{
				Badges[j] = reader.ReadInt32();
			}
		}
	}
	public struct Bitfield
	{
		private bool[] _values;

		public bool this[Enum key]
		{
			get
			{
				return GetValue(key);
			}
			set
			{
				SetValue(key, value);
			}
		}

		public Bitfield(Enum size)
		{
			_values = Array.Empty<bool>();
			_values = new bool[Convert.ToInt32(size)];
		}

		public Bitfield(int size)
		{
			_values = Array.Empty<bool>();
			_values = new bool[size];
		}

		public static Bitfield ReadByte(BinaryReader reader)
		{
			byte b = reader.ReadByte();
			int num = 8;
			Bitfield result = new Bitfield(num);
			for (int i = 0; i < num; i++)
			{
				byte b2 = (byte)(1 << i);
				result._values[i] = (b & b2) != 0;
			}
			return result;
		}

		public static Bitfield ReadShort(BinaryReader reader)
		{
			short num = reader.ReadInt16();
			int num2 = 16;
			Bitfield result = new Bitfield(num2);
			for (int i = 0; i < num2; i++)
			{
				short num3 = (short)(1 << i);
				result._values[i] = (num & num3) != 0;
			}
			return result;
		}

		public static Bitfield ReadInteger(BinaryReader reader)
		{
			int num = reader.ReadInt32();
			int num2 = 32;
			Bitfield result = new Bitfield(num2);
			for (int i = 0; i < num2; i++)
			{
				int num3 = 1 << i;
				result._values[i] = (num & num3) != 0;
			}
			return result;
		}

		public void WriteByte(BinaryWriter writer)
		{
			byte b = 0;
			for (int i = 0; i < _values.Length; i++)
			{
				if (_values[i])
				{
					b |= (byte)(1 << i);
				}
			}
			writer.Write(b);
		}

		public void WriteShort(BinaryWriter writer)
		{
			short num = 0;
			for (int i = 0; i < _values.Length; i++)
			{
				if (_values[i])
				{
					num |= (short)(1 << i);
				}
			}
			writer.Write(num);
		}

		public void WriteInteger(BinaryWriter writer)
		{
			int num = 0;
			for (int i = 0; i < _values.Length; i++)
			{
				if (_values[i])
				{
					num |= 1 << i;
				}
			}
			writer.Write(num);
		}

		public bool GetValue(Enum index)
		{
			return _values[Convert.ToInt32(index)];
		}

		public void SetValue(Enum index, bool value)
		{
			_values[Convert.ToInt32(index)] = value;
		}
	}
	public enum CharacterNames
	{
		Vinyl,
		Frank,
		Coil,
		Red,
		Tryce,
		Bel,
		Rave,
		DotExeMember,
		Solace,
		DjCyber,
		EclipseMember,
		DevilTheoryMember,
		FauxWithBoostPack,
		FleshPrince,
		Irene,
		Felix,
		OldHeadMember,
		Base,
		Jet,
		Mesh,
		FuturismMember,
		Rise,
		Shine,
		FauxWithoutBoostPack,
		DotExeBoss,
		FelixWithCyberHead
	}
	public enum ChatMessageTypes
	{
		Chat,
		PlayerJoinedOrLeft,
		System,
		PlayerAFK,
		ClearChat
	}
	public static class CommandUtility
	{
		public static string[] ParseArgs(string command, int argNumber)
		{
			string text = command.Split(new char[1] { ' ' })[0];
			string text2 = command.Substring(text.Length).Trim();
			string[] array = new string[argNumber];
			for (int i = 0; i < argNumber; i++)
			{
				array[i] = "";
			}
			bool flag = false;
			bool flag2 = false;
			int num = 0;
			string text3 = "";
			for (int j = 0; j < text2.Length; j++)
			{
				char c = text2[j];
				if (flag2)
				{
					text3 += c;
					flag2 = false;
					continue;
				}
				switch (c)
				{
				case ' ':
					if (num == argNumber - 1)
					{
						text3 += c;
					}
					else if (!flag)
					{
						if (!string.IsNullOrWhiteSpace(text3))
						{
							array[num] = text3.Trim();
							text3 = "";
							num++;
						}
					}
					else
					{
						text3 += c;
					}
					break;
				case '"':
					if (flag)
					{
						if (!string.IsNullOrWhiteSpace(text3))
						{
							array[num] = text3;
							text3 = "";
							num++;
							flag = false;
						}
					}
					else
					{
						flag = true;
					}
					break;
				case '\\':
					flag2 = true;
					break;
				default:
					text3 += c;
					break;
				}
			}
			if (!string.IsNullOrWhiteSpace(text3) && num < argNumber)
			{
				array[num] = text3.Trim();
			}
			return array;
		}
	}
	public static class Compression
	{
		private static MD5 Hasher = MD5.Create();

		public static int HashString(string s)
		{
			return BitConverter.ToInt32(Hasher.ComputeHash(Encoding.UTF8.GetBytes(s)), 0);
		}

		public static sbyte CompressToByte(float value, float maxValue)
		{
			return CompressNormal(value / maxValue);
		}

		public static float DecompressFromByte(sbyte compressedValue, float maxValue)
		{
			return DecompressNormal(compressedValue) * maxValue;
		}

		public static sbyte CompressNormal(float normalValue)
		{
			return (sbyte)(normalValue * 127f);
		}

		public static float DecompressNormal(sbyte compressedValue)
		{
			return (float)compressedValue / 127f;
		}

		public static void WriteCompressedQuaternion(Quaternion quat, BinaryWriter writer)
		{
			writer.Write(CompressNormal(quat.X));
			writer.Write(CompressNormal(quat.Y));
			writer.Write(CompressNormal(quat.Z));
			writer.Write(CompressNormal(quat.W));
		}

		public static Quaternion ReadCompressedQuaternion(BinaryReader reader)
		{
			float x = DecompressNormal(reader.ReadSByte());
			float y = DecompressNormal(reader.ReadSByte());
			float z = DecompressNormal(reader.ReadSByte());
			float w = DecompressNormal(reader.ReadSByte());
			return new Quaternion(x, y, z, w);
		}

		public static void WriteCompressedVector3Normal(Vector3 vec, BinaryWriter writer)
		{
			writer.Write(CompressNormal(vec.X));
			writer.Write(CompressNormal(vec.Y));
			writer.Write(CompressNormal(vec.Z));
		}

		public static Vector3 ReadCompressedVector3Normal(BinaryReader reader)
		{
			float x = DecompressNormal(reader.ReadSByte());
			float y = DecompressNormal(reader.ReadSByte());
			float z = DecompressNormal(reader.ReadSByte());
			return new Vector3(x, y, z);
		}
	}
	public static class Constants
	{
		public const uint ProtocolVersion = 17u;

		public const float DefaultNetworkingTickRate = 1f / 32f;

		public const float ScoreBattleDuration = 180f;

		public const int MaxPayloadSize = 10000;

		public const char CommandChar = '/';

		public const int MaxMessageLength = 256;

		public const int MaxNameLength = 64;

		public const int MaxCrewNameLength = 32;
	}
	public enum GamemodeIDs
	{
		ScoreBattle,
		GraffitiRace,
		TeamGraffitiRace,
		ProSkaterScoreBattle,
		TeamScoreBattle,
		TeamProSkaterScoreBattle
	}
	public enum GenericEvents
	{
		Spray,
		Teleport,
		GraffitiGameOver,
		Death,
		Land
	}
	public static class ListExtensions
	{
		private static Random rng = new Random();

		public static void Shuffle<T>(this IList<T> list)
		{
			int num = list.Count;
			while (num > 1)
			{
				num--;
				int index = rng.Next(num + 1);
				T value = list[index];
				list[index] = list[num];
				list[num] = value;
			}
		}
	}
	public class LobbyPlayer
	{
		public uint LobbyId;

		public ushort Id;

		public float Score;

		public bool Ready;

		public byte Team;

		public LobbyPlayer()
		{
		}

		public LobbyPlayer(uint lobbyId, ushort playerId, byte team)
		{
			LobbyId = lobbyId;
			Id = playerId;
			Team = team;
		}

		public void Write(BinaryWriter writer)
		{
			writer.Write(Id);
			writer.Write(Score);
			writer.Write(Ready);
			writer.Write(Team);
		}

		public void Read(BinaryReader reader)
		{
			Id = reader.ReadUInt16();
			Score = reader.ReadSingle();
			Ready = reader.ReadBoolean();
			Team = reader.ReadByte();
		}
	}
	public class LobbyState
	{
		private enum BooleanMask
		{
			InGame,
			AllowTeamSwitching,
			Challenge,
			MAX
		}

		public bool InGame;

		public bool AllowTeamSwitching = true;

		public bool Challenge;

		public GamemodeIDs Gamemode;

		public byte[] GamemodeSettings = Array.Empty<byte>();

		public int Stage;

		public uint Id;

		public ushort HostId;

		public Dictionary<ushort, LobbyPlayer> Players = new Dictionary<ushort, LobbyPlayer>();

		public Dictionary<ushort, DateTime> InvitedPlayers = new Dictionary<ushort, DateTime>();

		public LobbyState()
		{
		}

		public LobbyState(int stage, uint id, ushort hostId)
		{
			Stage = stage;
			Id = id;
			HostId = hostId;
		}

		public float GetScoreForTeam(byte team)
		{
			float num = 0f;
			foreach (KeyValuePair<ushort, LobbyPlayer> player in Players)
			{
				if (player.Value.Team == team)
				{
					num += player.Value.Score;
				}
			}
			return num;
		}

		public void Read(BinaryReader reader)
		{
			Bitfield bitfield = Bitfield.ReadByte(reader);
			InGame = bitfield[BooleanMask.InGame];
			AllowTeamSwitching = bitfield[BooleanMask.AllowTeamSwitching];
			Challenge = bitfield[BooleanMask.Challenge];
			Gamemode = (GamemodeIDs)reader.ReadInt32();
			int count = reader.ReadInt32();
			GamemodeSettings = reader.ReadBytes(count);
			Stage = reader.ReadInt32();
			Id = reader.ReadUInt32();
			HostId = reader.ReadUInt16();
			Players.Clear();
			int num = reader.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				LobbyPlayer lobbyPlayer = new LobbyPlayer();
				lobbyPlayer.Read(reader);
				lobbyPlayer.LobbyId = Id;
				Players[lobbyPlayer.Id] = lobbyPlayer;
			}
			InvitedPlayers.Clear();
			int num2 = reader.ReadInt32();
			for (int j = 0; j < num2; j++)
			{
				DateTime value = DateTime.FromBinary(reader.ReadInt64());
				ushort key = reader.ReadUInt16();
				InvitedPlayers[key] = value;
			}
		}

		public void Write(BinaryWriter writer)
		{
			Bitfield bitfield = new Bitfield(BooleanMask.MAX);
			bitfield[BooleanMask.InGame] = InGame;
			bitfield[BooleanMask.AllowTeamSwitching] = AllowTeamSwitching;
			bitfield[BooleanMask.Challenge] = Challenge;
			bitfield.WriteByte(writer);
			writer.Write((int)Gamemode);
			writer.Write(GamemodeSettings.Length);
			writer.Write(GamemodeSettings);
			writer.Write(Stage);
			writer.Write(Id);
			writer.Write(HostId);
			writer.Write(Players.Count);
			foreach (KeyValuePair<ushort, LobbyPlayer> player in Players)
			{
				player.Value.Write(writer);
			}
			writer.Write(InvitedPlayers.Count);
			foreach (KeyValuePair<ushort, DateTime> invitedPlayer in InvitedPlayers)
			{
				writer.Write(invitedPlayer.Value.ToBinary());
				writer.Write(invitedPlayer.Key);
			}
		}
	}
	public class MPStage
	{
		public string DisplayName;

		public int Id;

		public MPStage(string displayName, int id)
		{
			DisplayName = displayName;
			Id = id;
		}
	}
	public enum PlayerStates : byte
	{
		Normal,
		Graffiti,
		Toilet,
		Dead
	}
	public static class ReflectionUtility
	{
		public static Type GetTypeByName(string name)
		{
			foreach (Assembly item in AppDomain.CurrentDomain.GetAssemblies().Reverse())
			{
				Type type = item.GetType(name);
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}
	}
	public class ServerState
	{
		public HashSet<string> Tags = new HashSet<string>();

		public void Read(BinaryReader reader)
		{
			int num = reader.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				Tags.Add(reader.ReadString());
			}
		}

		public void Write(BinaryWriter writer)
		{
			writer.Write(Tags.Count);
			foreach (string tag in Tags)
			{
				writer.Write(tag);
			}
		}
	}
	public static class SpecialPlayerUtils
	{
		public const string SpecialPlayerName = "Freesoul Elite";

		public const string SpecialPlayerCrewName = "Freesoul";

		public const SpecialSkins SpecialPlayerSkin = SpecialSkins.SpecialPlayer;

		public const string SpecialPlayerTag = "elite";

		public const string SpecialPlayerUnlockName = "Goonie";

		public const string SpecialPlayerUnlockID = "goonieskateboard";

		public const string SpecialPlayerUnlockNotification = "<color=yellow>You've unlocked the Goonie skateboard skin for beating a Freesoul Elite!</color>";

		public const string SpecialPlayerNag = "<color=yellow>Beat a Freesoul Elite in any gamemode to unlock a skateboard skin.</color>";

		public const string SpecialPlayerJoinMessage = "<color=yellow>A {0} has entered the stage!</color>";

		public const string SpecialPlayerLeaveMessage = "<color=yellow>A {0} has left!</color>";

		public const string SpecialPlayerInviteMessage = "<color=yellow>A {0} is challenging you to a {1}.</color>";
	}
	public enum SpecialSkins
	{
		None = -1,
		FemaleCop,
		MaleCop,
		SpecialPlayer,
		SeanKingston,
		Forklift
	}
	public static class TMPFilter
	{
		public class Criteria
		{
			public enum Kinds
			{
				Whitelist,
				Blacklist
			}

			public Kinds ListKind;

			public string[] List;

			public Criteria(string[] list, Kinds listKind)
			{
				List = list;
				ListKind = listKind;
			}

			internal bool CheckTag(string tag)
			{
				if (List.Contains(tag.ToLowerInvariant()))
				{
					return ListKind == Kinds.Whitelist;
				}
				return ListKind == Kinds.Blacklist;
			}
		}

		public static string[] EnclosingTags = new string[30]
		{
			"align", "allcaps", "b", "color", "cspace", "font", "font-weight", "gradient", "i", "indent",
			"line-height", "link", "lowercase", "margin", "mark", "mspace", "nobr", "noparse", "pos", "rotate",
			"s", "size", "smallcaps", "style", "sub", "sup", "u", "uppercase", "voffset", "width"
		};

		public static bool IsValidChatMessage(string message)
		{
			message = Sanitize(message);
			message = RemoveAllTags(message);
			if (string.IsNullOrWhiteSpace(message))
			{
				return false;
			}
			return true;
		}

		public static string RemoveAllTags(string text)
		{
			text = new Regex("<[^>]*>").Replace(text, string.Empty);
			return text;
		}

		public static string EscapeAllTags(string text)
		{
			return FilterTags(text, new Criteria(Array.Empty<string>(), Criteria.Kinds.Whitelist));
		}

		public static string FilterTags(string text, Criteria criteria)
		{
			bool flag = false;
			int num = 0;
			string text2 = "";
			StringBuilder stringBuilder = new StringBuilder(text);
			int num2 = 0;
			for (int i = 0; i < text.Length; i++)
			{
				char c = text[i];
				if (!flag)
				{
					if (c == '<')
					{
						flag = true;
						text2 = "";
						num = i;
					}
				}
				else if (c == '>')
				{
					flag = false;
					if (text2[0] == '/')
					{
						text2 = text2.Substring(1);
					}
					if (text2[0] == '#')
					{
						text2 = "color";
					}
					text2 = text2.ToLowerInvariant();
					if (text2.Contains("="))
					{
						text2 = text2.Split(new char[1] { '=' })[0];
					}
					if (!criteria.CheckTag(text2))
					{
						stringBuilder.Insert(num + 1 + num2, "\u200b");
						num2++;
					}
				}
				else
				{
					text2 += c;
				}
			}
			return stringBuilder.ToString();
		}

		public static string Sanitize(string text)
		{
			text = text.Replace("\n", "");
			text = text.Replace("\t", "");
			text = text.Replace("\r", "");
			return text;
		}

		public static string CloseAllTags(string text)
		{
			bool flag = false;
			string text2 = "";
			List<string> list = new List<string>();
			string text3 = text;
			for (int i = 0; i < text3.Length; i++)
			{
				char c = text3[i];
				if (!flag)
				{
					if (c == '<')
					{
						flag = true;
						text2 = "";
					}
				}
				else if (c == '>')
				{
					flag = false;
					if (text2[0] == '/')
					{
						if (list.Count > 0)
						{
							text2 = text2.Substring(1);
							if (text2 == list[0])
							{
								list.RemoveAt(0);
							}
						}
						continue;
					}
					if (text2[0] == '#')
					{
						text2 = "color";
					}
					text2 = text2.ToLowerInvariant();
					if (text2.Contains("="))
					{
						text2 = text2.Split(new char[1] { '=' })[0];
					}
					if (EnclosingTags.Contains(text2))
					{
						list.Insert(0, text2);
					}
				}
				else
				{
					text2 += c;
				}
			}
			string text4 = "";
			foreach (string item in list)
			{
				text4 = text4 + "</" + item + ">";
			}
			text += text4;
			return text;
		}
	}
	public class UIDProvider
	{
		private uint _currentUID = 1u;

		private HashSet<uint> _usedUIDs = new HashSet<uint>();

		public uint RequestUID()
		{
			while (_usedUIDs.Contains(_currentUID))
			{
				if (_currentUID < uint.MaxValue)
				{
					_currentUID++;
				}
				else
				{
					_currentUID = 1u;
				}
			}
			_usedUIDs.Add(_currentUID);
			return _currentUID++;
		}

		public void FreeUID(uint uid)
		{
			_usedUIDs.Remove(uid);
		}
	}
	public enum UserKinds
	{
		Player,
		Mod,
		Admin
	}
}
namespace BombRushMP.Common.Packets
{
	public class ClientAuth : Packet
	{
		public string AuthKey = "";

		public bool Invisible;

		public ClientState State;

		public override Packets PacketId => Packets.ClientAuth;

		public ClientAuth()
		{
		}

		public ClientAuth(string authKey, ClientState state)
		{
			AuthKey = authKey;
			State = state;
		}

		public override void Read(BinaryReader reader)
		{
			if (reader.ReadUInt32() != 17)
			{
				throw new IncompatibleProtocolException();
			}
			AuthKey = reader.ReadString();
			Invisible = reader.ReadBoolean();
			State = new ClientState();
			State.Read(reader);
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(17u);
			writer.Write(AuthKey);
			writer.Write(Invisible);
			State.Write(writer);
		}
	}
	public class ClientChat : Packet
	{
		public string Message = "";

		public override Packets PacketId => Packets.ClientChat;

		public ClientChat()
		{
		}

		public ClientChat(string message)
		{
			Message = message;
		}

		public override void Read(BinaryReader reader)
		{
			Message = reader.ReadString();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Message);
		}
	}
	public class ClientComboOver : Packet
	{
		public float Score;

		public override Packets PacketId => Packets.ClientComboOver;

		public ClientComboOver()
		{
		}

		public ClientComboOver(float score)
		{
			Score = score;
		}

		public override void Read(BinaryReader reader)
		{
			Score = reader.ReadSingle();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Score);
		}
	}
	public class ClientGamemodeCountdown : Packet
	{
		public ushort CountdownSeconds = 3;

		public override Packets PacketId => Packets.ClientGamemodeCountdown;

		public ClientGamemodeCountdown()
		{
		}

		public ClientGamemodeCountdown(ushort seconds)
		{
			CountdownSeconds = seconds;
		}

		public override void Read(BinaryReader reader)
		{
			CountdownSeconds = reader.ReadUInt16();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(CountdownSeconds);
		}
	}
	public class ClientGamemodeScore : Packet
	{
		public float Score;

		public override Packets PacketId => Packets.ClientGameModeScore;

		public ClientGamemodeScore()
		{
		}

		public ClientGamemodeScore(float score)
		{
			Score = score;
		}

		public override void Read(BinaryReader reader)
		{
			Score = reader.ReadSingle();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Score);
		}
	}
	public class ClientGraffitiRaceGSpots : Packet
	{
		public const int MaxGraffitiSpotsPerPacket = 10;

		public List<int> GraffitiSpots = new List<int>();

		public bool FinalPacket = true;

		public override Packets PacketId => Packets.ClientGraffitiRaceGSpots;

		public ClientGraffitiRaceGSpots()
		{
		}

		public ClientGraffitiRaceGSpots(List<int> graffitiSpots, bool final)
		{
			GraffitiSpots = graffitiSpots;
			FinalPacket = final;
		}

		public override void Read(BinaryReader reader)
		{
			FinalPacket = reader.ReadBoolean();
			ushort num = reader.ReadUInt16();
			for (int i = 0; i < num; i++)
			{
				int item = reader.ReadInt32();
				GraffitiSpots.Add(item);
			}
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(FinalPacket);
			writer.Write((short)GraffitiSpots.Count);
			foreach (int graffitiSpot in GraffitiSpots)
			{
				writer.Write(graffitiSpot);
			}
		}
	}
	public class ClientGraffitiRaceStart : Packet
	{
		public Vector3 SpawnPosition = Vector3.Zero;

		public Quaternion SpawnRotation = Quaternion.Identity;

		public override Packets PacketId => Packets.ClientGraffitiRaceStart;

		public ClientGraffitiRaceStart(Vector3 position, Quaternion rotation)
		{
			SpawnPosition = position;
			SpawnRotation = rotation;
		}

		public ClientGraffitiRaceStart()
		{
		}

		public override void Read(BinaryReader reader)
		{
			float x = reader.ReadSingle();
			float y = reader.ReadSingle();
			float z = reader.ReadSingle();
			SpawnPosition = new Vector3(x, y, z);
			SpawnRotation = Quaternion.Normalize(Compression.ReadCompressedQuaternion(reader));
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(SpawnPosition.X);
			writer.Write(SpawnPosition.Y);
			writer.Write(SpawnPosition.Z);
			Compression.WriteCompressedQuaternion(SpawnRotation, writer);
		}
	}
	public class ClientHitByPlayer : PlayerPacket
	{
		public ushort Attacker;

		public override Packets PacketId => Packets.ClientHitByPlayer;

		public ClientHitByPlayer()
		{
		}

		public ClientHitByPlayer(ushort attacker)
		{
			Attacker = attacker;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Attacker);
		}

		public override void Read(BinaryReader reader)
		{
			Attacker = reader.ReadUInt16();
		}
	}
	public class ClientLobbyCreate : Packet
	{
		public GamemodeIDs GamemodeID;

		public byte[] Settings;

		public override Packets PacketId => Packets.ClientLobbyCreate;

		public ClientLobbyCreate()
		{
		}

		public ClientLobbyCreate(GamemodeIDs gamemode, byte[] settings)
		{
			GamemodeID = gamemode;
			Settings = settings;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write((int)GamemodeID);
			writer.Write(Settings.Length);
			writer.Write(Settings);
		}

		public override void Read(BinaryReader reader)
		{
			GamemodeID = (GamemodeIDs)reader.ReadInt32();
			int count = reader.ReadInt32();
			Settings = reader.ReadBytes(count);
		}
	}
	public class ClientLobbyDeclineAllInvites : Packet
	{
		public override Packets PacketId => Packets.ClientLobbyDeclineAllInvites;
	}
	public class ClientLobbyDeclineInvite : Packet
	{
		public uint LobbyId;

		public override Packets PacketId => Packets.ClientLobbyDeclineInvite;

		public ClientLobbyDeclineInvite()
		{
		}

		public ClientLobbyDeclineInvite(uint lobbyId)
		{
			LobbyId = lobbyId;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(LobbyId);
		}

		public override void Read(BinaryReader reader)
		{
			LobbyId = reader.ReadUInt32();
		}
	}
	public class ClientLobbyEnd : Packet
	{
		public override Packets PacketId => Packets.ClientLobbyEnd;
	}
	public class ClientLobbyInvite : Packet
	{
		public ushort InviteeId;

		public override Packets PacketId => Packets.ClientLobbyInvite;

		public ClientLobbyInvite()
		{
		}

		public ClientLobbyInvite(ushort inviteeId)
		{
			InviteeId = inviteeId;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(InviteeId);
		}

		public override void Read(BinaryReader reader)
		{
			InviteeId = reader.ReadUInt16();
		}
	}
	public class ClientLobbyJoin : Packet
	{
		public uint LobbyId;

		public override Packets PacketId => Packets.ClientLobbyJoin;

		public ClientLobbyJoin()
		{
		}

		public ClientLobbyJoin(uint lobbyId)
		{
			LobbyId = lobbyId;
		}

		public override void Read(BinaryReader reader)
		{
			LobbyId = reader.ReadUInt32();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(LobbyId);
		}
	}
	public class ClientLobbyKick : Packet
	{
		public ushort PlayerId;

		public override Packets PacketId => Packets.ClientLobbyKick;

		public ClientLobbyKick()
		{
		}

		public ClientLobbyKick(ushort playerId)
		{
			PlayerId = playerId;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(PlayerId);
		}

		public override void Read(BinaryReader reader)
		{
			PlayerId = reader.ReadUInt16();
		}
	}
	public class ClientLobbyLeave : Packet
	{
		public override Packets PacketId => Packets.ClientLobbyLeave;
	}
	public class ClientLobbySetAllowTeamSwitching : Packet
	{
		public bool Set = true;

		public override Packets PacketId => Packets.ClientLobbySetAllowTeamSwitching;

		public ClientLobbySetAllowTeamSwitching()
		{
		}

		public ClientLobbySetAllowTeamSwitching(bool set)
		{
			Set = set;
		}

		public override void Read(BinaryReader reader)
		{
			Set = reader.ReadBoolean();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Set);
		}
	}
	public class ClientLobbySetChallenge : Packet
	{
		public bool Set = true;

		public override Packets PacketId => Packets.ClientLobbySetChallenge;

		public ClientLobbySetChallenge()
		{
		}

		public ClientLobbySetChallenge(bool set)
		{
			Set = set;
		}

		public override void Read(BinaryReader reader)
		{
			Set = reader.ReadBoolean();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Set);
		}
	}
	public class ClientLobbySetGamemode : Packet
	{
		public GamemodeIDs Gamemode;

		public byte[] GamemodeSettings = Array.Empty<byte>();

		public override Packets PacketId => Packets.ClientLobbySetGamemode;

		public ClientLobbySetGamemode()
		{
		}

		public ClientLobbySetGamemode(GamemodeIDs gamemode, byte[] gamemodeSettings)
		{
			Gamemode = gamemode;
			GamemodeSettings = gamemodeSettings;
		}

		public override void Read(BinaryReader reader)
		{
			Gamemode = (GamemodeIDs)reader.ReadInt32();
			int count = reader.ReadInt32();
			GamemodeSettings = reader.ReadBytes(count);
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write((int)Gamemode);
			writer.Write(GamemodeSettings.Length);
			writer.Write(GamemodeSettings);
		}
	}
	public class ClientLobbySetPlayerTeam : Packet
	{
		public ushort PlayerId;

		public byte TeamId;

		public override Packets PacketId => Packets.ClientLobbySetPlayerTeam;

		public ClientLobbySetPlayerTeam()
		{
		}

		public ClientLobbySetPlayerTeam(ushort playerId, byte teamId)
		{
			PlayerId = playerId;
			TeamId = teamId;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(PlayerId);
			writer.Write(TeamId);
		}

		public override void Read(BinaryReader reader)
		{
			PlayerId = reader.ReadUInt16();
			TeamId = reader.ReadByte();
		}
	}
	public class ClientLobbySetReady : Packet
	{
		public bool Ready;

		public override Packets PacketId => Packets.ClientLobbySetReady;

		public ClientLobbySetReady()
		{
		}

		public ClientLobbySetReady(bool ready)
		{
			Ready = ready;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Ready);
		}

		public override void Read(BinaryReader reader)
		{
			Ready = reader.ReadBoolean();
		}
	}
	public class ClientLobbyStart : Packet
	{
		public override Packets PacketId => Packets.ClientLobbyStart;
	}
	public class ClientScoreBattleLength : Packet
	{
		public byte Minutes = 3;

		public override Packets PacketId => Packets.ClientScoreBattleLength;

		public ClientScoreBattleLength(byte minutes)
		{
			Minutes = minutes;
		}

		public ClientScoreBattleLength()
		{
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Minutes);
		}

		public override void Read(BinaryReader reader)
		{
			Minutes = reader.ReadByte();
		}
	}
	public class ClientSetTeam : Packet
	{
		public byte Team;

		public override Packets PacketId => Packets.ClientSetTeam;

		public ClientSetTeam()
		{
		}

		public ClientSetTeam(byte team)
		{
			Team = team;
		}

		public override void Read(BinaryReader reader)
		{
			Team = reader.ReadByte();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Team);
		}
	}
	public class ClientState : Packet
	{
		public Guid CrewBoomCharacter = Guid.Empty;

		public sbyte Character;

		public sbyte FallbackCharacter;

		public byte FallbackOutfit;

		public byte Outfit;

		public SpecialSkins SpecialSkin = SpecialSkins.None;

		public int SpecialSkinVariant = -1;

		public string Name = "Player";

		public string CrewName = "";

		public int Stage;

		public AuthUser User = new AuthUser();

		public override Packets PacketId => Packets.ClientState;

		public override void Read(BinaryReader reader)
		{
			if (Guid.TryParse(reader.ReadString(), out var result))
			{
				CrewBoomCharacter = result;
			}
			Character = reader.ReadSByte();
			FallbackCharacter = reader.ReadSByte();
			FallbackOutfit = reader.ReadByte();
			Outfit = reader.ReadByte();
			Stage = reader.ReadInt32();
			Name = reader.ReadString();
			CrewName = reader.ReadString();
			SpecialSkin = (SpecialSkins)reader.ReadInt32();
			SpecialSkinVariant = reader.ReadInt32();
			new AuthUser();
			User.Read(reader);
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(CrewBoomCharacter.ToString());
			writer.Write(Character);
			writer.Write(FallbackCharacter);
			writer.Write(FallbackOutfit);
			writer.Write(Outfit);
			writer.Write(Stage);
			writer.Write(Name);
			writer.Write(CrewName);
			writer.Write((int)SpecialSkin);
			writer.Write(SpecialSkinVariant);
			User.Write(writer);
		}
	}
	public class IncompatibleProtocolException : Exception
	{
	}
	public class ClientTeamGraffRaceScore : Packet
	{
		public int TagHash;

		public override Packets PacketId => Packets.ClientTeamGraffRaceScore;

		public ClientTeamGraffRaceScore()
		{
		}

		public ClientTeamGraffRaceScore(int tagHash)
		{
			TagHash = tagHash;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(TagHash);
		}

		public override void Read(BinaryReader reader)
		{
			TagHash = reader.ReadInt32();
		}
	}
	public class ClientVisualState : Packet
	{
		private enum BooleanMask
		{
			MoveStyleEquipped,
			SprayCanHeld,
			PhoneHeld,
			AFK,
			Hitbox,
			HitboxLeftLeg,
			HitboxRightLeg,
			HitboxUpperBody,
			HitboxAerial,
			HitboxRadial,
			HitboxSpray,
			BoostpackTrail,
			Chibi,
			BoEAnimation,
			MAX
		}

		private const float PhoneDirectionMaxValue = 2f;

		public Vector3 Position = Vector3.Zero;

		public Vector3 VisualPosition = Vector3.Zero;

		public Vector3 Velocity = Vector3.Zero;

		public Quaternion Rotation = Quaternion.Identity;

		public Quaternion VisualRotation = Quaternion.Identity;

		public bool MoveStyleEquipped;

		public int MoveStyle;

		public float GrindDirection;

		public bool SprayCanHeld;

		public bool PhoneHeld;

		public float PhoneDirectionX;

		public float PhoneDirectionY;

		public float TurnDirection1;

		public float TurnDirection2;

		public float TurnDirection3;

		public float TurnDirectionSkateboard;

		public PlayerStates State;

		public byte DustEmissionRate;

		public byte BoostpackEffectMode;

		public byte FrictionEffectMode;

		public int CurrentAnimation;

		public float CurrentAnimationTime;

		public bool AFK;

		public byte MoveStyleSkin;

		public int MPMoveStyleSkin = -1;

		public bool Hitbox;

		public bool HitboxLeftLeg;

		public bool HitboxRightLeg;

		public bool HitboxUpperBody;

		public bool HitboxAerial;

		public bool HitboxRadial;

		public bool HitboxSpray;

		public bool BoostpackTrail;

		public bool Chibi;

		public bool BoEAnimation;

		public override Packets PacketId => Packets.ClientVisualState;

		public override void Write(BinaryWriter writer)
		{
			writer.Write((byte)State);
			writer.Write(Position.X);
			writer.Write(Position.Y);
			writer.Write(Position.Z);
			writer.Write(VisualPosition.X);
			writer.Write(VisualPosition.Y);
			writer.Write(VisualPosition.Z);
			Compression.WriteCompressedQuaternion(Rotation, writer);
			Compression.WriteCompressedQuaternion(VisualRotation, writer);
			writer.Write(Velocity.X);
			writer.Write(Velocity.Y);
			writer.Write(Velocity.Z);
			Bitfield bitfield = new Bitfield(BooleanMask.MAX);
			bitfield[BooleanMask.MoveStyleEquipped] = MoveStyleEquipped;
			bitfield[BooleanMask.SprayCanHeld] = SprayCanHeld;
			bitfield[BooleanMask.PhoneHeld] = PhoneHeld;
			bitfield[BooleanMask.AFK] = AFK;
			bitfield[BooleanMask.Hitbox] = Hitbox;
			bitfield[BooleanMask.HitboxLeftLeg] = HitboxLeftLeg;
			bitfield[BooleanMask.HitboxRightLeg] = HitboxRightLeg;
			bitfield[BooleanMask.HitboxUpperBody] = HitboxUpperBody;
			bitfield[BooleanMask.HitboxAerial] = HitboxAerial;
			bitfield[BooleanMask.HitboxRadial] = HitboxRadial;
			bitfield[BooleanMask.HitboxSpray] = HitboxSpray;
			bitfield[BooleanMask.BoostpackTrail] = BoostpackTrail;
			bitfield[BooleanMask.Chibi] = Chibi;
			bitfield[BooleanMask.BoEAnimation] = BoEAnimation;
			bitfield.WriteShort(writer);
			writer.Write(MoveStyle);
			writer.Write(Compression.CompressToByte(PhoneDirectionX, 2f));
			writer.Write(Compression.CompressToByte(PhoneDirectionY, 2f));
			writer.Write(Compression.CompressNormal(TurnDirection1));
			writer.Write(Compression.CompressNormal(TurnDirection2));
			writer.Write(Compression.CompressNormal(TurnDirection3));
			writer.Write(Compression.CompressNormal(TurnDirectionSkateboard));
			writer.Write(Compression.CompressNormal(GrindDirection));
			writer.Write(DustEmissionRate);
			writer.Write(BoostpackEffectMode);
			writer.Write(FrictionEffectMode);
			writer.Write(CurrentAnimation);
			writer.Write(CurrentAnimationTime);
			writer.Write(MoveStyleSkin);
			writer.Write(MPMoveStyleSkin);
		}

		public override void Read(BinaryReader reader)
		{
			State = (PlayerStates)reader.ReadByte();
			float x = reader.ReadSingle();
			float y = reader.ReadSingle();
			float z = reader.ReadSingle();
			float x2 = reader.ReadSingle();
			float y2 = reader.ReadSingle();
			float z2 = reader.ReadSingle();
			Rotation = Quaternion.Normalize(Compression.ReadCompressedQuaternion(reader));
			VisualRotation = Quaternion.Normalize(Compression.ReadCompressedQuaternion(reader));
			float x3 = reader.ReadSingle();
			float y3 = reader.ReadSingle();
			float z3 = reader.ReadSingle();
			Bitfield bitfield = Bitfield.ReadShort(reader);
			MoveStyleEquipped = bitfield[BooleanMask.MoveStyleEquipped];
			SprayCanHeld = bitfield[BooleanMask.SprayCanHeld];
			PhoneHeld = bitfield[BooleanMask.PhoneHeld];
			AFK = bitfield[BooleanMask.AFK];
			bool hitbox2 = (bitfield[BooleanMask.Hitbox] = Hitbox);
			Hitbox = hitbox2;
			HitboxLeftLeg = bitfield[BooleanMask.HitboxLeftLeg];
			HitboxRightLeg = bitfield[BooleanMask.HitboxRightLeg];
			HitboxUpperBody = bitfield[BooleanMask.HitboxUpperBody];
			HitboxAerial = bitfield[BooleanMask.HitboxAerial];
			HitboxRadial = bitfield[BooleanMask.HitboxRadial];
			HitboxSpray = bitfield[BooleanMask.HitboxSpray];
			BoostpackTrail = bitfield[BooleanMask.BoostpackTrail];
			Chibi = bitfield[BooleanMask.Chibi];
			BoEAnimation = bitfield[BooleanMask.BoEAnimation];
			MoveStyle = reader.ReadInt32();
			PhoneDirectionX = Compression.DecompressFromByte(reader.ReadSByte(), 2f);
			PhoneDirectionY = Compression.DecompressFromByte(reader.ReadSByte(), 2f);
			TurnDirection1 = Compression.DecompressNormal(reader.ReadSByte());
			TurnDirection2 = Compression.DecompressNormal(reader.ReadSByte());
			TurnDirection3 = Compression.DecompressNormal(reader.ReadSByte());
			TurnDirectionSkateboard = Compression.DecompressNormal(reader.ReadSByte());
			GrindDirection = Compression.DecompressNormal(reader.ReadSByte());
			Position = new Vector3(x, y, z);
			VisualPosition = new Vector3(x2, y2, z2);
			Velocity = new Vector3(x3, y3, z3);
			DustEmissionRate = reader.ReadByte();
			BoostpackEffectMode = reader.ReadByte();
			FrictionEffectMode = reader.ReadByte();
			CurrentAnimation = reader.ReadInt32();
			CurrentAnimationTime = reader.ReadSingle();
			MoveStyleSkin = reader.ReadByte();
			MPMoveStyleSkin = reader.ReadInt32();
		}
	}
	public abstract class Packet
	{
		public abstract Packets PacketId { get; }

		public virtual void Read(BinaryReader reader)
		{
		}

		public virtual void Write(BinaryWriter writer)
		{
		}
	}
	public static class PacketFactory
	{
		private static Dictionary<Packets, Type> _packetTypeById = new Dictionary<Packets, Type>();

		private static INetworkingInterface NetworkingInterface => NetworkingEnvironment.NetworkingInterface;

		public static void Initialize()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				if (typeof(Packet).IsAssignableFrom(type) && !type.IsAbstract)
				{
					Packet packet = Activator.CreateInstance(type) as Packet;
					_packetTypeById[packet.PacketId] = type;
				}
			}
		}

		public static IMessage MessageFromPacket(Packet packet, IMessage.SendModes sendMode, NetChannels channel)
		{
			IMessage message = NetworkingInterface.CreateMessage(sendMode, channel, packet.PacketId);
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter writer = new BinaryWriter(memoryStream);
			packet.Write(writer);
			message.Add(memoryStream.ToArray());
			return message;
		}

		public static Packet PacketFromMessage(Packets packetId, IMessage message)
		{
			using MemoryStream input = new MemoryStream(message.GetBytes());
			using BinaryReader reader = new BinaryReader(input);
			Packet packet = null;
			if (_packetTypeById.TryGetValue(packetId, out var value))
			{
				packet = Activator.CreateInstance(value) as Packet;
			}
			packet?.Read(reader);
			return packet;
		}
	}
	public enum Packets : ushort
	{
		ClientState,
		ServerConnectionResponse,
		ServerClientStates,
		ClientVisualState,
		ServerClientVisualStates,
		PlayerAnimation,
		PlayerVoice,
		PlayerGenericEvent,
		PlayerGraffitiSlash,
		PlayerGraffitiFinisher,
		ClientLobbyCreate,
		ClientLobbyJoin,
		ClientLobbyLeave,
		ServerLobbies,
		ServerLobbyCreateResponse,
		ServerLobbyDeleted,
		ClientLobbyStart,
		ServerLobbyStart,
		ServerLobbyEnd,
		ServerGamemodeBegin,
		ClientGameModeScore,
		ClientLobbyEnd,
		ClientGraffitiRaceGSpots,
		ClientLobbySetGamemode,
		ServerPlayerCount,
		ClientLobbySetReady,
		ClientLobbyInvite,
		ServerLobbyInvite,
		ClientLobbyDeclineInvite,
		ClientLobbyDeclineAllInvites,
		ClientLobbyKick,
		ClientChat,
		ServerChat,
		ClientComboOver,
		ClientAuth,
		ServerBanList,
		ClientGraffitiRaceStart,
		ClientGamemodeCountdown,
		ClientScoreBattleLength,
		ClientHitByPlayer,
		ServerSetChibi,
		ClientSetTeam,
		ClientTeamGraffRaceScore,
		ServerTeamGraffRaceScore,
		ClientLobbySetAllowTeamSwitching,
		ClientLobbySetPlayerTeam,
		ClientLobbySetChallenge,
		ServerLobbySoftUpdate,
		ServerClientDisconnected,
		ServerSetSpecialSkin,
		ServerServerStateUpdate
	}
	public class PlayerAnimation : PlayerPacket
	{
		private enum BooleanMask
		{
			ForceOverwrite,
			Instant,
			BoE,
			MAX
		}

		public static IMessage.SendModes ClientSendMode = IMessage.SendModes.ReliableUnordered;

		public static IMessage.SendModes ServerSendMode = IMessage.SendModes.Unreliable;

		public int NewAnim;

		public bool ForceOverwrite;

		public bool Instant;

		public bool BoE;

		public float AtTime;

		public override Packets PacketId => Packets.PlayerAnimation;

		public PlayerAnimation()
		{
		}

		public PlayerAnimation(int newAnim, bool forceOverwrite = false, bool instant = false, float atTime = -1f)
		{
			NewAnim = newAnim;
			ForceOverwrite = forceOverwrite;
			Instant = instant;
			AtTime = atTime;
		}

		public override void Write(BinaryWriter writer)
		{
			base.Write(writer);
			writer.Write(ClientId);
			writer.Write(NewAnim);
			Bitfield bitfield = new Bitfield(BooleanMask.MAX);
			bitfield[BooleanMask.Instant] = Instant;
			bitfield[BooleanMask.ForceOverwrite] = ForceOverwrite;
			bitfield[BooleanMask.BoE] = BoE;
			bitfield.WriteByte(writer);
			writer.Write(Compression.CompressNormal(AtTime));
		}

		public override void Read(BinaryReader reader)
		{
			base.Read(reader);
			ClientId = reader.ReadUInt16();
			NewAnim = reader.ReadInt32();
			Bitfield bitfield = Bitfield.ReadByte(reader);
			Instant = bitfield[BooleanMask.Instant];
			ForceOverwrite = bitfield[BooleanMask.ForceOverwrite];
			BoE = bitfield[BooleanMask.BoE];
			AtTime = Compression.DecompressNormal(reader.ReadSByte());
		}
	}
	public class PlayerGenericEvent : PlayerPacket
	{
		public GenericEvents Event;

		public override Packets PacketId => Packets.PlayerGenericEvent;

		public PlayerGenericEvent()
		{
		}

		public PlayerGenericEvent(GenericEvents ev)
		{
			Event = ev;
		}

		public override void Read(BinaryReader reader)
		{
			base.Read(reader);
			Event = (GenericEvents)reader.ReadInt32();
		}

		public override void Write(BinaryWriter writer)
		{
			base.Write(writer);
			writer.Write((int)Event);
		}
	}
	public class PlayerGraffitiFinisher : PlayerPacket
	{
		public byte GraffitiSize;

		public override Packets PacketId => Packets.PlayerGraffitiFinisher;

		public PlayerGraffitiFinisher()
		{
		}

		public PlayerGraffitiFinisher(byte graffitiSize)
		{
			GraffitiSize = graffitiSize;
		}

		public override void Read(BinaryReader reader)
		{
			base.Read(reader);
			GraffitiSize = reader.ReadByte();
		}

		public override void Write(BinaryWriter writer)
		{
			base.Write(writer);
			writer.Write(GraffitiSize);
		}
	}
	public class PlayerGraffitiSlash : PlayerPacket
	{
		public Vector3 Direction = Vector3.Zero;

		public override Packets PacketId => Packets.PlayerGraffitiSlash;

		public PlayerGraffitiSlash()
		{
		}

		public PlayerGraffitiSlash(Vector3 direction)
		{
			Direction = direction;
		}

		public override void Read(BinaryReader reader)
		{
			base.Read(reader);
			Direction = Compression.ReadCompressedVector3Normal(reader);
		}

		public override void Write(BinaryWriter writer)
		{
			base.Write(writer);
			Compression.WriteCompressedVector3Normal(Direction, writer);
		}
	}
	public abstract class PlayerPacket : Packet
	{
		public ushort ClientId;

		public override void Read(BinaryReader reader)
		{
			ClientId = reader.ReadUInt16();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(ClientId);
		}
	}
	public class PlayerVoice : PlayerPacket
	{
		public int AudioClipId;

		public int VoicePriority;

		public override Packets PacketId => Packets.PlayerVoice;

		public override void Read(BinaryReader reader)
		{
			base.Read(reader);
			AudioClipId = reader.ReadInt32();
			VoicePriority = reader.ReadInt32();
		}

		public override void Write(BinaryWriter writer)
		{
			base.Write(writer);
			writer.Write(AudioClipId);
			writer.Write(VoicePriority);
		}
	}
	public class ServerBanList : Packet
	{
		public string JsonData = "";

		public override Packets PacketId => Packets.ServerBanList;

		public ServerBanList()
		{
		}

		public ServerBanList(string banList)
		{
			JsonData = banList;
		}

		public override void Read(BinaryReader reader)
		{
			JsonData = reader.ReadString();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(JsonData);
		}
	}
	public class ServerChat : Packet
	{
		public string Author = "";

		public string Message = "";

		public int[] Badges = Array.Empty<int>();

		public ChatMessageTypes MessageType;

		public override Packets PacketId => Packets.ServerChat;

		public ServerChat()
		{
		}

		public ServerChat(ChatMessageTypes messageType)
		{
			MessageType = messageType;
		}

		public ServerChat(string author, string message, int[] badges = null, ChatMessageTypes messageType = ChatMessageTypes.Chat)
		{
			Author = author;
			Message = message;
			MessageType = messageType;
			Badges = badges;
			if (Badges == null)
			{
				Badges = Array.Empty<int>();
			}
		}

		public ServerChat(string message, ChatMessageTypes messageType = ChatMessageTypes.System)
		{
			Message = message;
			MessageType = messageType;
		}

		public override void Read(BinaryReader reader)
		{
			Author = reader.ReadString();
			Message = reader.ReadString();
			MessageType = (ChatMessageTypes)reader.ReadInt32();
			int num = reader.ReadInt32();
			Badges = new int[num];
			for (int i = 0; i < num; i++)
			{
				Badges[i] = reader.ReadInt32();
			}
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Author);
			writer.Write(Message);
			writer.Write((int)MessageType);
			writer.Write(Badges.Length);
			int[] badges = Badges;
			foreach (int value in badges)
			{
				writer.Write(value);
			}
		}
	}
	public class ServerClientDisconnected : Packet
	{
		public ushort ClientId;

		public override Packets PacketId => Packets.ServerClientDisconnected;

		public ServerClientDisconnected(ushort clientId)
		{
			ClientId = clientId;
		}

		public ServerClientDisconnected()
		{
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(ClientId);
		}

		public override void Read(BinaryReader reader)
		{
			ClientId = reader.ReadUInt16();
		}
	}
	public class ServerClientStates : Packet
	{
		public Dictionary<ushort, ClientState> ClientStates = new Dictionary<ushort, ClientState>();

		public bool Full;

		public override Packets PacketId => Packets.ServerClientStates;

		public override void Read(BinaryReader reader)
		{
			Full = reader.ReadBoolean();
			int num = reader.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				ushort key = reader.ReadUInt16();
				ClientState clientState = new ClientState();
				clientState.Read(reader);
				ClientStates[key] = clientState;
			}
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Full);
			writer.Write(ClientStates.Count);
			foreach (KeyValuePair<ushort, ClientState> clientState in ClientStates)
			{
				writer.Write(clientState.Key);
				clientState.Value.Write(writer);
			}
		}
	}
	public class ServerClientVisualStates : Packet
	{
		public Dictionary<ushort, ClientVisualState> ClientVisualStates = new Dictionary<ushort, ClientVisualState>();

		public override Packets PacketId => Packets.ServerClientVisualStates;

		public override void Read(BinaryReader reader)
		{
			int num = reader.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				ushort key = reader.ReadUInt16();
				ClientVisualState clientVisualState = new ClientVisualState();
				clientVisualState.Read(reader);
				ClientVisualStates[key] = clientVisualState;
			}
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(ClientVisualStates.Count);
			foreach (KeyValuePair<ushort, ClientVisualState> clientVisualState in ClientVisualStates)
			{
				writer.Write(clientVisualState.Key);
				clientVisualState.Value.Write(writer);
			}
		}
	}
	public class ServerConnectionResponse : Packet
	{
		public ushort LocalClientId;

		public float TickRate = 1f / 32f;

		public IMessage.SendModes ClientAnimationSendMode = IMessage.SendModes.ReliableUnordered;

		public AuthUser User;

		public ServerState ServerState;

		public override Packets PacketId => Packets.ServerConnectionResponse;

		public override void Read(BinaryReader reader)
		{
			LocalClientId = reader.ReadUInt16();
			TickRate = reader.ReadSingle();
			ClientAnimationSendMode = (IMessage.SendModes)reader.ReadByte();
			User = new AuthUser();
			User.Read(reader);
			ServerState = new ServerState();
			ServerState.Read(reader);
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(LocalClientId);
			writer.Write(TickRate);
			writer.Write((byte)ClientAnimationSendMode);
			User.Write(writer);
			ServerState.Write(writer);
		}
	}
	public class ServerGamemodeBegin : Packet
	{
		public DateTime StartTime = DateTime.UtcNow;

		public override Packets PacketId => Packets.ServerGamemodeBegin;

		public ServerGamemodeBegin()
		{
		}

		public ServerGamemodeBegin(DateTime startTime)
		{
			StartTime = startTime;
		}

		public override void Read(BinaryReader reader)
		{
			StartTime = DateTime.FromBinary(reader.ReadInt64());
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(StartTime.ToBinary());
		}
	}
	public class ServerLobbies : Packet
	{
		public List<LobbyState> Lobbies = new List<LobbyState>();

		public override Packets PacketId => Packets.ServerLobbies;

		public ServerLobbies()
		{
		}

		public ServerLobbies(List<LobbyState> lobbies)
		{
			Lobbies = lobbies;
		}

		public override void Read(BinaryReader reader)
		{
			int num = reader.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				LobbyState lobbyState = new LobbyState();
				lobbyState.Read(reader);
				Lobbies.Add(lobbyState);
			}
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Lobbies.Count);
			foreach (LobbyState lobby in Lobbies)
			{
				lobby.Write(writer);
			}
		}
	}
	public class ServerLobbyCreateResponse : Packet
	{
		public override Packets PacketId => Packets.ServerLobbyCreateResponse;
	}
	public class ServerLobbyDeleted : Packet
	{
		public uint LobbyUID;

		public override Packets PacketId => Packets.ServerLobbyDeleted;

		public ServerLobbyDeleted()
		{
		}

		public ServerLobbyDeleted(uint lobbyUid)
		{
			LobbyUID = lobbyUid;
		}

		public override void Read(BinaryReader reader)
		{
			LobbyUID = reader.ReadUInt32();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(LobbyUID);
		}
	}
	public class ServerLobbyEnd : Packet
	{
		public bool Cancelled;

		public override Packets PacketId => Packets.ServerLobbyEnd;

		public ServerLobbyEnd()
		{
		}

		public ServerLobbyEnd(bool cancelled)
		{
			Cancelled = cancelled;
		}

		public override void Read(BinaryReader reader)
		{
			Cancelled = reader.ReadBoolean();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Cancelled);
		}
	}
	public class ServerLobbyInvite : Packet
	{
		public ushort InviteeId;

		public ushort InviterId;

		public uint LobbyId;

		public override Packets PacketId => Packets.ServerLobbyInvite;

		public ServerLobbyInvite()
		{
		}

		public ServerLobbyInvite(ushort inviteeId, ushort inviterId, uint lobbyId)
		{
			InviteeId = inviteeId;
			InviterId = inviterId;
			LobbyId = lobbyId;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(InviteeId);
			writer.Write(InviterId);
			writer.Write(LobbyId);
		}

		public override void Read(BinaryReader reader)
		{
			InviteeId = reader.ReadUInt16();
			InviterId = reader.ReadUInt16();
			LobbyId = reader.ReadUInt32();
		}
	}
	public class ServerLobbySoftUpdate : Packet
	{
		public uint LobbyId;

		public ushort PlayerId;

		public float Score;

		public override Packets PacketId => Packets.ServerLobbySoftUpdate;

		public ServerLobbySoftUpdate()
		{
		}

		public ServerLobbySoftUpdate(uint lobbyId, ushort playerId, float score)
		{
			LobbyId = lobbyId;
			PlayerId = playerId;
			Score = score;
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(LobbyId);
			writer.Write(PlayerId);
			writer.Write(Score);
		}

		public override void Read(BinaryReader reader)
		{
			LobbyId = reader.ReadUInt32();
			PlayerId = reader.ReadUInt16();
			Score = reader.ReadSingle();
		}
	}
	public class ServerLobbyStart : Packet
	{
		public override Packets PacketId => Packets.ServerLobbyStart;
	}
	public class ServerPlayerCount : Packet
	{
		public Dictionary<int, int> PlayerCountByStage = new Dictionary<int, int>();

		public override Packets PacketId => Packets.ServerPlayerCount;

		public ServerPlayerCount()
		{
		}

		public ServerPlayerCount(Dictionary<int, int> playerCountByStage)
		{
			PlayerCountByStage = playerCountByStage;
		}

		public override void Read(BinaryReader reader)
		{
			int num = reader.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				int key = reader.ReadInt32();
				int value = reader.ReadInt32();
				PlayerCountByStage[key] = value;
			}
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(PlayerCountByStage.Count);
			foreach (KeyValuePair<int, int> item in PlayerCountByStage)
			{
				writer.Write(item.Key);
				writer.Write(item.Value);
			}
		}
	}
	public class ServerServerStateUpdate : Packet
	{
		public ServerState State;

		public override Packets PacketId => Packets.ServerServerStateUpdate;

		public ServerServerStateUpdate(ServerState state)
		{
			State = state;
		}

		public ServerServerStateUpdate()
		{
		}

		public override void Read(BinaryReader reader)
		{
			State = new ServerState();
			State.Read(reader);
		}

		public override void Write(BinaryWriter writer)
		{
			State.Write(writer);
		}
	}
	public class ServerSetChibi : Packet
	{
		public bool Set;

		public override Packets PacketId => Packets.ServerSetChibi;

		public ServerSetChibi(bool set)
		{
			Set = set;
		}

		public ServerSetChibi()
		{
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(Set);
		}

		public override void Read(BinaryReader reader)
		{
			Set = reader.ReadBoolean();
		}
	}
	public class ServerSetSpecialSkin : Packet
	{
		public SpecialSkins SpecialSkin = SpecialSkins.None;

		public override Packets PacketId => Packets.ServerSetSpecialSkin;

		public ServerSetSpecialSkin(SpecialSkins specialSkin)
		{
			SpecialSkin = specialSkin;
		}

		public ServerSetSpecialSkin()
		{
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write((int)SpecialSkin);
		}

		public override void Read(BinaryReader reader)
		{
			SpecialSkin = (SpecialSkins)reader.ReadInt32();
		}
	}
	public class ServerTeamGraffRaceScore : Packet
	{
		public int TagHash;

		public ushort PlayerId;

		public override Packets PacketId => Packets.ServerTeamGraffRaceScore;

		public ServerTeamGraffRaceScore()
		{
		}

		public ServerTeamGraffRaceScore(ushort playerId, int tagHash)
		{
			PlayerId = playerId;
			TagHash = tagHash;
		}

		public override void Read(BinaryReader reader)
		{
			PlayerId = reader.ReadUInt16();
			TagHash = reader.ReadInt32();
		}

		public override void Write(BinaryWriter writer)
		{
			writer.Write(PlayerId);
			writer.Write(TagHash);
		}
	}
}
namespace BombRushMP.Common.Networking
{
	public class ConnectionFailedEventArgs
	{
		public readonly string Reason;

		public ConnectionFailedEventArgs(string reason)
		{
			Reason = reason;
		}
	}
	public class DisconnectedEventArgs
	{
		public readonly string Reason;

		public DisconnectedEventArgs(string reason)
		{
			Reason = reason;
		}
	}
	public interface IMessage
	{
		public enum SendModes
		{
			Unreliable,
			Reliable,
			ReliableUnordered
		}

		byte[] GetBytes();

		IMessage Add(byte[] data);
	}
	public interface INetClient
	{
		bool IsConnected { get; }

		EventHandler Connected { get; set; }

		EventHandler<MessageReceivedEventArgs> MessageReceived { get; set; }

		EventHandler<DisconnectedEventArgs> Disconnected { get; set; }

		EventHandler<ConnectionFailedEventArgs> ConnectionFailed { get; set; }

		bool Connect(string address, int port);

		void Disconnect();

		void Update();

		void Send(IMessage message);
	}
	public interface INetConnection
	{
		bool CanQualityDisconnect { get; set; }

		ushort Id { get; }

		string Address { get; }

		void Send(IMessage message);
	}
	public interface INetServer
	{
		EventHandler<MessageReceivedEventArgs> MessageReceived { get; set; }

		EventHandler<ServerDisconnectedEventArgs> ClientDisconnected { get; set; }

		EventHandler<ServerConnectedEventArgs> ClientConnected { get; set; }

		int TimeoutTime { set; }

		void Start(ushort port, ushort maxPlayers);

		void DisconnectClient(ushort id);

		void DisconnectClient(INetConnection client);

		void Update();

		void Stop();
	}
	public interface INetworkingInterface
	{
		int MaxPayloadSize { get; set; }

		INetClient CreateClient();

		INetServer CreateServer();

		IMessage CreateMessage(IMessage.SendModes sendMode, NetChannels channel, Enum packetId);
	}
	public class MessageReceivedEventArgs
	{
		public readonly ushort MessageId;

		public readonly IMessage Message;

		public readonly INetConnection FromConnection;

		public MessageReceivedEventArgs(ushort messageId, IMessage message, INetConnection fromConnection)
		{
			MessageId = messageId;
			Message = message;
			FromConnection = fromConnection;
		}
	}
	public enum NetChannels : byte
	{
		Default,
		Gamemodes,
		ClientAndLobbyUpdates,
		VisualUpdates,
		Chat,
		Animation,
		MAX
	}
	public static class NetworkingEnvironment
	{
		public static INetworkingInterface NetworkingInterface;

		public static bool UseNativeSocketsIfAvailable = true;

		public static Action<string> LogEventHandler;

		public static void Log(string message)
		{
			LogEventHandler?.Invoke(message);
		}
	}
	public class ServerConnectedEventArgs
	{
		public readonly INetConnection Client;

		public ServerConnectedEventArgs(INetConnection client)
		{
			Client = client;
		}
	}
	public class ServerDisconnectedEventArgs
	{
		public readonly INetConnection Client;

		public readonly string Reason;

		public ServerDisconnectedEventArgs(INetConnection client, string reason)
		{
			Client = client;
			Reason = reason;
		}
	}
}

BombRushMP.CrewBoom.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BombRushMP.Common;
using BombRushMP.PluginCommon;
using CommonAPI;
using Microsoft.CodeAnalysis;
using Reptile;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BombRushMP.CrewBoom
{
	internal static class AudioLibraryUtils
	{
		public static AudioLibrary CreateFromCrewBoomCharacterDefinition(object definition)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Expected O, but got Unknown
			AudioLibrary val = new AudioLibrary();
			AudioCollection val2 = new AudioCollection();
			AudioCollection val3 = new AudioCollection();
			AudioCollection val4 = new AudioCollection();
			AudioCollection val5 = new AudioCollection();
			AudioCollection val6 = new AudioCollection();
			AudioCollection val7 = new AudioCollection();
			AudioCollection val8 = new AudioCollection();
			AudioClip[] collection = CrewBoomTypes.CharacterDefinitionVoiceJumpField.GetValue(definition) as AudioClip[];
			AudioClip[] collection2 = CrewBoomTypes.CharacterDefinitionVoiceGetHitField.GetValue(definition) as AudioClip[];
			AudioClip[] collection3 = CrewBoomTypes.CharacterDefinitionVoiceDieField.GetValue(definition) as AudioClip[];
			AudioClip[] collection4 = CrewBoomTypes.CharacterDefinitionVoiceDieFallField.GetValue(definition) as AudioClip[];
			AudioClip[] collection5 = CrewBoomTypes.CharacterDefinitionVoiceComboField.GetValue(definition) as AudioClip[];
			AudioClip[] collection6 = CrewBoomTypes.CharacterDefinitionVoiceBoostTrickField.GetValue(definition) as AudioClip[];
			AudioClip[] collection7 = CrewBoomTypes.CharacterDefinitionVoiceTalkField.GetValue(definition) as AudioClip[];
			val2.Clips.AddRange(collection);
			val3.Clips.AddRange(collection2);
			val4.Clips.AddRange(collection3);
			val5.Clips.AddRange(collection4);
			val6.Clips.AddRange(collection5);
			val7.Clips.AddRange(collection6);
			val8.Clips.AddRange(collection7);
			val.Collections[(AudioClipID)489] = val2;
			val.Collections[(AudioClipID)488] = val3;
			val.Collections[(AudioClipID)484] = val4;
			val.Collections[(AudioClipID)485] = val5;
			val.Collections[(AudioClipID)487] = val6;
			val.Collections[(AudioClipID)498] = val7;
			val.Collections[(AudioClipID)486] = val8;
			return val;
		}
	}
	public class CharacterHandle : IDisposable
	{
		public bool Finished;

		public bool Failed;

		public Action OnLoadFinished;

		private AssetBundleCreateRequest _request;

		private AssetBundle _bundle;

		public Guid GUID = Guid.Empty;

		private AssetBundleRequest _assetRequest;

		public GameObject CharacterPrefab { get; private set; }

		public int References { get; private set; }

		public AudioLibrary AudioLibrary { get; private set; }

		public CharacterHandle(Guid guid)
		{
			GUID = guid;
		}

		public void LoadAsync(string bundle)
		{
			_request = AssetBundle.LoadFromFileAsync(bundle);
			((AsyncOperation)_request).completed += OnAssetBundleLoadCompletion;
		}

		private void OnAssetBundleLoadCompletion(AsyncOperation operation)
		{
			_bundle = _request.assetBundle;
			Failed = (Object)(object)_bundle == (Object)null;
			if (!Failed)
			{
				_assetRequest = _bundle.LoadAllAssetsAsync<GameObject>();
				((AsyncOperation)_assetRequest).completed += OnGameObjectsLoadCompletion;
			}
			else
			{
				Finished = true;
				OnLoadFinished?.Invoke();
			}
		}

		private void OnGameObjectsLoadCompletion(AsyncOperation operation)
		{
			Object[] allAssets = _assetRequest.allAssets;
			foreach (Object obj in allAssets)
			{
				GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
				if (!((Object)(object)val == (Object)null))
				{
					Component component = val.GetComponent(CrewBoomTypes.CharacterDefinitionType);
					if ((Object)(object)component != (Object)null)
					{
						CharacterPrefab = val;
						AudioLibrary = AudioLibraryUtils.CreateFromCrewBoomCharacterDefinition(component);
						break;
					}
				}
			}
			Failed = (Object)(object)CharacterPrefab != (Object)null;
			Finished = true;
			OnLoadFinished?.Invoke();
		}

		public void Load(string bundle)
		{
			try
			{
				_bundle = AssetBundle.LoadFromFile(bundle);
				GameObject[] array = _bundle.LoadAllAssets<GameObject>();
				foreach (GameObject val in array)
				{
					Component component = val.GetComponent(CrewBoomTypes.CharacterDefinitionType);
					if ((Object)(object)component != (Object)null)
					{
						CharacterPrefab = val;
						AudioLibrary = AudioLibraryUtils.CreateFromCrewBoomCharacterDefinition(component);
						break;
					}
				}
			}
			finally
			{
				Failed = (Object)(object)_bundle == (Object)null;
				Finished = true;
				OnLoadFinished?.Invoke();
			}
		}

		public void AddReference()
		{
			References++;
		}

		public void Release()
		{
			References--;
		}

		public void Dispose()
		{
			if ((Object)(object)_bundle != (Object)null)
			{
				_bundle.Unload(true);
				_bundle = null;
			}
		}

		public CharacterVisual ConstructVisual()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_003d: 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)
			GameObject obj = Object.Instantiate<GameObject>(CharacterPrefab);
			GameObject val = new GameObject(((Object)CharacterPrefab).name + " Visual");
			obj.transform.SetParent(val.transform, false);
			obj.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
			return val.AddComponent<CharacterVisual>();
		}
	}
	public static class CrewBoomStreamer
	{
		public static bool AlreadyLoadedThisSession = false;

		internal static FieldInfo CharacterDefinitionIdField;

		internal static Dictionary<Guid, CharacterHandle> CharacterHandleByGUID = new Dictionary<Guid, CharacterHandle>();

		private static Dictionary<Guid, string> BundlePathByGUID = new Dictionary<Guid, string>();

		private static List<string> Directories = new List<string>();

		public static int LoadedCharacters => CharacterHandleByGUID.Count;

		public static Shader CharacterShader { get; private set; }

		public static void Initialize()
		{
			CharacterDefinitionIdField = CrewBoomTypes.CharacterDefinitionType.GetField("Id");
		}

		public static void AddDirectory(string directory)
		{
			Directories.Add(directory);
			Directory.CreateDirectory(directory);
		}

		public static void ReloadResources()
		{
			CharacterShader = AssetAPI.GetShader((ShaderNames)0);
		}

		public static void ReloadCharacters()
		{
			foreach (KeyValuePair<Guid, CharacterHandle> item in CharacterHandleByGUID)
			{
				item.Value.Dispose();
			}
			CharacterHandleByGUID.Clear();
			BundlePathByGUID.Clear();
			foreach (string directory in Directories)
			{
				LoadFromDirectory(directory);
			}
			AlreadyLoadedThisSession = true;
		}

		public static void LoadFromDirectory(string directory)
		{
			string[] files = Directory.GetFiles(directory, "*.cbb", SearchOption.AllDirectories);
			foreach (string text in files)
			{
				string path = Path.ChangeExtension(text, ".txt");
				if (File.Exists(path))
				{
					Register(Guid.Parse(File.ReadAllText(path)), text);
					continue;
				}
				AssetBundle val = null;
				try
				{
					val = AssetBundle.LoadFromFile(text);
					GameObject[] array = val.LoadAllAssets<GameObject>();
					for (int j = 0; j < array.Length; j++)
					{
						Component component = array[j].GetComponent(CrewBoomTypes.CharacterDefinitionType);
						if ((Object)(object)component != (Object)null)
						{
							Guid guid = Guid.Parse(CharacterDefinitionIdField.GetValue(component) as string);
							Register(guid, text);
							File.WriteAllText(path, guid.ToString());
							break;
						}
					}
				}
				catch (Exception ex)
				{
					Debug.LogException(ex);
				}
				finally
				{
					if ((Object)(object)val != (Object)null)
					{
						val.Unload(true);
					}
				}
			}
		}

		public static bool HasCharacter(Guid guid)
		{
			return BundlePathByGUID.ContainsKey(guid);
		}

		public static CharacterHandle RequestCharacter(Guid guid, bool isAsync)
		{
			if (CharacterHandleByGUID.TryGetValue(guid, out var value))
			{
				value.AddReference();
				return value;
			}
			if (BundlePathByGUID.TryGetValue(guid, out var value2))
			{
				CharacterHandle characterHandle = new CharacterHandle(guid);
				if (isAsync)
				{
					characterHandle.LoadAsync(value2);
				}
				else
				{
					characterHandle.Load(value2);
				}
				characterHandle.AddReference();
				CharacterHandleByGUID[guid] = characterHandle;
				return characterHandle;
			}
			return null;
		}

		public static void Tick()
		{
			foreach (KeyValuePair<Guid, CharacterHandle> item in new Dictionary<Guid, CharacterHandle>(CharacterHandleByGUID))
			{
				if (item.Value.References <= 0 && item.Value.Finished)
				{
					item.Value.Dispose();
					CharacterHandleByGUID.Remove(item.Key);
				}
			}
		}

		private static void Register(Guid guid, string file)
		{
			BundlePathByGUID[guid] = file;
		}
	}
	public static class CrewBoomSupport
	{
		public const string SKATE_OFFSET_L = "skateOffsetL";

		public const string SKATE_OFFSET_R = "skateOffsetR";

		private static Dictionary<Characters, List<Guid>> _characterIds;

		private static MethodInfo _customCharactersTryGetValueMethod;

		private static PropertyInfo _customCharacterDefinitionProperty;

		private static FieldInfo _characterDefinitionIdField;

		public static bool Installed { get; private set; }

		public static void Initialize()
		{
			Installed = true;
			CrewBoomTypes.Initialize();
			_characterIds = ReflectionUtility.GetTypeByName("CrewBoom.CharacterDatabase").GetField("_characterIds", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as Dictionary<Characters, List<Guid>>;
		}

		public static Characters GetCharacterForGuid(Guid guid, Characters fallback = 3)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (guid.Equals(Guid.Empty))
			{
				return fallback;
			}
			foreach (KeyValuePair<Characters, List<Guid>> characterId in _characterIds)
			{
				if (characterId.Value != null && characterId.Value.Contains(guid))
				{
					return characterId.Key;
				}
			}
			return fallback;
		}

		public static Guid GetGuidForCharacter(Characters character)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if ((int)character < 26)
			{
				return Guid.Empty;
			}
			if (_characterIds.TryGetValue(character, out var value))
			{
				return value[0];
			}
			return Guid.Empty;
		}
	}
	public static class CrewBoomTypes
	{
		public static Type CharacterDefinitionType;

		public static Type CharacterOutfitType;

		public static Type CharacterOutfitRendererType;

		public static FieldInfo CharacterDefinitionOutfitsField;

		public static FieldInfo CharacterDefinitionRenderersField;

		public static FieldInfo CharacterDefinitionCanBlinkField;

		public static FieldInfo CharacterOutfitEnabledRenderersField;

		public static FieldInfo CharacterOutfitMaterialContainersField;

		public static FieldInfo CharacterOutfitRendererMaterialsField;

		public static FieldInfo CharacterOutfitRendererUseShaderForMaterialField;

		public static FieldInfo CharacterDefinitionVoiceDieField;

		public static FieldInfo CharacterDefinitionVoiceDieFallField;

		public static FieldInfo CharacterDefinitionVoiceTalkField;

		public static FieldInfo CharacterDefinitionVoiceBoostTrickField;

		public static FieldInfo CharacterDefinitionVoiceComboField;

		public static FieldInfo CharacterDefinitionVoiceGetHitField;

		public static FieldInfo CharacterDefinitionVoiceJumpField;

		public static void Initialize()
		{
			CharacterDefinitionType = ReflectionUtility.GetTypeByName("CrewBoomMono.CharacterDefinition");
			CharacterOutfitType = ReflectionUtility.GetTypeByName("CrewBoomMono.CharacterOutfit");
			CharacterOutfitRendererType = ReflectionUtility.GetTypeByName("CrewBoomMono.CharacterOutfitRenderer");
			CharacterDefinitionOutfitsField = CharacterDefinitionType.GetField("Outfits");
			CharacterDefinitionRenderersField = CharacterDefinitionType.GetField("Renderers");
			CharacterDefinitionCanBlinkField = CharacterDefinitionType.GetField("CanBlink");
			CharacterOutfitEnabledRenderersField = CharacterOutfitType.GetField("EnabledRenderers");
			CharacterOutfitMaterialContainersField = CharacterOutfitType.GetField("MaterialContainers");
			CharacterOutfitRendererMaterialsField = CharacterOutfitRendererType.GetField("Materials");
			CharacterOutfitRendererUseShaderForMaterialField = CharacterOutfitRendererType.GetField("UseShaderForMaterial");
			CharacterDefinitionVoiceDieField = CharacterDefinitionType.GetField("VoiceDie");
			CharacterDefinitionVoiceDieFallField = CharacterDefinitionType.GetField("VoiceDieFall");
			CharacterDefinitionVoiceTalkField = CharacterDefinitionType.GetField("VoiceTalk");
			CharacterDefinitionVoiceBoostTrickField = CharacterDefinitionType.GetField("VoiceBoostTrick");
			CharacterDefinitionVoiceComboField = CharacterDefinitionType.GetField("VoiceCombo");
			CharacterDefinitionVoiceGetHitField = CharacterDefinitionType.GetField("VoiceGetHit");
			CharacterDefinitionVoiceJumpField = CharacterDefinitionType.GetField("VoiceJump");
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

BombRushMP.LiteNetLibInterface.dll

Decompiled 2 hours ago
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BombRushMP.Common.Networking;
using LiteNetLib;
using LiteNetLib.Layers;
using LiteNetLib.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BombRushMP.LiteNetLibInterface")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BombRushMP.LiteNetLibInterface")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("12cf70a5-535b-4ce2-be8f-c0f34cab3614")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BombRushMP.LiteNetLibInterface;

public class LiteNetLibClient : INetClient
{
	private EventBasedNetListener _netListener;

	private NetManager _netManager;

	public bool IsConnected
	{
		get
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			if (_netManager != null && _netManager.FirstPeer != null)
			{
				return (int)_netManager.FirstPeer.ConnectionState == 4;
			}
			return false;
		}
	}

	public EventHandler Connected { get; set; }

	public EventHandler<MessageReceivedEventArgs> MessageReceived { get; set; }

	public EventHandler<DisconnectedEventArgs> Disconnected { get; set; }

	public EventHandler<ConnectionFailedEventArgs> ConnectionFailed { get; set; }

	public LiteNetLibClient()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Expected O, but got Unknown
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		_netListener = new EventBasedNetListener();
		_netListener.PeerConnectedEvent += new OnPeerConnected(_netListener_PeerConnectedEvent);
		_netListener.NetworkReceiveEvent += new OnNetworkReceive(_netListener_NetworkReceiveEvent);
		_netListener.PeerDisconnectedEvent += new OnPeerDisconnected(_netListener_PeerDisconnectedEvent);
	}

	private void _netListener_PeerDisconnectedEvent(NetPeer peer, DisconnectInfo disconnectInfo)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_0015: 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_002d: Expected O, but got Unknown
		if ((int)disconnectInfo.Reason == 0)
		{
			EventHandler<ConnectionFailedEventArgs> connectionFailed = ConnectionFailed;
			if (connectionFailed != null)
			{
				DisconnectReason val = (DisconnectReason)0;
				connectionFailed(this, new ConnectionFailedEventArgs(((object)(DisconnectReason)(ref val)).ToString()));
			}
		}
		else
		{
			Disconnected?.Invoke(this, new DisconnectedEventArgs(((object)(DisconnectReason)(ref disconnectInfo.Reason)).ToString()));
		}
	}

	private void _netListener_NetworkReceiveEvent(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod)
	{
		//IL_001e: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		if (((NetDataReader)reader).GetByte() != 0)
		{
			ushort uShort = ((NetDataReader)reader).GetUShort();
			byte[] remainingBytes = ((NetDataReader)reader).GetRemainingBytes();
			LiteNetLibConnection liteNetLibConnection = new LiteNetLibConnection(peer);
			LiteNetLibMessage liteNetLibMessage = new LiteNetLibMessage(LiteNetLibUtils.DeliveryMethodToSendMode(deliveryMethod), (NetChannels)channel, uShort);
			liteNetLibMessage.Add(remainingBytes);
			MessageReceived?.Invoke(this, new MessageReceivedEventArgs(uShort, (IMessage)(object)liteNetLibMessage, (INetConnection)(object)liteNetLibConnection));
			reader.Recycle();
		}
	}

	private void _netListener_PeerConnectedEvent(NetPeer peer)
	{
		Connected?.Invoke(this, null);
	}

	public bool Connect(string address, int port)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		if (_netManager != null)
		{
			_netManager.Stop();
		}
		_netManager = new NetManager((INetEventListener)(object)_netListener, (PacketLayerBase)null);
		_netManager.ChannelsCount = 6;
		if (NetworkingEnvironment.UseNativeSocketsIfAvailable)
		{
			NetworkingEnvironment.Log("LiteNetLib: Using native sockets if supported.");
			_netManager.UseNativeSockets = true;
		}
		if (_netManager.Start())
		{
			IPAddress[] hostAddresses = Dns.GetHostAddresses(address);
			if (hostAddresses.Length != 0)
			{
				address = hostAddresses[0].ToString();
			}
			IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(address), port);
			_netManager.Connect(iPEndPoint, LiteNetLibInterface.Key);
			return true;
		}
		return false;
	}

	public void Disconnect()
	{
		_netManager.DisconnectAll();
	}

	public void Send(IMessage message)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		_netManager.SendToAll((message as LiteNetLibMessage).GetBytesForSend(), (message as LiteNetLibMessage).DeliveryMethod);
	}

	public void Update()
	{
		_netManager.TriggerUpdate();
		_netManager.PollEvents(0);
	}

	public override string ToString()
	{
		return ((object)_netManager).ToString();
	}
}
public class LiteNetLibConnection : INetConnection
{
	public NetPeer Peer;

	public bool CanQualityDisconnect
	{
		get
		{
			return false;
		}
		set
		{
		}
	}

	public ushort Id => LiteNetLibUtils.PeerIdToGameId(Peer.Id);

	public string Address => ((object)Peer).ToString().Split(new char[1] { ':' })[0];

	public LiteNetLibConnection(NetPeer peer)
	{
		Peer = peer;
	}

	public void Send(IMessage message)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected I4, but got Unknown
		LiteNetLibMessage liteNetLibMessage = message as LiteNetLibMessage;
		byte[] bytesForSend = liteNetLibMessage.GetBytesForSend();
		Peer.Send(bytesForSend, (byte)(int)liteNetLibMessage.Channel, liteNetLibMessage.DeliveryMethod);
	}

	public override string ToString()
	{
		return ((object)Peer).ToString();
	}
}
public class LiteNetLibInterface : INetworkingInterface
{
	public static string Key = $"ACN-{17u}";

	public int MaxPayloadSize
	{
		get
		{
			return 1400;
		}
		set
		{
		}
	}

	public INetClient CreateClient()
	{
		return (INetClient)(object)new LiteNetLibClient();
	}

	public IMessage CreateMessage(SendModes sendMode, NetChannels channel, Enum packetId)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return (IMessage)(object)new LiteNetLibMessage(sendMode, channel, Convert.ToUInt16(packetId));
	}

	public INetServer CreateServer()
	{
		return (INetServer)(object)new LiteNetLibServer();
	}

	public override string ToString()
	{
		return "LiteNetLib";
	}
}
public class LiteNetLibMessage : IMessage
{
	public DeliveryMethod DeliveryMethod;

	public NetChannels Channel;

	private ushort _packetId;

	private NetDataWriter _writer;

	public LiteNetLibMessage(SendModes sendMode, NetChannels channel, ushort packetId)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		DeliveryMethod = LiteNetLibUtils.SendModeToDeliveryMethod(sendMode);
		Channel = channel;
		_writer = new NetDataWriter();
		_packetId = packetId;
	}

	public IMessage Add(byte[] data)
	{
		_writer.Put(data);
		return (IMessage)(object)this;
	}

	public byte[] GetBytes()
	{
		return _writer.CopyData();
	}

	public byte[] GetBytesForSend()
	{
		using MemoryStream memoryStream = new MemoryStream();
		using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
		binaryWriter.Write((byte)1);
		binaryWriter.Write(_packetId);
		binaryWriter.Write(GetBytes());
		return memoryStream.ToArray();
	}
}
public class LiteNetLibServer : INetServer
{
	private int _disconnectTimeout = 10000;

	private EventBasedNetListener _netListener;

	private NetManager _netManager;

	private ushort _maxPlayers;

	public EventHandler<MessageReceivedEventArgs> MessageReceived { get; set; }

	public EventHandler<ServerDisconnectedEventArgs> ClientDisconnected { get; set; }

	public EventHandler<ServerConnectedEventArgs> ClientConnected { get; set; }

	public int TimeoutTime
	{
		set
		{
			_disconnectTimeout = value;
		}
	}

	public LiteNetLibServer()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Expected O, but got Unknown
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Expected O, but got Unknown
		_netListener = new EventBasedNetListener();
		_netListener.ConnectionRequestEvent += new OnConnectionRequest(_netListener_ConnectionRequestEvent);
		_netListener.PeerConnectedEvent += new OnPeerConnected(_netListener_PeerConnectedEvent);
		_netListener.PeerDisconnectedEvent += new OnPeerDisconnected(_netListener_PeerDisconnectedEvent);
		_netListener.NetworkReceiveEvent += new OnNetworkReceive(_netListener_NetworkReceiveEvent);
	}

	private void _netListener_NetworkReceiveEvent(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod)
	{
		//IL_001e: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		if (((NetDataReader)reader).GetByte() != 0)
		{
			ushort uShort = ((NetDataReader)reader).GetUShort();
			byte[] remainingBytes = ((NetDataReader)reader).GetRemainingBytes();
			LiteNetLibConnection liteNetLibConnection = new LiteNetLibConnection(peer);
			LiteNetLibMessage liteNetLibMessage = new LiteNetLibMessage(LiteNetLibUtils.DeliveryMethodToSendMode(deliveryMethod), (NetChannels)channel, uShort);
			liteNetLibMessage.Add(remainingBytes);
			MessageReceived?.Invoke(this, new MessageReceivedEventArgs(uShort, (IMessage)(object)liteNetLibMessage, (INetConnection)(object)liteNetLibConnection));
			reader.Recycle();
		}
	}

	private void _netListener_PeerDisconnectedEvent(NetPeer peer, DisconnectInfo disconnectInfo)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		ClientDisconnected?.Invoke(this, new ServerDisconnectedEventArgs((INetConnection)(object)new LiteNetLibConnection(peer), ((object)(DisconnectReason)(ref disconnectInfo.Reason)).ToString()));
		using MemoryStream memoryStream = new MemoryStream();
		using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
		binaryWriter.Write((byte)0);
		binaryWriter.Write(LiteNetLibUtils.PeerIdToGameId(peer.Id));
		byte[] array = memoryStream.ToArray();
		_netManager.SendToAll(array, (DeliveryMethod)2);
	}

	private void _netListener_PeerConnectedEvent(NetPeer peer)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		ClientConnected?.Invoke(this, new ServerConnectedEventArgs((INetConnection)(object)new LiteNetLibConnection(peer)));
	}

	private void _netListener_ConnectionRequestEvent(ConnectionRequest request)
	{
		if (_netManager.ConnectedPeersCount < _maxPlayers)
		{
			request.AcceptIfKey(LiteNetLibInterface.Key);
		}
		else
		{
			request.Reject();
		}
	}

	public void DisconnectClient(ushort id)
	{
		NetPeer peerById = _netManager.GetPeerById(LiteNetLibUtils.GameIdToPeerId(id));
		_netManager.DisconnectPeer(peerById);
	}

	public void DisconnectClient(INetConnection client)
	{
		LiteNetLibConnection liteNetLibConnection = client as LiteNetLibConnection;
		_netManager.DisconnectPeer(liteNetLibConnection.Peer);
	}

	public void Start(ushort port, ushort maxPlayers)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		if (_netManager != null)
		{
			_netManager.Stop();
		}
		_netManager = new NetManager((INetEventListener)(object)_netListener, (PacketLayerBase)null);
		_netManager.ChannelsCount = 6;
		if (NetworkingEnvironment.UseNativeSocketsIfAvailable)
		{
			NetworkingEnvironment.Log("LiteNetLib: Using native sockets if supported.");
			_netManager.UseNativeSockets = true;
		}
		_netManager.DisconnectTimeout = _disconnectTimeout;
		_netManager.Start((int)port);
		_maxPlayers = maxPlayers;
	}

	public void Stop()
	{
		_netManager.Stop();
	}

	public void Update()
	{
		_netManager.TriggerUpdate();
		_netManager.PollEvents(0);
	}

	public override string ToString()
	{
		return ((object)_netManager).ToString();
	}
}
public static class LiteNetLibUtils
{
	public static ushort PeerIdToGameId(int peerId)
	{
		return (ushort)(peerId + 1);
	}

	public static int GameIdToPeerId(ushort gameId)
	{
		return gameId - 1;
	}

	public static DeliveryMethod SendModeToDeliveryMethod(SendModes sendMode)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected I4, but got Unknown
		return (DeliveryMethod)((int)sendMode switch
		{
			0 => 4, 
			1 => 2, 
			2 => 0, 
			_ => 2, 
		});
	}

	public static SendModes DeliveryMethodToSendMode(DeliveryMethod deliveryMethod)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected I4, but got Unknown
		return (SendModes)((int)deliveryMethod switch
		{
			4 => 0, 
			2 => 1, 
			0 => 2, 
			_ => 1, 
		});
	}
}

BombRushMP.MapStation.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BombRushMP.Common;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BombRushMP.MapStation
{
	public static class MapStationSupport
	{
		public static List<MPStage> Stages = new List<MPStage>();

		private static Type _apiManagerType;

		public static bool Installed { get; private set; } = false;


		public static void Initialize()
		{
			Installed = true;
			_apiManagerType = ReflectionUtility.GetTypeByName("MapStation.API.APIManager");
			_apiManagerType.GetEvent("OnInitialized", BindingFlags.Static | BindingFlags.Public).AddEventHandler(null, new Action(OnMapStationAPIInitialized));
		}

		private static void OnMapStationAPIInitialized()
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			ReflectionUtility.GetTypeByName("MapStation.API.ICustomStage");
			Type typeByName = ReflectionUtility.GetTypeByName("MapStation.API.IMapStationAPI");
			object value = _apiManagerType.GetField("API", BindingFlags.Static | BindingFlags.Public).GetValue(null);
			IList obj = typeByName.GetProperty("CustomStages", BindingFlags.Instance | BindingFlags.Public).GetValue(value) as IList;
			Type typeByName2 = ReflectionUtility.GetTypeByName("MapStation.API.ICustomStage");
			PropertyInfo property = typeByName2.GetProperty("DisplayName");
			PropertyInfo property2 = typeByName2.GetProperty("StageID");
			foreach (object item2 in obj)
			{
				string obj2 = (string)property.GetValue(item2);
				int num = (int)property2.GetValue(item2);
				MPStage item = new MPStage(obj2, num);
				Stages.Add(item);
			}
		}

		public static bool IsMapOptionToggleable(GameObject go)
		{
			MonoBehaviour[] componentsInParent = go.GetComponentsInParent<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInParent)
			{
				if (!((Object)(object)val == (Object)null) && ((object)val).GetType().Name == "ActiveOnMapOption")
				{
					return true;
				}
			}
			return false;
		}
	}
}

BombRushMP.Mono.dll

Decompiled 2 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BombRushMP.Mono
{
	public class SpecialSkinDefinition : MonoBehaviour
	{
		[Header("Visuals")]
		public bool CanBlink;

		public string MainRendererName;

		public Material[] Variants;

		[Header("Voice Lines")]
		public AudioClip[] Jump;

		public AudioClip[] GetHit;

		public AudioClip[] Die;

		public AudioClip[] DieFall;

		public AudioClip[] Combo;

		public AudioClip[] BoostTrick;

		public AudioClip[] Talk;
	}
}

BombRushMP.NetworkInterfaceProvider.dll

Decompiled 2 hours ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BombRushMP.Common.Networking;
using BombRushMP.LiteNetLibInterface;
using BombRushMP.RiptideInterface;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BombRushMP.NetworkInterfaceProvider")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BombRushMP.NetworkInterfaceProvider")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("db50ed07-4684-485a-a962-e29460c006a1")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BombRushMP.NetworkInterfaceProvider;

public enum NetworkInterfaces
{
	Riptide,
	LiteNetLib
}
public static class NetworkInterfaceFactory
{
	public static INetworkingInterface GetNetworkInterface(NetworkInterfaces netInterface)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		INetworkingInterface result = null;
		switch (netInterface)
		{
		case NetworkInterfaces.Riptide:
			result = (INetworkingInterface)new RiptideInterface();
			break;
		case NetworkInterfaces.LiteNetLib:
			result = (INetworkingInterface)new LiteNetLibInterface();
			break;
		}
		return result;
	}
}

BombRushMP.Plugin.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BombRushMP.BunchOfEmotes;
using BombRushMP.Common;
using BombRushMP.Common.Networking;
using BombRushMP.Common.Packets;
using BombRushMP.CrewBoom;
using BombRushMP.MapStation;
using BombRushMP.Mono;
using BombRushMP.NetworkInterfaceProvider;
using BombRushMP.Plugin;
using BombRushMP.Plugin.Gamemodes;
using BombRushMP.Plugin.LocalServer;
using BombRushMP.Plugin.OfflineInterface;
using BombRushMP.Plugin.Patches;
using BombRushMP.Plugin.Phone;
using BombRushMP.PluginCommon;
using BombRushMP.Server;
using CommonAPI;
using CommonAPI.Phone;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using Reptile.Phone;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Playables;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("BombRushMP.Plugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a04cda609b5a0a0f830ac52bbd58291ca8231db1")]
[assembly: AssemblyProduct("BombRushMP.Plugin")]
[assembly: AssemblyTitle("BombRushMP.Plugin")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class AppJoinLobbyDebug : CustomApp
{
	public override bool Available => false;

	public static void Initialize()
	{
		PhoneAPI.RegisterApp<AppJoinLobbyDebug>("debug join lobby", (Sprite)null);
	}

	public override void OnAppInit()
	{
		((CustomApp)this).OnAppInit();
		((CustomApp)this).CreateIconlessTitleBar("Lobbies", 80f);
		base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
	}

	public override void OnAppEnable()
	{
		((App)this).OnAppEnable();
		PopulateButtons();
	}

	private void PopulateButtons()
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		base.ScrollView.RemoveAllButtons();
		ClientController clientController = ClientController.Instance;
		foreach (KeyValuePair<uint, Lobby> lobby in clientController.ClientLobbyManager.Lobbies)
		{
			MPPlayer mPPlayer = clientController.Players[lobby.Value.LobbyState.HostId];
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton($"[{lobby.Value.LobbyState.Players.Count}] {GamemodeFactory.GetGamemodeName(lobby.Value.LobbyState.Gamemode)} - {MPUtility.GetPlayerDisplayName(mPPlayer.ClientState)}");
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				clientController.ClientLobbyManager.JoinLobby(lobby.Key);
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
		}
	}
}
public class AppMultiplayer : CustomApp
{
	private PhoneButton _createLobbyButton;

	private PhoneButton _lobbyButton;

	private bool _waitingForLobbyCreateResponse;

	public static void Initialize()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		byte[] array = File.ReadAllBytes(Path.Combine(MPSettings.Instance.Directory, "acn_icon.png"));
		Texture2D val = new Texture2D(1, 1);
		ImageConversion.LoadImage(val, array);
		((Texture)val).wrapMode = (TextureWrapMode)1;
		Sprite val2 = TextureUtility.CreateSpriteFromTexture(val);
		PhoneAPI.RegisterApp<AppMultiplayer>("multiplayer", val2);
	}

	public override void OnAppInit()
	{
		((CustomApp)this).OnAppInit();
		((CustomApp)this).CreateIconlessTitleBar("Multiplayer", 70f);
		base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
		PopulateButtons();
	}

	public override void OnAppUpdate()
	{
		((App)this).OnAppUpdate();
		ClientController instance = ClientController.Instance;
		if (!instance.Connected)
		{
			_waitingForLobbyCreateResponse = false;
			ClientController.PacketReceived = (Action<Packets, Packet>)Delegate.Remove(ClientController.PacketReceived, new Action<Packets, Packet>(OnPacketReceived_LobbyCreation));
		}
		if (instance.ClientLobbyManager.CurrentLobby != null)
		{
			if ((Object)(object)_lobbyButton == (Object)null)
			{
				MakeLobbyButton();
			}
			if ((Object)(object)_createLobbyButton != (Object)null)
			{
				base.ScrollView.RemoveButton(_createLobbyButton);
				_createLobbyButton = null;
			}
		}
		else
		{
			if ((Object)(object)_createLobbyButton == (Object)null)
			{
				MakeCreateLobbyButton();
			}
			if ((Object)(object)_lobbyButton != (Object)null)
			{
				base.ScrollView.RemoveButton(_lobbyButton);
				_lobbyButton = null;
			}
		}
	}

	private void MakeCreateLobbyButton()
	{
		ClientLobbyManager lobbyManager = ClientController.Instance.ClientLobbyManager;
		_createLobbyButton = (PhoneButton)(object)PhoneUIUtility.CreateSimpleButton("Create Lobby");
		PhoneButton createLobbyButton = _createLobbyButton;
		createLobbyButton.OnConfirm = (Action)Delegate.Combine(createLobbyButton.OnConfirm, (Action)delegate
		{
			if (!_waitingForLobbyCreateResponse)
			{
				GamemodeSettings gamemodeSettings = GamemodeFactory.GetGamemodeSettings((GamemodeIDs)0);
				SavedGamemodeSettings savedSettings = MPSaveData.Instance.GetSavedSettings((GamemodeIDs)0);
				if (savedSettings != null)
				{
					gamemodeSettings.ApplySaved(savedSettings);
				}
				lobbyManager.CreateLobby((GamemodeIDs)0, gamemodeSettings);
				_waitingForLobbyCreateResponse = true;
				ClientController.PacketReceived = (Action<Packets, Packet>)Delegate.Combine(ClientController.PacketReceived, new Action<Packets, Packet>(OnPacketReceived_LobbyCreation));
			}
		});
		base.ScrollView.InsertButton(0, _createLobbyButton);
	}

	private void OnPacketReceived_LobbyCreation(Packets packetId, Packet packet)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		if ((int)packetId == 14)
		{
			_waitingForLobbyCreateResponse = false;
			ClientController.PacketReceived = (Action<Packets, Packet>)Delegate.Remove(ClientController.PacketReceived, new Action<Packets, Packet>(OnPacketReceived_LobbyCreation));
			((App)this).MyPhone.OpenApp(typeof(AppMultiplayerCurrentLobby));
		}
	}

	private void MakeLobbyButton()
	{
		_lobbyButton = (PhoneButton)(object)PhoneUIUtility.CreateSimpleButton("Lobby");
		PhoneButton lobbyButton = _lobbyButton;
		lobbyButton.OnConfirm = (Action)Delegate.Combine(lobbyButton.OnConfirm, (Action)delegate
		{
			((App)this).MyPhone.OpenApp(typeof(AppMultiplayerCurrentLobby));
		});
		base.ScrollView.InsertButton(0, _lobbyButton);
	}

	private void PopulateButtons()
	{
		base.ScrollView.RemoveAllButtons();
		SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Invites");
		SimplePhoneButton obj = val;
		((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
		{
			((App)this).MyPhone.OpenApp(typeof(AppMultiplayerInvites));
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Stages");
		SimplePhoneButton obj2 = val;
		((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
		{
			if (MapStationSupport.Stages.Count > 0)
			{
				((App)this).MyPhone.OpenApp(typeof(AppMultiplayerStages));
			}
			else
			{
				((App)this).MyPhone.OpenApp(typeof(AppMultiplayerBaseStages));
			}
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Spectate");
		SimplePhoneButton obj3 = val;
		((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate
		{
			SpectatorController.StartSpectating();
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Go AFK");
		SimplePhoneButton obj4 = val;
		((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate
		{
			PlayerComponent.Get(((App)this).MyPhone.player).ForceAFK();
			((App)this).MyPhone.TurnOff(true);
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Stop AFK");
		SimplePhoneButton obj5 = val;
		((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate
		{
			PlayerComponent.Get(((App)this).MyPhone.player).StopAFK();
			((App)this).MyPhone.TurnOff(true);
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Movestyle");
		SimplePhoneButton obj6 = val;
		((PhoneButton)obj6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj6).OnConfirm, (Action)delegate
		{
			((App)this).MyPhone.OpenApp(typeof(MoveStylePickerApp));
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
	}
}
public class AppMultiplayerBaseStages : StageListApp
{
	private static bool LastSortedByPlayerCount = false;

	private static Dictionary<string, Stage> StageMap = new Dictionary<string, Stage>
	{
		{
			"Hideout",
			(Stage)5
		},
		{
			"Versum Hill",
			(Stage)4
		},
		{
			"Millenium Square",
			(Stage)11
		},
		{
			"Brink Terminal",
			(Stage)12
		},
		{
			"Millenium Mall",
			(Stage)6
		},
		{
			"Mataan",
			(Stage)7
		},
		{
			"Pyramid Island",
			(Stage)9
		},
		{
			"Police Station",
			(Stage)8
		}
	};

	public override bool Available => false;

	public static void Initialize()
	{
		PhoneAPI.RegisterApp<AppMultiplayerBaseStages>("base stages", (Sprite)null);
	}

	public override void OnAppInit()
	{
		((CustomApp)this).OnAppInit();
		((CustomApp)this).CreateIconlessTitleBar("Base Stages", 70f);
		((CustomApp)this).ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
	}

	public override void OnAppEnable()
	{
		((App)this).OnAppEnable();
		PopulateButtons(LastSortedByPlayerCount);
	}

	private void PopulateButtons(bool sortByPlayerCount = false)
	{
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		LastSortedByPlayerCount = sortByPlayerCount;
		((CustomApp)this).ScrollView.RemoveAllButtons();
		SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Sort: Player Count");
		SimplePhoneButton obj = val;
		((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
		{
			PopulateButtons(sortByPlayerCount: true);
		});
		((CustomApp)this).ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Sort: Default");
		SimplePhoneButton obj2 = val;
		((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
		{
			PopulateButtons();
		});
		((CustomApp)this).ScrollView.AddButton((PhoneButton)(object)val);
		Dictionary<string, Stage> dictionary = new Dictionary<string, Stage>(StageMap);
		if (sortByPlayerCount)
		{
			dictionary = StageMap.OrderByDescending((KeyValuePair<string, Stage> x) => base.ClientController.GetPlayerCountForStage(x.Value)).ToDictionary((KeyValuePair<string, Stage> x) => x.Key, (KeyValuePair<string, Stage> x) => x.Value);
		}
		foreach (KeyValuePair<string, Stage> item in dictionary)
		{
			CreateStageButton(item.Key, item.Value);
		}
	}
}
public class AppMultiplayerCustomStages : StageListApp
{
	private static bool LastSortedByPlayerCount;

	public override bool Available => false;

	public static void Initialize()
	{
		PhoneAPI.RegisterApp<AppMultiplayerCustomStages>("custom stages", (Sprite)null);
	}

	public override void OnAppInit()
	{
		((CustomApp)this).OnAppInit();
		((CustomApp)this).CreateIconlessTitleBar("Custom Stages", 70f);
		((CustomApp)this).ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
		PopulateButtons(LastSortedByPlayerCount);
	}

	private void PopulateButtons(bool sortByPlayerCount = false)
	{
		LastSortedByPlayerCount = sortByPlayerCount;
		((CustomApp)this).ScrollView.RemoveAllButtons();
		SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Sort: Player Count");
		SimplePhoneButton obj = val;
		((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
		{
			PopulateButtons(sortByPlayerCount: true);
		});
		((CustomApp)this).ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Sort: Alphabetically");
		SimplePhoneButton obj2 = val;
		((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
		{
			PopulateButtons();
		});
		((CustomApp)this).ScrollView.AddButton((PhoneButton)(object)val);
		List<MPStage> source = new List<MPStage>(MapStationSupport.Stages);
		source = source.OrderBy((MPStage x) => x.DisplayName).ToList();
		if (sortByPlayerCount)
		{
			source = source.OrderByDescending((MPStage x) => base.ClientController.GetPlayerCountForStage((Stage)x.Id)).ToList();
		}
		foreach (MPStage item in source)
		{
			CreateStageButton(item.DisplayName, (Stage)item.Id);
		}
	}
}
public class AppMultiplayerDebug : CustomApp
{
	public override bool Available => false;

	public static void Initialize()
	{
		PhoneAPI.RegisterApp<AppMultiplayerDebug>("multiplayer debug", (Sprite)null);
	}

	public override void OnAppInit()
	{
		((CustomApp)this).OnAppInit();
		((CustomApp)this).CreateIconlessTitleBar("Debug", 80f);
		base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
		PopulateButtons();
	}

	private void PopulateButtons()
	{
		base.ScrollView.RemoveAllButtons();
		SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Join Lobby");
		SimplePhoneButton obj = val;
		((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
		{
			((App)this).MyPhone.OpenApp(typeof(AppJoinLobbyDebug));
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Forklift Skin");
		SimplePhoneButton obj2 = val;
		((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
		{
			Player currentPlayer4 = WorldHandler.instance.GetCurrentPlayer();
			SpecialSkinManager.Instance.ApplySpecialSkinToPlayer(currentPlayer4, (SpecialSkins)4);
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Sean Kingston Skin");
		SimplePhoneButton obj3 = val;
		((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate
		{
			Player currentPlayer3 = WorldHandler.instance.GetCurrentPlayer();
			SpecialSkinManager.Instance.ApplySpecialSkinToPlayer(currentPlayer3, (SpecialSkins)3);
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Cop Skin Test");
		SimplePhoneButton obj4 = val;
		((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate
		{
			Player currentPlayer2 = WorldHandler.instance.GetCurrentPlayer();
			if (Random.Range(0, 2) == 0)
			{
				SpecialSkinManager.Instance.ApplySpecialSkinToPlayer(currentPlayer2, (SpecialSkins)0);
			}
			else
			{
				SpecialSkinManager.Instance.ApplySpecialSkinToPlayer(currentPlayer2, (SpecialSkins)1);
			}
			SpecialSkinManager.Instance.ApplyRandomVariantToPlayer(currentPlayer2);
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Remove Skin");
		SimplePhoneButton obj5 = val;
		((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate
		{
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			SpecialSkinManager.Instance.RemoveSpecialSkinFromPlayer(currentPlayer);
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Enable ProSkater Mode");
		SimplePhoneButton obj6 = val;
		((PhoneButton)obj6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj6).OnConfirm, (Action)delegate
		{
			ProSkaterPlayer.Set(WorldHandler.instance.GetCurrentPlayer(), set: true);
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Disable ProSkater Mode");
		SimplePhoneButton obj7 = val;
		((PhoneButton)obj7).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj7).OnConfirm, (Action)delegate
		{
			ProSkaterPlayer.Set(WorldHandler.instance.GetCurrentPlayer(), set: false);
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
	}
}
public class AppMultiplayerStages : CustomApp
{
	public override bool Available => false;

	public static void Initialize()
	{
		PhoneAPI.RegisterApp<AppMultiplayerStages>("stages", (Sprite)null);
	}

	public override void OnAppInit()
	{
		((CustomApp)this).OnAppInit();
		((CustomApp)this).CreateIconlessTitleBar("Stages", 80f);
		base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
		PopulateButtons();
	}

	private void PopulateButtons()
	{
		base.ScrollView.RemoveAllButtons();
		SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Base Stages");
		SimplePhoneButton obj = val;
		((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
		{
			((App)this).MyPhone.OpenApp(typeof(AppMultiplayerBaseStages));
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
		val = PhoneUIUtility.CreateSimpleButton("Custom Stages");
		SimplePhoneButton obj2 = val;
		((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
		{
			((App)this).MyPhone.OpenApp(typeof(AppMultiplayerCustomStages));
		});
		base.ScrollView.AddButton((PhoneButton)(object)val);
	}
}
public abstract class StageListApp : CustomApp
{
	protected ClientController ClientController => ClientController.Instance;

	protected SimplePhoneButton CreateStageButton(string label, Stage stage)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("(0) " + label);
		((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Core.Instance.BaseModule.StageManager.ExitCurrentStage(stage, (Stage)(-1));
		});
		StageButton stageButton = ((Component)val).gameObject.AddComponent<StageButton>();
		stageButton.Stage = stage;
		stageButton.StageName = label;
		base.ScrollView.AddButton((PhoneButton)(object)val);
		return val;
	}
}
namespace BombRushMP.Plugin
{
	public static class AudioLibraryUtils
	{
		public static AudioLibrary CreateFromSpecialSkin(SpecialSkinDefinition definition)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			AudioLibrary val = new AudioLibrary();
			AudioCollection val2 = new AudioCollection();
			AudioCollection val3 = new AudioCollection();
			AudioCollection val4 = new AudioCollection();
			AudioCollection val5 = new AudioCollection();
			AudioCollection val6 = new AudioCollection();
			AudioCollection val7 = new AudioCollection();
			AudioCollection val8 = new AudioCollection();
			val2.Clips.AddRange(definition.Jump);
			val3.Clips.AddRange(definition.GetHit);
			val4.Clips.AddRange(definition.Die);
			val5.Clips.AddRange(definition.DieFall);
			val6.Clips.AddRange(definition.Combo);
			val7.Clips.AddRange(definition.BoostTrick);
			val8.Clips.AddRange(definition.Talk);
			val.Collections[(AudioClipID)489] = val2;
			val.Collections[(AudioClipID)488] = val3;
			val.Collections[(AudioClipID)484] = val4;
			val.Collections[(AudioClipID)485] = val5;
			val.Collections[(AudioClipID)487] = val6;
			val.Collections[(AudioClipID)498] = val7;
			val.Collections[(AudioClipID)486] = val8;
			return val;
		}
	}
	public class BalanceUI : MonoBehaviour
	{
		public enum Types
		{
			TypeA,
			TypeB,
			TypeC
		}

		private const float TypeARotation = 61.62f;

		private const float TypeBRotation = 90f;

		private const float TypeCRotation = 52f;

		private Types Type = Types.TypeB;

		private GameObject _grindUI;

		private Image _grindUIBG;

		private RawImage _grindUIIndicatorImage;

		private GameObject _grindUIIndicator;

		private GameObject _manualUI;

		private Image _manualUIBG;

		private RawImage _manualUIIndicatorImage;

		private GameObject _manualUIIndicator;

		public static BalanceUI Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			Transform val = ((Component)this).transform.Find("Canvas");
			_grindUI = ((Component)val.Find("Grind Balance UI")).gameObject;
			_manualUI = ((Component)val.Find("Manual Balance UI")).gameObject;
			_grindUIBG = ((Component)_grindUI.transform.Find("Image")).GetComponent<Image>();
			_grindUIIndicator = ((Component)_grindUI.transform.Find("Indicator")).gameObject;
			_grindUIIndicatorImage = _grindUIIndicator.GetComponentInChildren<RawImage>(true);
			_manualUIBG = ((Component)_manualUI.transform.Find("Image")).GetComponent<Image>();
			_manualUIIndicator = ((Component)_manualUI.transform.Find("Indicator")).gameObject;
			_manualUIIndicatorImage = _manualUIIndicator.GetComponentInChildren<RawImage>(true);
			_manualUI.SetActive(false);
			_grindUI.SetActive(false);
		}

		private void Update()
		{
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			UIManager uIManager = Core.Instance.UIManager;
			if ((Object)(object)uIManager.gameplay == (Object)null || (Object)(object)uIManager.gameplay.gameplayScreen == (Object)null)
			{
				return;
			}
			if (!((Component)uIManager.gameplay.gameplayScreen).gameObject.activeInHierarchy)
			{
				_grindUI.SetActive(false);
				_manualUI.SetActive(false);
				return;
			}
			WorldHandler instance = WorldHandler.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Player currentPlayer = instance.GetCurrentPlayer();
			if ((Object)(object)currentPlayer == (Object)null)
			{
				return;
			}
			ProSkaterPlayer proSkaterPlayer = ProSkaterPlayer.Get(currentPlayer);
			if ((Object)(object)proSkaterPlayer == (Object)null)
			{
				_grindUI.SetActive(false);
				_manualUI.SetActive(false);
				return;
			}
			float num = 61.62f;
			if (Type == Types.TypeB)
			{
				num = 90f;
			}
			else if (Type == Types.TypeC)
			{
				num = 52f;
			}
			if (!proSkaterPlayer.DidGrind)
			{
				_grindUI.SetActive(false);
			}
			else
			{
				_grindUI.SetActive(true);
				Color color = ((Graphic)_grindUIBG).color;
				color.a = 0.3f;
				if (currentPlayer.ability != null && (currentPlayer.ability is GrindAbility || currentPlayer.ability is HandplantAbility))
				{
					color.a = 1f;
				}
				((Graphic)_grindUIBG).color = color;
				((Graphic)_grindUIIndicatorImage).color = color;
				_grindUIIndicator.transform.localRotation = Quaternion.Euler(0f, 0f, (0f - proSkaterPlayer.GrindBalance.Current) * num);
			}
			if (!proSkaterPlayer.DidManual)
			{
				_manualUI.SetActive(false);
				return;
			}
			_manualUI.SetActive(true);
			Color color2 = ((Graphic)_manualUIBG).color;
			color2.a = 0.3f;
			if (proSkaterPlayer.IsOnManual())
			{
				color2.a = 1f;
			}
			((Graphic)_manualUIBG).color = color2;
			((Graphic)_manualUIIndicatorImage).color = color2;
			_manualUIIndicator.transform.localRotation = Quaternion.Euler(0f, 0f, (0f - proSkaterPlayer.ManualBalance.Current) * num);
		}

		public static void Create()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)Instance).gameObject);
			}
			MPAssets instance = MPAssets.Instance;
			GameObject val = instance.Bundle.LoadAsset<GameObject>("Balance UI");
			if (MPSettings.Instance.BalanceUIType == Types.TypeB)
			{
				val = instance.Bundle.LoadAsset<GameObject>("Balance UI B");
			}
			else if (MPSettings.Instance.BalanceUIType == Types.TypeC)
			{
				val = instance.Bundle.LoadAsset<GameObject>("Balance UI C");
			}
			GameObject obj = Object.Instantiate<GameObject>(val);
			obj.transform.SetParent(((Component)Core.Instance.UIManager).transform, false);
			obj.AddComponent<BalanceUI>().Type = MPSettings.Instance.BalanceUIType;
		}
	}
	public class ChatUI : MonoBehaviour
	{
		public enum States
		{
			None,
			Unfocused,
			Focused
		}

		private const int MaxMessages = 250;

		private Button _sendButton;

		private TMP_InputField _inputField;

		private ScrollRect _scrollRect;

		private Image _scrollRectImage;

		private Image[] _scrollBarImages;

		private GameObject _chatWindow;

		private TextMeshProUGUI _referenceText;

		private List<TextMeshProUGUI> _messages = new List<TextMeshProUGUI>();

		private const float TimeForMessagesToHide = 30f;

		private bool _messagesHidden;

		private float _messageHideTimer;

		public static ChatUI Instance { get; private set; }

		public States State { get; private set; }

		private void Awake()
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			Instance = this;
			_chatWindow = ((Component)((Component)this).transform.Find("Canvas").Find("Chat Window")).gameObject;
			_sendButton = ((Component)_chatWindow.transform.Find("Send Button")).GetComponent<Button>();
			_inputField = ((Component)_chatWindow.transform.Find("Input Field")).GetComponent<TMP_InputField>();
			_inputField.characterLimit = 256;
			_scrollRect = ((Component)_chatWindow.transform.Find("Scroll View")).GetComponent<ScrollRect>();
			_scrollBarImages = ((Component)((Component)_scrollRect).transform.Find("Scrollbar Vertical")).GetComponentsInChildren<Image>(true);
			_scrollRectImage = ((Component)_scrollRect).GetComponent<Image>();
			_referenceText = ((Component)((Transform)_scrollRect.content).Find("Text")).GetComponent<TextMeshProUGUI>();
			((Component)_referenceText).gameObject.SetActive(false);
			((UnityEvent)_sendButton.onClick).AddListener(new UnityAction(TrySendChatMessage));
			((TMP_Text)_referenceText).spriteAsset = MPAssets.Instance.Sprites;
			ClientController.PacketReceived = (Action<Packets, Packet>)Delegate.Combine(ClientController.PacketReceived, new Action<Packets, Packet>(OnPacketReceived));
			SetState(States.Unfocused);
		}

		private void OnDestroy()
		{
			ClientController.PacketReceived = (Action<Packets, Packet>)Delegate.Remove(ClientController.PacketReceived, new Action<Packets, Packet>(OnPacketReceived));
		}

		private void OnPacketReceived(Packets packetId, Packet packet)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			MPSettings instance = MPSettings.Instance;
			ClientController instance2 = ClientController.Instance;
			_ = instance2.ClientLobbyManager;
			if ((int)packetId != 27)
			{
				if ((int)packetId == 32)
				{
					HandleServerMessage((ServerChat)packet);
				}
			}
			else
			{
				if (!instance.InviteMessages)
				{
					return;
				}
				ServerLobbyInvite val = (ServerLobbyInvite)packet;
				ushort inviterId = val.InviterId;
				ushort inviteeId = val.InviteeId;
				uint lobbyId = val.LobbyId;
				if (inviteeId == instance2.LocalID)
				{
					string playerDisplayName = MPUtility.GetPlayerDisplayName(instance2.Players[inviterId].ClientState);
					string lobbyName = instance2.ClientLobbyManager.GetLobbyName(lobbyId);
					string format = "{0} Has invited you to their {1} lobby.";
					if (instance2.GetUser(inviterId).HasTag("elite"))
					{
						format = "<color=yellow>A {0} is challenging you to a {1}.</color>";
					}
					AddMessage(string.Format(format, playerDisplayName, lobbyName));
				}
			}
		}

		private void HandleServerMessage(ServerChat serverMessage)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			MPSettings instance = MPSettings.Instance;
			string message = serverMessage.Message;
			if ((int)serverMessage.MessageType == 4)
			{
				Clear();
			}
			else
			{
				if (((int)serverMessage.MessageType == 1 && !instance.LeaveJoinMessages) || ((int)serverMessage.MessageType == 3 && !instance.AFKMessages))
				{
					return;
				}
				string text = serverMessage.Author;
				if (string.IsNullOrEmpty(text))
				{
					text = "";
				}
				text = MPUtility.GetPlayerDisplayName(text);
				int[] badges = serverMessage.Badges;
				foreach (int num in badges)
				{
					text = $"<sprite={num}> {text}";
				}
				if ((int)serverMessage.MessageType == 0)
				{
					message = TMPFilter.CloseAllTags(TMPFilter.FilterTags(message, MPSettings.Instance.ChatCriteria));
					if (ProfanityFilter.TMPContainsProfanity(message))
					{
						message = ((!MPSettings.Instance.FilterProfanity) ? (message + "<sprite=37><color=red>[FILTERED]</color>") : "I said a naughty word!");
					}
					message = MPUtility.ParseMessageEmojis(message);
					message = $"{text} : {message}";
				}
				else
				{
					message = string.Format(message, text);
				}
				AddMessage(message);
			}
		}

		private void Clear()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			foreach (TextMeshProUGUI message in _messages)
			{
				Object.Destroy((Object)(object)((Component)message).gameObject);
			}
			_messages.Clear();
			LayoutRebuilder.ForceRebuildLayoutImmediate(ComponentExtensions.RectTransform((Component)(object)_scrollRect));
			_scrollRect.normalizedPosition = new Vector2(0f, 0f);
		}

		public void AddMessage(string text)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			bool flag = true;
			if (State == States.Focused && _scrollRect.normalizedPosition.y > 0.1f)
			{
				flag = false;
			}
			if (State == States.Focused && MPSettings.Instance.DontAutoScrollChatIfFocused)
			{
				flag = false;
			}
			if (MPSettings.Instance.ShowChat)
			{
				ShowMessages();
			}
			if (_messages.Count >= 250)
			{
				Object.Destroy((Object)(object)((Component)_messages[0]).gameObject);
				_messages.RemoveAt(0);
			}
			GameObject obj = Object.Instantiate<GameObject>(((Component)_referenceText).gameObject);
			obj.SetActive(true);
			obj.transform.SetParent((Transform)(object)_scrollRect.content, false);
			TextMeshProUGUI component = obj.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).text = text;
			_messages.Add(component);
			LayoutRebuilder.ForceRebuildLayoutImmediate(ComponentExtensions.RectTransform((Component)(object)_scrollRect));
			if (flag)
			{
				_scrollRect.normalizedPosition = new Vector2(0f, 0f);
			}
		}

		private bool CanOpen()
		{
			//IL_0014: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (MPUtility.AnyMenusOpen())
			{
				return false;
			}
			PlayerControllerMapIDCollection allCurrentEnabledControllerMapCategoryIDs = Core.Instance.gameInput.GetAllCurrentEnabledControllerMapCategoryIDs(0);
			if (allCurrentEnabledControllerMapCategoryIDs.controllerMapCategoryIDs.Contains(0) && allCurrentEnabledControllerMapCategoryIDs.controllerMapCategoryIDs.Contains(6))
			{
				return !Core.Instance.IsCorePaused;
			}
			return false;
		}

		public void TrySendChatMessage()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			string text = _inputField.text;
			_inputField.text = "";
			SetState(States.Unfocused);
			if (TMPFilter.IsValidChatMessage(text))
			{
				ClientController.Instance.SendPacket((Packet)new ClientChat(text), (SendModes)2, (NetChannels)4);
				if (text[0] == '/')
				{
					ProcessLocalCommand(text);
				}
			}
		}

		private void ProcessLocalCommand(string message)
		{
			string[] array = message.Substring(1).Split(new char[1] { ' ' });
			ClientLogger.Log("Processing chat command " + array[0]);
			switch (array[0])
			{
			case "hide":
				MPSettings.Instance.ShowChat = false;
				break;
			case "show":
				MPSettings.Instance.ShowChat = true;
				break;
			case "clear":
				Clear();
				break;
			}
		}

		private void LateUpdate()
		{
			if (ShouldDisplay())
			{
				_chatWindow.SetActive(true);
				switch (State)
				{
				case States.Unfocused:
					UnfocusedUpdate();
					break;
				case States.Focused:
					FocusedUpdate();
					break;
				}
			}
			else
			{
				SetState(States.Unfocused);
				_chatWindow.SetActive(false);
			}
		}

		private void HideMessages()
		{
			_messageHideTimer = 30f;
			_messagesHidden = true;
			((Component)_scrollRect).gameObject.SetActive(false);
		}

		private void ShowMessages()
		{
			_messageHideTimer = 0f;
			_messagesHidden = false;
			((Component)_scrollRect).gameObject.SetActive(true);
		}

		private void UnfocusedUpdate()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			_scrollRect.normalizedPosition = new Vector2(0f, 0f);
			_messageHideTimer += Time.deltaTime;
			if (_messageHideTimer >= 30f || !MPSettings.Instance.ShowChat)
			{
				HideMessages();
			}
			if (Input.GetKeyDown(MPSettings.Instance.ChatKey) && CanOpen())
			{
				SetState(States.Focused);
			}
		}

		private void FocusedUpdate()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			InputUtils.Override = true;
			try
			{
				_messageHideTimer = 0f;
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
				if ((Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) || Input.GetMouseButtonDown(2)) && !RectTransformUtility.RectangleContainsScreenPoint(GameObjectExtensions.RectTransform(_chatWindow), Vector2.op_Implicit(Input.mousePosition)))
				{
					SetState(States.Unfocused);
				}
				if (Input.GetKeyDown((KeyCode)279))
				{
					_scrollRect.normalizedPosition = new Vector2(0f, 0f);
				}
				if (Input.GetKeyDown((KeyCode)271) || (Input.GetKeyDown((KeyCode)13) && (Object)(object)EventSystem.current.currentSelectedGameObject == (Object)(object)((Component)_inputField).gameObject))
				{
					TrySendChatMessage();
				}
				if (Input.GetKeyDown((KeyCode)27))
				{
					SetState(States.Unfocused);
				}
			}
			finally
			{
				InputUtils.Override = false;
			}
		}

		public void SetState(States newState)
		{
			if (State != newState)
			{
				State = newState;
				switch (State)
				{
				case States.Unfocused:
					EnterUnfocusedState();
					break;
				case States.Focused:
					EnterFocusedState();
					break;
				}
			}
		}

		private void EnterUnfocusedState()
		{
			Cursor.visible = false;
			Cursor.lockState = (CursorLockMode)1;
			GameInput gameInput = Core.Instance.GameInput;
			gameInput.DisableAllControllerMaps(0);
			gameInput.EnableControllerMaps(BaseModule.IN_GAME_INPUT_MAPS, 0);
			if ((Object)(object)SpectatorController.Instance != (Object)null)
			{
				gameInput.EnableControllerMaps(BaseModule.MENU_INPUT_MAPS, 0);
			}
			((Behaviour)_scrollRectImage).enabled = false;
			((Component)_inputField).gameObject.SetActive(false);
			((Component)_sendButton).gameObject.SetActive(false);
			Image[] scrollBarImages = _scrollBarImages;
			for (int i = 0; i < scrollBarImages.Length; i++)
			{
				((Behaviour)scrollBarImages[i]).enabled = false;
			}
			EventSystem.current.SetSelectedGameObject((GameObject)null);
		}

		private void EnterFocusedState()
		{
			Core.Instance.GameInput.DisableAllControllerMaps(0);
			ShowMessages();
			((Behaviour)_scrollRectImage).enabled = true;
			((Component)_inputField).gameObject.SetActive(true);
			((Component)_sendButton).gameObject.SetActive(true);
			Image[] scrollBarImages = _scrollBarImages;
			for (int i = 0; i < scrollBarImages.Length; i++)
			{
				((Behaviour)scrollBarImages[i]).enabled = true;
			}
			((Selectable)_inputField).Select();
		}

		private bool ShouldDisplay()
		{
			UIManager uIManager = Core.Instance.UIManager;
			if ((Object)(object)uIManager == (Object)null || (Object)(object)uIManager.gameplay == (Object)null || (Object)(object)uIManager.gameplay.gameplayScreen == (Object)null)
			{
				return false;
			}
			if (!((Component)uIManager.gameplay.gameplayScreen).gameObject.activeInHierarchy && (Object)(object)SpectatorController.Instance == (Object)null)
			{
				return false;
			}
			return true;
		}

		public static void Create()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)Instance).gameObject);
			}
			GameObject obj = Object.Instantiate<GameObject>(MPAssets.Instance.Bundle.LoadAsset<GameObject>("Chat UI"));
			obj.transform.SetParent(((Component)Core.Instance.UIManager).transform, false);
			obj.AddComponent<ChatUI>();
		}
	}
	public static class ClientConstants
	{
		public const string ChatMessage = "{0} : {1}";

		public const string LobbyChatMessage = "{0} (LOBBY) : {1}";

		public const string LobbyInviteMessage = "{0} Has invited you to their {1} lobby.";

		public const string DeathMessage = "{0} died!";

		public const int MinimumPlayersToCheer = 2;

		public const float PlayerInterpolation = 12f;

		public const float PlayerGraffitiDistance = 1f;

		public const float PlayerGraffitiDownDistance = 1f;

		public const float AFKTime = 300f;

		public const float InfrequentUpdateRate = 1f;

		public static int GrindDirectionHash = Animator.StringToHash("grindDirection");

		public static int PhoneDirectionXHash = Animator.StringToHash("phoneDirectionX");

		public static int PhoneDirectionYHash = Animator.StringToHash("phoneDirectionY");

		public static int TurnDirection1Hash = Animator.StringToHash("turnDirectionX");

		public static int TurnDirection2Hash = Animator.StringToHash("turnDirectionX2");

		public static int TurnDirection3Hash = Animator.StringToHash("turnDirectionX3");

		public static int TurnDirectionSkateboardHash = Animator.StringToHash("turnDirectionSkateboard");

		public static int MissingAnimationHash = Animator.StringToHash("softBounce17");
	}
	public class ClientController : MonoBehaviour
	{
		public Dictionary<int, int> PlayerCountByStage = new Dictionary<int, int>();

		public ClientLobbyManager ClientLobbyManager;

		public Dictionary<Player, MPPlayer> MultiplayerPlayerByPlayer = new Dictionary<Player, MPPlayer>();

		public Dictionary<ushort, MPPlayer> Players = new Dictionary<ushort, MPPlayer>();

		public ushort LocalID;

		public float TickRate = 1f / 32f;

		public string Address = "";

		public int Port;

		public GraffitiGame CurrentGraffitiGame;

		public static Action ServerDisconnect;

		public static Action ServerConnect;

		public static Action<ushort> PlayerDisconnected;

		public static Action<Packets, Packet> PacketReceived;

		public static Action ClientStatesUpdate;

		public string AuthKey;

		public bool InfrequentClientStateUpdateQueued;

		public ServerState ServerState = new ServerState();

		private PlayerComponent _cachedPlayerComponent;

		private INetClient _client;

		private float _tickTimer;

		private float _infrequentUpdateTimer;

		private bool _handShook;

		private MPSettings _mpSettings;

		private List<Plane[]> _frustumList = new List<Plane[]>();

		public static float DeltaTime { get; private set; }

		public static ClientController Instance { get; private set; }

		public bool Connected
		{
			get
			{
				if (_client != null && _client.IsConnected)
				{
					return _handShook;
				}
				return false;
			}
		}

		public PlayerComponent LocalPlayerComponent
		{
			get
			{
				if ((Object)(object)_cachedPlayerComponent == (Object)null)
				{
					_cachedPlayerComponent = PlayerComponent.Get(WorldHandler.instance.GetCurrentPlayer());
				}
				return _cachedPlayerComponent;
			}
		}

		private INetworkingInterface NetworkingInterface => NetworkingEnvironment.NetworkingInterface;

		private void Awake()
		{
			Instance = this;
			_mpSettings = MPSettings.Instance;
			ClientLobbyManager = new ClientLobbyManager();
			ClientLobbyManager.LobbiesUpdated = (Action)Delegate.Combine(ClientLobbyManager.LobbiesUpdated, new Action(OnLobbiesUpdated));
			MPPlayer.OptimizationActions.Clear();
		}

		public int GetPlayerCountForStage(Stage stage)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected I4, but got Unknown
			if (PlayerCountByStage.TryGetValue((int)stage, out var value))
			{
				return value;
			}
			return 0;
		}

		public AuthUser GetUser(ushort playerId)
		{
			if (Players.TryGetValue(playerId, out var value) && value.ClientState != null)
			{
				return value.ClientState.User;
			}
			return null;
		}

		public AuthUser GetLocalUser()
		{
			return GetUser(LocalID);
		}

		public void Connect()
		{
			ClientLogger.Log($"Connecting to {Address}:{Port}");
			_client = NetworkingInterface.CreateClient();
			Task.Run(delegate
			{
				_client.Connect(Address, Port);
			});
			INetClient client = _client;
			client.Connected = (EventHandler)Delegate.Combine(client.Connected, new EventHandler(OnConnected));
			INetClient client2 = _client;
			client2.Disconnected = (EventHandler<DisconnectedEventArgs>)Delegate.Combine(client2.Disconnected, new EventHandler<DisconnectedEventArgs>(OnDisconnect));
			INetClient client3 = _client;
			client3.ConnectionFailed = (EventHandler<ConnectionFailedEventArgs>)Delegate.Combine(client3.ConnectionFailed, new EventHandler<ConnectionFailedEventArgs>(OnConnectionFailed));
			INetClient client4 = _client;
			client4.MessageReceived = (EventHandler<MessageReceivedEventArgs>)Delegate.Combine(client4.MessageReceived, new EventHandler<MessageReceivedEventArgs>(OnMessageReceived));
			ServerConnect?.Invoke();
		}

		public void Disconnect()
		{
			foreach (KeyValuePair<ushort, MPPlayer> player in Players)
			{
				player.Value.Delete();
			}
			Players.Clear();
			_handShook = false;
			LocalID = 0;
			if (_client != null)
			{
				INetClient client = _client;
				client.Connected = (EventHandler)Delegate.Remove(client.Connected, new EventHandler(OnConnected));
				INetClient client2 = _client;
				client2.Disconnected = (EventHandler<DisconnectedEventArgs>)Delegate.Remove(client2.Disconnected, new EventHandler<DisconnectedEventArgs>(OnDisconnect));
				INetClient client3 = _client;
				client3.ConnectionFailed = (EventHandler<ConnectionFailedEventArgs>)Delegate.Remove(client3.ConnectionFailed, new EventHandler<ConnectionFailedEventArgs>(OnConnectionFailed));
				INetClient client4 = _client;
				client4.MessageReceived = (EventHandler<MessageReceivedEventArgs>)Delegate.Remove(client4.MessageReceived, new EventHandler<MessageReceivedEventArgs>(OnMessageReceived));
				_client.Disconnect();
			}
			_client = null;
			ServerDisconnect?.Invoke();
		}

		public void SendGenericEvent(GenericEvents ev, SendModes sendMode)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			SendPacket((Packet)new PlayerGenericEvent(ev), sendMode, (NetChannels)0);
		}

		public void SendPacket(Packet packet, SendModes sendMode, NetChannels channel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			IMessage val = PacketFactory.MessageFromPacket(packet, sendMode, channel);
			_client.Send(val);
		}

		public static ClientController Create(string address, int port)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			ClientController clientController = new GameObject("Client Controller").AddComponent<ClientController>();
			clientController.Address = address;
			clientController.Port = port;
			clientController.Connect();
			return clientController;
		}

		private ClientVisualState CreateVisualStatePacket(Player player)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected I4, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected I4, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Invalid comparison between Unknown and I4
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Invalid comparison between Unknown and I4
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			PlayerStates val = (PlayerStates)0;
			if ((Object)(object)CurrentGraffitiGame != (Object)null)
			{
				val = (PlayerStates)1;
			}
			PublicToilet currentToilet = MPUtility.GetCurrentToilet();
			if ((Object)(object)currentToilet != (Object)null)
			{
				val = (PlayerStates)2;
			}
			if (player.IsDead())
			{
				val = (PlayerStates)3;
			}
			PlayerComponent localPlayerComponent = LocalPlayerComponent;
			ClientVisualState val2 = new ClientVisualState();
			val2.State = val;
			val2.AFK = localPlayerComponent.AFK;
			val2.MoveStyleSkin = (byte)Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(player.character).moveStyleSkin;
			val2.MoveStyle = (int)player.moveStyleEquipped;
			val2.Chibi = localPlayerComponent.Chibi;
			MPSaveData.MPCharacterData characterData = MPSaveData.Instance.GetCharacterData(player.character);
			if (characterData != null)
			{
				val2.MPMoveStyleSkin = characterData.MPMoveStyleSkin;
			}
			switch ((int)val)
			{
			case 0:
			case 3:
			{
				val2.MoveStyleEquipped = player.usingEquippedMovestyle;
				val2.Position = ((Component)player).gameObject.transform.position.ToSystemVector3();
				val2.VisualPosition = player.visualTf.localPosition.ToSystemVector3();
				val2.Rotation = ((Component)player).gameObject.transform.rotation.ToSystemQuaternion();
				val2.VisualRotation = player.visualTf.localRotation.ToSystemQuaternion();
				val2.Velocity = player.motor._rigidbody.velocity.ToSystemVector3();
				val2.GrindDirection = player.anim.GetFloat(ClientConstants.GrindDirectionHash);
				val2.SprayCanHeld = (int)player.spraycanState == 1 || (int)player.spraycanState == 2;
				val2.PhoneHeld = player.characterVisual.phoneActive;
				val2.PhoneDirectionX = player.anim.GetFloat(ClientConstants.PhoneDirectionXHash);
				val2.PhoneDirectionY = player.anim.GetFloat(ClientConstants.PhoneDirectionYHash);
				val2.TurnDirection1 = player.anim.GetFloat(ClientConstants.TurnDirection1Hash);
				val2.TurnDirection2 = player.anim.GetFloat(ClientConstants.TurnDirection2Hash);
				val2.TurnDirection3 = player.anim.GetFloat(ClientConstants.TurnDirection3Hash);
				val2.TurnDirectionSkateboard = player.anim.GetFloat(ClientConstants.TurnDirectionSkateboardHash);
				val2.BoostpackEffectMode = (byte)player.characterVisual.boostpackEffectMode;
				val2.FrictionEffectMode = (byte)player.characterVisual.frictionEffectMode;
				if ((Object)(object)player.characterVisual.dustParticles != (Object)null)
				{
					EmissionModule emission = player.characterVisual.dustParticles.emission;
					MinMaxCurve rateOverTime = ((EmissionModule)(ref emission)).rateOverTime;
					val2.DustEmissionRate = (byte)((MinMaxCurve)(ref rateOverTime)).constant;
				}
				val2.CurrentAnimation = player.curAnim;
				val2.CurrentAnimationTime = player.curAnimActiveTime;
				val2.Hitbox = player.hitbox.activeSelf;
				val2.HitboxLeftLeg = player.hitboxLeftLeg.activeSelf;
				val2.HitboxRightLeg = player.hitboxRightLeg.activeSelf;
				val2.HitboxUpperBody = player.hitboxUpperBody.activeSelf;
				val2.HitboxAerial = player.airialHitbox.activeSelf;
				val2.HitboxRadial = player.radialHitbox.activeSelf;
				val2.HitboxSpray = player.sprayHitbox.activeSelf;
				int currentAnimation = default(int);
				if (BunchOfEmotesSupport.TryGetCustomAnimationHashByGameAnimation(val2.CurrentAnimation, ref currentAnimation))
				{
					val2.BoEAnimation = true;
					val2.CurrentAnimation = currentAnimation;
				}
				break;
			}
			case 1:
			{
				Quaternion quaternion = Quaternion.LookRotation(-((Component)CurrentGraffitiGame.gSpot).transform.forward, Vector3.up);
				val2.Position = (((Component)CurrentGraffitiGame.gSpot).transform.position + ((Component)CurrentGraffitiGame.gSpot).transform.forward * 1f + -((Component)CurrentGraffitiGame.gSpot).transform.up * 1f).ToSystemVector3();
				val2.Rotation = quaternion.ToSystemQuaternion();
				val2.BoostpackEffectMode = (byte)CurrentGraffitiGame.characterPuppet.boostpackEffectMode;
				break;
			}
			case 2:
				val2.Position = (((Component)currentToilet).transform.position + Vector3.up * 0.2f - ((Component)currentToilet).transform.forward * 0.2f).ToSystemVector3();
				val2.Rotation = (((Component)currentToilet).transform.rotation * Quaternion.Euler(0f, 180f, 0f)).ToSystemQuaternion();
				val2.CurrentAnimation = Animator.StringToHash("idle");
				break;
			}
			return val2;
		}

		private void SendVisualState()
		{
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			if (!((Object)(object)currentPlayer == (Object)null))
			{
				ClientVisualState packet = CreateVisualStatePacket(currentPlayer);
				SendPacket((Packet)(object)packet, (SendModes)0, (NetChannels)3);
			}
		}

		private void Tick()
		{
			INetClient client = _client;
			if (client != null)
			{
				client.Update();
			}
			if (Connected)
			{
				SendVisualState();
			}
			foreach (KeyValuePair<ushort, MPPlayer> player in Players)
			{
				player.Value.TickUpdate();
			}
			ClientLobbyManager.OnTick();
		}

		private void OnLobbiesUpdated()
		{
			foreach (KeyValuePair<ushort, MPPlayer> player in Players)
			{
				player.Value.UpdateLobby();
				player.Value.UpdateNameplate();
			}
		}

		private void Update()
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			MPSettings instance = MPSettings.Instance;
			bool flag = (Object)(object)MPUtility.GetCurrentToilet() != (Object)null;
			_tickTimer += Time.deltaTime;
			_infrequentUpdateTimer += Time.deltaTime;
			if (_tickTimer >= TickRate)
			{
				DeltaTime = _tickTimer;
				Tick();
				_tickTimer = 0f;
			}
			if (_infrequentUpdateTimer >= 1f)
			{
				InfrequentUpdate();
				_infrequentUpdateTimer = 0f;
			}
			_frustumList.Clear();
			WorldHandler instance2 = WorldHandler.instance;
			bool hidePlayersOutOfView = instance.HidePlayersOutOfView;
			_ = instance.PlayerDrawDistance;
			if (hidePlayersOutOfView)
			{
				Camera currentCamera = instance2.CurrentCamera;
				_frustumList.Add(GeometryUtility.CalculateFrustumPlanes(currentCamera));
				PlayerPhoneCameras instance3 = PlayerPhoneCameras.Instance;
				if ((Object)(object)instance3 != (Object)null && ((Behaviour)instance3).isActiveAndEnabled)
				{
					foreach (KeyValuePair<PhoneCam, Camera> camera in instance3.Cameras)
					{
						if (((Behaviour)camera.Value).enabled)
						{
							_frustumList.Add(GeometryUtility.CalculateFrustumPlanes(camera.Value));
						}
					}
				}
			}
			Vector3 position = ((Component)instance2.currentCamera).transform.position;
			List<StageChunk> stageChunks = null;
			if (instance.HidePlayersInInactiveChunks)
			{
				stageChunks = instance2.SceneObjectsRegister.stageChunks;
			}
			foreach (KeyValuePair<ushort, MPPlayer> player in Players)
			{
				bool flag2 = flag;
				Vector3 val;
				if (hidePlayersOutOfView && !flag)
				{
					if ((Object)(object)player.Value.Player != (Object)null)
					{
						val = ((Component)player.Value.Player).transform.position - position;
						if (((Vector3)(ref val)).sqrMagnitude >= instance.PlayerDrawDistance)
						{
							flag2 = true;
							goto IL_01dc;
						}
					}
					if (!player.Value.CalculateVisibility(_frustumList, stageChunks))
					{
						flag2 = true;
					}
				}
				goto IL_01dc;
				IL_01dc:
				bool lod = false;
				if (!flag2 && (Object)(object)player.Value.Player != (Object)null && instance.PlayerLodEnabled)
				{
					val = ((Component)player.Value.Player).transform.position - position;
					if (((Vector3)(ref val)).sqrMagnitude >= instance.PlayerLodDistance)
					{
						lod = true;
					}
				}
				player.Value.FrameUpdate(flag2, lod);
			}
			if (MPPlayer.OptimizationActions.Count > 0)
			{
				Action action = MPPlayer.OptimizationActions[0];
				MPPlayer.OptimizationActions.RemoveAt(0);
				action?.Invoke();
			}
			ClientLobbyManager.OnUpdate();
		}

		private void InfrequentUpdate()
		{
			if (InfrequentClientStateUpdateQueued)
			{
				SendClientState();
			}
		}

		private void OnClientDisconnected(object sender, ushort id)
		{
			if (Players.TryGetValue(id, out var value))
			{
				value.Delete();
				Players.Remove(id);
			}
			PlayerDisconnected?.Invoke(id);
		}

		private void ExecuteGenericEvent(GenericEvents ev, MPPlayer player)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected I4, but got Unknown
			//IL_003e: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			switch ((int)ev)
			{
			case 0:
				if (!((Object)(object)player.Player == (Object)null))
				{
					player.Player.characterVisual.SetSpraycan(true, player.Player.character);
					player.Player.SetSpraycanState((SpraycanState)3);
				}
				break;
			case 1:
				player.Teleporting = true;
				break;
			case 2:
				if (!((Object)(object)player.Player == (Object)null))
				{
					player.Player.RemoveGraffitiSlash();
				}
				break;
			case 3:
				if (player.ClientState != null && MPSettings.Instance.DeathMessages)
				{
					ChatUI.Instance.AddMessage($"{MPUtility.GetPlayerDisplayName(player.ClientState)} died!");
				}
				break;
			case 4:
				if (!((Object)(object)player.Player == (Object)null))
				{
					player.Player.AudioManager.PlaySfxGameplay(player.Player.moveStyle, (AudioClipID)255, player.Player.playerOneShotAudioSource, 0f);
					player.Player.CreateCircleDustEffect(-((Component)player.Player).transform.up);
				}
				break;
			}
		}

		private void OnMessageReceived(object sender, MessageReceivedEventArgs e)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Invalid comparison between Unknown and I4
			//IL_002f: 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_005b: Expected I4, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Expected O, but got Unknown
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Expected O, but got Unknown
			//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ea: Expected O, but got Unknown
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Expected O, but got Unknown
			//IL_055a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0561: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected I4, but got Unknown
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Expected O, but got Unknown
			//IL_0606: Unknown result type (might be due to invalid IL or missing references)
			//IL_0614: Unknown result type (might be due to invalid IL or missing references)
			//IL_061b: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Invalid comparison between Unknown and I4
			//IL_06bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c4: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Invalid comparison between Unknown and I4
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_063a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0641: Expected O, but got Unknown
			Packets val = (Packets)e.MessageId;
			Packet val2 = PacketFactory.PacketFromMessage(val, e.Message);
			if (val2 == null)
			{
				return;
			}
			PacketReceived?.Invoke(val, val2);
			if ((int)val <= 35)
			{
				switch (val - 1)
				{
				case 0:
				{
					ServerConnectionResponse val8 = (ServerConnectionResponse)val2;
					LocalID = val8.LocalClientId;
					TickRate = val8.TickRate;
					ServerState = val8.ServerState;
					PlayerAnimation.ClientSendMode = val8.ClientAnimationSendMode;
					_handShook = true;
					ClientLogger.Log($"Received server handshake - our local ID is {val8.LocalClientId}, our UserKind is {val8.User.UserKind}.");
					if (val8.User.HasTag("elite"))
					{
						Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
						currentPlayer.SetCurrentMoveStyleEquipped((MoveStyle)2, true, true);
						SaveManager saveManager = Core.Instance.SaveManager;
						MPSkateboardSkin mPSkateboardSkin = MPUnlockManager.Instance.UnlockByID[Animator.StringToHash("goonieskateboard")] as MPSkateboardSkin;
						saveManager.CurrentSaveSlot.GetCharacterProgress(currentPlayer.character).moveStyleSkin = 0;
						saveManager.CurrentSaveSlot.GetCharacterProgress(currentPlayer.character).moveStyle = (MoveStyle)2;
						MPSaveData.Instance.GetCharacterData(currentPlayer.character).MPMoveStyleSkin = mPSkateboardSkin.Identifier;
						mPSkateboardSkin.ApplyToPlayer(currentPlayer);
						saveManager.SaveCurrentSaveSlot();
						SpecialSkinManager.Instance.ApplySpecialSkinToPlayer(currentPlayer, (SpecialSkins)2);
					}
					return;
				}
				case 1:
				{
					ServerClientStates val5 = (ServerClientStates)val2;
					foreach (KeyValuePair<ushort, ClientState> clientState in val5.ClientStates)
					{
						if (!Players.TryGetValue(clientState.Key, out var value4))
						{
							value4 = new MPPlayer();
							Players[clientState.Key] = value4;
						}
						value4.SetClientState(clientState.Value);
						value4.ClientId = clientState.Key;
						value4.UpdateClientStateVisuals();
						value4.UpdateNameplate();
					}
					if (val5.Full)
					{
						foreach (MPPlayer item in new List<MPPlayer>(Players.Values))
						{
							if (!val5.ClientStates.ContainsKey(item.ClientId))
							{
								OnClientDisconnected(this, item.ClientId);
							}
						}
					}
					ClientStatesUpdate?.Invoke();
					return;
				}
				case 3:
				{
					foreach (KeyValuePair<ushort, ClientVisualState> clientVisualState2 in ((ServerClientVisualStates)val2).ClientVisualStates)
					{
						if (Players.TryGetValue(clientVisualState2.Key, out var value2))
						{
							ClientVisualState clientVisualState = value2.ClientVisualState;
							value2.UpdateVisualState(clientVisualState2.Value);
							if (clientVisualState == null)
							{
								value2.UpdateClientStateVisuals();
							}
						}
					}
					return;
				}
				case 4:
				{
					PlayerAnimation val7 = (PlayerAnimation)val2;
					if (Players.TryGetValue(((PlayerPacket)val7).ClientId, out var value6) && (Object)(object)value6.Player != (Object)null)
					{
						int num = val7.NewAnim;
						if (val7.BoE)
						{
							int num2 = default(int);
							num = ((!BunchOfEmotesSupport.TryGetGameAnimationForCustomAnimationHash(num, ref num2)) ? ClientConstants.MissingAnimationHash : num2);
						}
						MPUtility.PlayAnimationOnMultiplayerPlayer(value6.Player, num, val7.ForceOverwrite, val7.Instant, val7.AtTime);
					}
					return;
				}
				case 5:
					if (MPSettings.Instance.PlayerAudioEnabled)
					{
						PlayerVoice val9 = (PlayerVoice)val2;
						if (Players.TryGetValue(((PlayerPacket)val9).ClientId, out var value7) && (Object)(object)value7.Player != (Object)null)
						{
							value7.Player.PlayVoice((AudioClipID)val9.AudioClipId, (VoicePriority)val9.VoicePriority, true);
						}
					}
					return;
				case 7:
				{
					PlayerGraffitiSlash val6 = (PlayerGraffitiSlash)val2;
					if (Players.TryGetValue(((PlayerPacket)val6).ClientId, out var value5) && (Object)(object)value5.Player != (Object)null)
					{
						value5.Player.RemoveGraffitiSlash();
						value5.Player.CreateGraffitiSlashEffect(((Component)value5.Player).transform, val6.Direction.ToUnityVector3());
						value5.Player.AudioManager.PlaySfxGameplay((SfxCollectionID)13, (AudioClipID)10, value5.Player.playerOneShotAudioSource, 0f);
					}
					return;
				}
				case 8:
				{
					PlayerGraffitiFinisher val4 = (PlayerGraffitiFinisher)val2;
					if (Players.TryGetValue(((PlayerPacket)val4).ClientId, out var value3) && (Object)(object)value3.Player != (Object)null)
					{
						value3.Player.RemoveGraffitiSlash();
						value3.Player.CreateGraffitiFinishEffect(((Component)value3.Player).transform, (GraffitiSize)val4.GraffitiSize);
						value3.Player.AudioManager.PlaySfxGameplay((SfxCollectionID)13, (AudioClipID)559, value3.Player.playerOneShotAudioSource, 0f);
					}
					return;
				}
				case 6:
				{
					PlayerGenericEvent val3 = (PlayerGenericEvent)val2;
					if (Players.TryGetValue(((PlayerPacket)val3).ClientId, out var value))
					{
						ExecuteGenericEvent(val3.Event, value);
					}
					return;
				}
				case 2:
					return;
				}
				if ((int)val != 24)
				{
					if ((int)val == 35 && GetLocalUser().IsModerator)
					{
						ServerBanList val10 = (ServerBanList)val2;
						string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "ACN");
						string text2 = Path.Combine(text, "banned_users.json");
						ChatUI instance = ChatUI.Instance;
						ClientLogger.Log("Received ban list from server. Will write to " + text2 + ".");
						try
						{
							Directory.CreateDirectory(text);
							File.WriteAllText(text2, val10.JsonData);
							instance.AddMessage("Ban list written to " + text2);
						}
						catch (Exception ex)
						{
							instance.AddMessage("Failed to write ban list.");
							Debug.LogError((object)ex);
						}
					}
				}
				else
				{
					ServerPlayerCount val11 = (ServerPlayerCount)val2;
					PlayerCountByStage = val11.PlayerCountByStage;
				}
			}
			else if ((int)val != 39)
			{
				if ((int)val != 40)
				{
					switch (val - 48)
					{
					case 2:
					{
						ServerServerStateUpdate val14 = (ServerServerStateUpdate)(object)((val2 is ServerServerStateUpdate) ? val2 : null);
						ServerState = val14.State;
						break;
					}
					case 1:
					{
						ServerSetSpecialSkin val13 = (ServerSetSpecialSkin)(object)((val2 is ServerSetSpecialSkin) ? val2 : null);
						Player currentPlayer2 = WorldHandler.instance.GetCurrentPlayer();
						if ((int)val13.SpecialSkin == -1)
						{
							SpecialSkinManager.Instance.RemoveSpecialSkinFromPlayer(currentPlayer2);
						}
						else
						{
							SpecialSkinManager.Instance.ApplySpecialSkinToPlayer(currentPlayer2, val13.SpecialSkin);
						}
						break;
					}
					case 0:
					{
						ServerClientDisconnected val12 = (ServerClientDisconnected)val2;
						if (Players.ContainsKey(val12.ClientId))
						{
							OnClientDisconnected(this, val12.ClientId);
							ClientStatesUpdate?.Invoke();
						}
						break;
					}
					}
				}
				else
				{
					LocalPlayerComponent.Chibi = ((ServerSetChibi)((val2 is ServerSetChibi) ? val2 : null)).Set;
				}
			}
			else
			{
				ClientHitByPlayer val15 = (ClientHitByPlayer)(object)((val2 is ClientHitByPlayer) ? val2 : null);
				if (((PlayerPacket)val15).ClientId != LocalID && val15.Attacker == LocalID)
				{
					MPSaveData.Instance.Stats.PlayersHit++;
					Core.Instance.SaveManager.SaveCurrentSaveSlot();
				}
			}
		}

		private IEnumerator AttemptReconnect()
		{
			yield return (object)new WaitForSecondsRealtime(1f);
			Disconnect();
			Connect();
		}

		private void OnConnectionFailed(object sender, ConnectionFailedEventArgs e)
		{
			ClientLogger.Log("Failed to connect to server. Reason: " + e.Reason);
			ClientLogger.Log("Will attempt to re-connect");
			((MonoBehaviour)this).StopAllCoroutines();
			((MonoBehaviour)this).StartCoroutine(AttemptReconnect());
		}

		private void OnDisconnect(object sender, DisconnectedEventArgs e)
		{
			ClientLogger.Log("Disconnected! Reason: " + e.Reason);
			ClientLogger.Log("Will attempt to re-connect");
			((MonoBehaviour)this).StopAllCoroutines();
			((MonoBehaviour)this).StartCoroutine(AttemptReconnect());
		}

		public void SendAuth()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			string authKey = AuthKey;
			ClientState val = CreateClientState();
			ClientAuth val2 = new ClientAuth(authKey, val);
			val2.Invisible = MPSettings.Instance.Invisible;
			SendPacket((Packet)(object)val2, (SendModes)1, (NetChannels)0);
		}

		public ClientState CreateClientState()
		{
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0068: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected I4, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			PlayerComponent localPlayerComponent = LocalPlayerComponent;
			ClientState val = new ClientState
			{
				Name = _mpSettings.PlayerName,
				CrewName = _mpSettings.CrewName,
				Character = (sbyte)currentPlayer.character,
				FallbackCharacter = (sbyte)MPSettings.Instance.FallbackCharacter,
				FallbackOutfit = (byte)MPSettings.Instance.FallbackOutfit,
				Outfit = (byte)Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(currentPlayer.character).outfit
			};
			Scene activeScene = SceneManager.GetActiveScene();
			val.Stage = (int)Utility.SceneNameToStage(((Scene)(ref activeScene)).name);
			val.SpecialSkin = localPlayerComponent.SpecialSkin;
			val.SpecialSkinVariant = localPlayerComponent.SpecialSkinVariant;
			ClientState val2 = val;
			if (CrewBoomSupport.Installed)
			{
				val2.CrewBoomCharacter = CrewBoomSupport.GetGuidForCharacter(currentPlayer.character);
				if (localPlayerComponent.StreamedCharacterHandle != null)
				{
					val2.CrewBoomCharacter = localPlayerComponent.StreamedCharacterHandle.GUID;
					val2.Outfit = (byte)localPlayerComponent.StreamedOutfit;
				}
			}
			return val2;
		}

		public void SendClientState()
		{
			SendPacket((Packet)(object)CreateClientState(), (SendModes)1, (NetChannels)2);
			InfrequentClientStateUpdateQueued = false;
		}

		private void OnConnected(object sender, EventArgs e)
		{
			ClientLogger.Log("Connected! Sending Auth request...");
			SendAuth();
		}

		private void OnDestroy()
		{
			Disconnect();
			ClientLobbyManager.LobbiesUpdated = (Action)Delegate.Remove(ClientLobbyManager.LobbiesUpdated, new Action(OnLobbiesUpdated));
			ClientLobbyManager?.Dispose();
		}
	}
	public class ClientLobbyManager : IDisposable
	{
		public static Action LobbiesUpdated;

		public static Action LobbyChanged;

		public static Action LobbySoftUpdated;

		public Dictionary<uint, Lobby> Lobbies = new Dictionary<uint, Lobby>();

		public List<uint> LobbiesInvited = new List<uint>();

		private ClientController _clientController;

		private WorldHandler _worldHandler;

		public Lobby CurrentLobby { get; private set; }

		public ClientLobbyManager()
		{
			_clientController = ClientController.Instance;
			ClientController.PacketReceived = (Action<Packets, Packet>)Delegate.Combine(ClientController.PacketReceived, new Action<Packets, Packet>(OnPacketReceived));
			ClientController.ServerDisconnect = (Action)Delegate.Combine(ClientController.ServerDisconnect, new Action(OnDisconnect));
			_worldHandler = WorldHandler.instance;
			LobbyChanged = (Action)Delegate.Combine(LobbyChanged, new Action(HandleEncounter));
		}

		public void Dispose()
		{
			ClientController.PacketReceived = (Action<Packets, Packet>)Delegate.Remove(ClientController.PacketReceived, new Action<Packets, Packet>(OnPacketReceived));
			ClientController.ServerDisconnect = (Action)Delegate.Remove(ClientController.ServerDisconnect, new Action(OnDisconnect));
			if (CurrentLobby != null && CurrentLobby.InGame)
			{
				CurrentLobby.CurrentGamemode.OnEnd(cancelled: true);
			}
			if ((Object)(object)_worldHandler.currentEncounter != (Object)null && _worldHandler.currentEncounter is ProxyEncounter)
			{
				_worldHandler.currentEncounter.SetEncounterState((EncounterState)0);
			}
			LobbyChanged = (Action)Delegate.Remove(LobbyChanged, new Action(HandleEncounter));
		}

		private void HandleEncounter()
		{
			if (CurrentLobby == null && (Object)(object)_worldHandler.currentEncounter != (Object)null && _worldHandler.currentEncounter is ProxyEncounter)
			{
				_worldHandler.currentEncounter.SetEncounterState((EncounterState)0);
			}
			else if (CurrentLobby != null && (Object)(object)_worldHandler.currentEncounter == (Object)null)
			{
				((Encounter)ProxyEncounter.Instance).ActivateEncounter();
			}
		}

		public void OnUpdate()
		{
			if (CurrentLobby != null && CurrentLobby.InGame)
			{
				CurrentLobby.CurrentGamemode.OnUpdate_InGame();
			}
		}

		public bool CanJoinLobby()
		{
			if ((Object)(object)_worldHandler.currentEncounter != (Object)null && !(_worldHandler.currentEncounter is ProxyEncounter))
			{
				return false;
			}
			return true;
		}

		public void OnTick()
		{
			if (CurrentLobby != null && CurrentLobby.InGame)
			{
				CurrentLobby.CurrentGamemode.OnTick_InGame();
			}
		}

		public string GetLobbyName(uint lobbyId)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return GamemodeFactory.GetGamemodeName(Lobbies[lobbyId].LobbyState.Gamemode);
		}

		public void CreateLobby(GamemodeIDs gamemode, GamemodeSettings settings)
		{
			//IL_0040: 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_004e: Expected O, but got Unknown
			if (!CanJoinLobby())
			{
				return;
			}
			byte[] array;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				using BinaryWriter writer = new BinaryWriter(memoryStream);
				settings.Write(writer);
				array = memoryStream.ToArray();
			}
			_clientController.SendPacket((Packet)new ClientLobbyCreate(gamemode, array), (SendModes)2, (NetChannels)2);
		}

		public void JoinLobby(uint lobbyId)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if (CanJoinLobby())
			{
				_clientController.SendPacket((Packet)new ClientLobbyJoin(lobbyId), (SendModes)2, (NetChannels)2);
				NotificationController.Instance.RemoveNotificationForLobby(lobbyId);
			}
		}

		public void LeaveLobby()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			_clientController.SendPacket((Packet)new ClientLobbyLeave(), (SendModes)2, (NetChannels)2);
		}

		public void StartGame()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			_clientController.SendPacket((Packet)new ClientLobbyStart(), (SendModes)2, (NetChannels)2);
		}

		public void EndGame()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			_clientController.SendPacket((Packet)new ClientLobbyEnd(), (SendModes)2, (NetChannels)2);
		}

		public void SetChallenge(bool set)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			_clientController.SendPacket((Packet)new ClientLobbySetChallenge(set), (SendModes)2, (NetChannels)2);
		}

		public void SetAllowTeamSwitching(bool set)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			_clientController.SendPacket((Packet)new ClientLobbySetAllowTeamSwitching(set), (SendModes)2, (NetChannels)2);
		}

		public void SetGamemode(GamemodeIDs gamemode, GamemodeSettings settings)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			byte[] array;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				using BinaryWriter writer = new BinaryWriter(memoryStream);
				settings.Write(writer);
				array = memoryStream.ToArray();
			}
			_clientController.SendPacket((Packet)new ClientLobbySetGamemode(gamemode, array), (SendModes)2, (NetChannels)2);
		}

		public void InvitePlayer(ushort playerId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			_clientController.SendPacket((Packet)new ClientLobbyInvite(playerId), (SendModes)2, (NetChannels)2);
		}

		public void DeclineInvite(uint lobbyId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			_clientController.SendPacket((Packet)new ClientLobbyDeclineInvite(lobbyId), (SendModes)2, (NetChannels)2);
			NotificationController.Instance.RemoveNotificationForLobby(lobbyId);
		}

		public void DeclineAllInvites()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			_clientController.SendPacket((Packet)new ClientLobbyDeclineAllInvites(), (SendModes)2, (NetChannels)2);
			NotificationController.Instance.RemoveAllNotifications();
		}

		public void KickPlayer(ushort playerId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			_clientController.SendPacket((Packet)new ClientLobbyKick(playerId), (SendModes)2, (NetChannels)2);
		}

		private void OnPacketReceived(Packets packetId, Packet packet)
		{
			//IL_0027: 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_0048: Expected I4, but got Unknown
			//IL_008b: 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_0058: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			if (CurrentLobby != null && CurrentLobby.InGame)
			{
				CurrentLobby.CurrentGamemode.OnPacketReceived_InGame(packetId, packet);
			}
			switch (packetId - 13)
			{
			case 2:
			{
				ServerLobbyDeleted val2 = (ServerLobbyDeleted)packet;
				if (Lobbies.TryGetValue(val2.LobbyUID, out var value2))
				{
					Lobbies.Remove(val2.LobbyUID);
					OnLobbyDeleted(value2);
				}
				return;
			}
			case 0:
				foreach (LobbyState lobby in ((ServerLobbies)packet).Lobbies)
				{
					if (!Lobbies.TryGetValue(lobby.Id, out var value))
					{
						value = new Lobby();
						Lobbies[lobby.Id] = value;
					}
					value.LobbyState = lobby;
				}
				OnLobbiesUpdated();
				return;
			case 4:
				OnStartGame();
				return;
			case 5:
			{
				ServerLobbyEnd val = (ServerLobbyEnd)packet;
				OnEndGame(val.Cancelled);
				return;
			}
			case 1:
			case 3:
				return;
			}
			if ((int)packetId == 47)
			{
				ServerLobbySoftUpdate val3 = (ServerLobbySoftUpdate)packet;
				if (CurrentLobby == null)
				{
					UpdateCurrentLobby();
				}
				if (CurrentLobby.LobbyState.Players.TryGetValue(val3.PlayerId, out var value3))
				{
					value3.Score = val3.Score;
				}
				OnLobbySoftUpdated();
			}
		}

		private void OnDisconnect()
		{
			Lobbies.Clear();
			OnLobbiesUpdated();
		}

		private void UpdateCurrentLobby()
		{
			CurrentLobby = null;
			foreach (KeyValuePair<uint, Lobby> lobby in Lobbies)
			{
				if (lobby.Value.LobbyState.Players.Keys.Contains(_clientController.LocalID))
				{
					CurrentLobby = lobby.Value;
				}
			}
		}

		private void OnEndGame(bool cancelled)
		{
			if (CurrentLobby != null)
			{
				if (CurrentLobby.InGame)
				{
					CurrentLobby.CurrentGamemode.OnEnd(cancelled);
				}
				CurrentLobby.CurrentGamemode = null;
				CurrentLobby.LobbyState.InGame = false;
			}
		}

		private void OnStartGame()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (CurrentLobby == null)
			{
				UpdateCurrentLobby();
			}
			if (CurrentLobby.InGame)
			{
				CurrentLobby.CurrentGamemode.OnEnd(cancelled: true);
			}
			CurrentLobby.CurrentGamemode = GamemodeFactory.GetGamemode(CurrentLobby.LobbyState.Gamemode);
			CurrentLobby.CurrentGamemode.Lobby = CurrentLobby;
			CurrentLobby.LobbyState.InGame = true;
			CurrentLobby.CurrentGamemode.OnStart();
			Player currentPlayer = _worldHandler.GetCurrentPlayer();
			PhoneUtility.BackToHomescreen(currentPlayer.phone);
			currentPlayer.phone.TurnOff(false);
		}

		private void OnLobbyDeleted(Lobby lobby)
		{
			if (lobby == CurrentLobby)
			{
				CurrentLobby = null;
				if (lobby.InGame)
				{
					lobby.CurrentGamemode.OnEnd(cancelled: true);
				}
				LobbyChanged?.Invoke();
			}
			UpdateCurrentLobby();
			LobbiesUpdated?.Invoke();
		}

		private void OnLobbySoftUpdated()
		{
			LobbySoftUpdated?.Invoke();
		}

		private void OnLobbiesUpdated()
		{
			Lobby currentLobby = CurrentLobby;
			UpdateCurrentLobby();
			LobbiesInvited.Clear();
			foreach (KeyValuePair<uint, Lobby> lobby in Lobbies)
			{
				if (lobby.Value != CurrentLobby && lobby.Value.LobbyState.InvitedPlayers.Keys.Contains(_clientController.LocalID))
				{
					LobbiesInvited.Add(lobby.Key);
				}
			}
			if (currentLobby != CurrentLobby)
			{
				if (currentLobby != null && currentLobby.InGame)
				{
					currentLobby.CurrentGamemode.OnEnd(cancelled: true);
					currentLobby.CurrentGamemode = null;
				}
				LobbyChanged?.Invoke();
			}
			LobbiesUpdated?.Invoke();
		}
	}
	public static class ClientLogger
	{
		public static void Log(string message)
		{
			Debug.Log((object)("[" + DateTime.Now.ToShortTimeString() + "] " + message));
		}
	}
	public class DebugUI : MonoBehaviour
	{
		internal static DebugUI Instance;

		private TextMeshProUGUI _curAnimLabel;

		private void Awake()
		{
			Instance = this;
			Init();
		}

		private static TextMeshProUGUI MakeLabel(TextMeshProUGUI reference, string name)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			TMP_FontAsset font = ((TMP_Text)reference).font;
			float fontSize = ((TMP_Text)reference).fontSize;
			Material fontMaterial = ((TMP_Text)reference).fontMaterial;
			TextMeshProUGUI obj = new GameObject(name).AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).font = font;
			((TMP_Text)obj).fontSize = fontSize;
			((TMP_Text)obj).fontMaterial = fontMaterial;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)obj).fontStyle = (FontStyles)1;
			((TMP_Text)obj).outlineWidth = 0.2f;
			return obj;
		}

		private static TextMeshProUGUI MakeGlyph(TextMeshProUGUI reference, int actionID)
		{
			TextMeshProUGUI val = MakeLabel(reference, "");
			((Component)val).gameObject.SetActive(false);
			UIButtonGlyphComponent obj = ((Component)val).gameObject.AddComponent<UIButtonGlyphComponent>();
			obj.inputActionID = actionID;
			obj.localizedGlyphTextComponent = val;
			obj.localizedTextComponent = val;
			((Behaviour)obj).enabled = true;
			((Component)val).gameObject.SetActive(true);
			return val;
		}

		private void Init()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = ((Component)Instance).gameObject.AddComponent<RectTransform>();
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			TextMeshProUGUI[] componentsInChildren = ((Component)Core.Instance.UIManager.danceAbilityUI).GetComponentsInChildren<TextMeshProUGUI>(true);
			TextMeshProUGUI val2 = null;
			TextMeshProUGUI[] array = componentsInChildren;
			foreach (TextMeshProUGUI val3 in array)
			{
				if (((Object)((Component)((TMP_Text)val3).transform).gameObject).name == "DanceSelectConfirmText")
				{
					val2 = val3;
				}
			}
			if (!((Object)(object)val2 == (Object)null))
			{
				float num = 100f;
				float num2 = -50f;
				float num3 = 50f;
				float num4 = 75f;
				_curAnimLabel = MakeLabel(val2, "CurAnim");
				((TMP_Text)_curAnimLabel).text = "CurAnim";
				((TMP_Text)_curAnimLabel).rectTransform.anchorMin = new Vector2(0f, 0f);
				((TMP_Text)_curAnimLabel).rectTransform.anchorMax = new Vector2(1f, 1f);
				((TMP_Text)_curAnimLabel).rectTransform.pivot = new Vector2(0f, 1f);
				((TMP_Text)_curAnimLabel).rectTransform.anchoredPosition = new Vector2(num + num4, num3 + num2);
				((Transform)((TMP_Text)_curAnimLabel).rectTransform).SetParent((Transform)(object)val, false);
			}
		}

		private void Update()
		{
			if ((Object)(object)_curAnimLabel == (Object)null)
			{
				return;
			}
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				Player currentPlayer = instance.GetCurrentPlayer();
				if (!((Object)(object)currentPlayer == (Object)null))
				{
					((TMP_Text)_curAnimLabel).text = $"CurAnim: {currentPlayer.curAnim}\n";
					TextMeshProUGUI curAnimLabel = _curAnimLabel;
					((TMP_Text)curAnimLabel).text = ((TMP_Text)curAnimLabel).text + $"Players: {RenderStats.Players}\n";
					TextMeshProUGUI curAnimLabel2 = _curAnimLabel;
					((TMP_Text)curAnimLabel2).text = ((TMP_Text)curAnimLabel2).text + $"Players Rendered (High): {RenderStats.PlayersRendered}\n";
					TextMeshProUGUI curAnimLabel3 = _curAnimLabel;
					((TMP_Text)curAnimLabel3).text = ((TMP_Text)curAnimLabel3).text + $"Players Rendered (Low): {RenderStats.PlayersRenderedLOD}\n";
					TextMeshProUGUI curAnimLabel4 = _curAnimLabel;
					((TMP_Text)curAnimLabel4).text = ((TMP_Text)curAnimLabel4).text + $"Players Culled: {RenderStats.PlayersCulled}\n";
					TextMeshProUGUI curAnimLabel5 = _curAnimLabel;
					((TMP_Text)curAnimLabel5).text = ((TMP_Text)curAnimLabel5).text + $"Loaded Characters: {CrewBoomStreamer.LoadedCharacters}\n";
				}
			}
		}

		public static void Create()
		{
			//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)
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)Instance).gameObject);
			}
			GameObject val = new GameObject("Debug UI");
			val.transform.SetParent((Transform)(object)((Component)((Component)Core.Instance.UIManager.gameplay).transform.parent).GetComponent<RectTransform>(), false);
			val.AddComponent<DebugUI>();
		}
	}
	public class Emojis
	{
		public Dictionary<string, int> Sprites = new Dictionary<string, int>
		{
			{ ":car:", 25 },
			{ ":akkowot:", 24 },
			{ ":krehs:", 26 }
		};
	}
	public static class InputUtils
	{
		public static bool Override;

		public static bool InputBlocked
		{
			get
			{
				if (Override)
				{
					return false;
				}
				ChatUI instance = ChatUI.Instance;
				PlayerListUI instance2 = PlayerListUI.Instance;
				if ((Object)(object)instance2 == (Object)null)
				{
					return false;
				}
				if ((Object)(object)instance == (Object)null)
				{
					return false;
				}
				if (instance.State != ChatUI.States.Focused)
				{
					return instance2.Displaying;
				}
				return true;
			}
		}
	}
	public class Lobby
	{
		public LobbyState LobbyState;

		public Gamemode CurrentGamemode;

		public bool InGame
		{
			get
			{
				if (CurrentGamemode != null)
				{
					return CurrentGamemode.InGame;
				}
				return false;
			}
		}

		public LobbyPlayer GetHighestScoringPlayer()
		{
			LobbyPlayer val = null;
			foreach (KeyValuePair<ushort, LobbyPlayer> player in LobbyState.Players)
			{
				if (val == null || player.Value.Score > val.Score)
				{
					val = player.Value;
				}
			}
			return val;
		}

		public Gamemode GetOrCreateGamemode()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (CurrentGamemode != null)
			{
				return CurrentGamemode;
			}
			return GamemodeFactory.GetGamemode(LobbyState.Gamemode);
		}
	}
	public class LobbyPlayerUI : MonoBehaviour
	{
		private TextMeshProUGUI _playerName;

		private TextMeshProUGUI _score;

		private ClientController _clientController;

		private LobbyPlayer _lobbyPlayer;

		private Lobby _lobby;

		private GameObject _readySprite;

		private GameObject _notReadySprite;

		private GameObject _afkSprite;

		private Image _bg;

		private Image _teamBg;

		public int Position = -1;

		private const float TeamPlayerDarkening = 0.25f;

		private void Awake()
		{
			_playerName = ((Component)((Component)this).transform.Find("Label")).GetComponent<TextMeshProUGUI>();
			_score = ((Component)((Component)this).transform.Find("Score")).GetComponent<TextMeshProUGUI>();
			_readySprite = ((Component)((Component)this).transform.Find("Ready")).gameObject;
			_notReadySprite = ((Component)((Component)this).transform.Find("Not Ready")).gameObject;
			_afkSprite = ((Component)((Component)this).transform.Find("AFK")).gameObject;
			_bg = ((Component)((Component)this).transform.Find("BG")).GetComponent<Image>();
			_teamBg = ((Component)((Component)this).transform.Find("Team BG")).GetComponent<Image>();
			_clientController = ClientController.Instance;
			((TMP_Text)_playerName).spriteAsset = MPAssets.Instance.Sprites;
		}

		private void Update()
		{
			if (_lobbyPlayer == null)
			{
				return;
			}
			ClientVisualState clientVisualState = _clientController.Players[_lobbyPlayer.Id].ClientVisualState;
			if (clientVisualState != null)
			{
				_afkSprite.SetActive(clientVisualState.AFK);
				if (!_lobby.InGame)
				{
					_readySprite.SetActive(_lobbyPlayer.Ready);
					_notReadySprite.SetActive(!_lobbyPlayer.Ready);
				}
				else
				{
					_readySprite.SetActive(false);
					_notReadySprite.SetActive(false);
				}
				if (_lobby.LobbyState.HostId == _lobbyPlayer.Id)
				{
					_readySprite.SetActive(false);
					_notReadySprite.SetActive(false);
				}
			}
		}

		private string FormatScore(float score)
		{
			if (score <= 0f)
			{
				return "0";
			}
			return FormattingUtility.FormatPlayerScore(CultureInfo.CurrentCulture, score);
		}

		public void SetTeam(Lobby lobby, Team team, byte teamId, int standing)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			_lobby = lobby;
			string text = MPUtility.GetCrewDisplayName(MPUtility.GetTeamName(lobby.LobbyState, team, teamId));
			if (string.IsNullOrWhiteSpace(text))
			{
				text = team.Name;
			}
			_lobbyPlayer = null;
			((TMP_Text)_playerName).text = $"{standing}. {text}";
			((Component)_bg).gameObject.SetActive(false);
			_readySprite.SetActive(false);
			_notReadySprite.SetActive(false);
			((Component)_teamBg).gameObject.SetActive(true);
			_afkSprite.gameObject.SetActive(false);
			((Graphic)_teamBg).color = new Color(team.Color.r, team.Color.g, team.Color.b, ((Graphic)_teamBg).color.a);
			((TMP_Text)_score).text = FormatScore(_lobby.LobbyState.GetScoreForTeam(teamId));
		}

		public void SetPlayer(LobbyPlayer player, Team team)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			((Component)_bg).gameObject.SetActive(false);
			((Component)_teamBg).gameObject.SetActive(false);
			if (team == null)
			{
				((Component)_bg).gameObject.SetActive(true);
			}
			else
			{
				((Component)_teamBg).gameObject.SetActive(true);
				((Graphic)_teamBg).color = new Color(team.Color.r * 0.25f, team.Color.g * 0.25f, team.Color.b * 0.25f, ((Graphic)_teamBg).color.a);
			}
			Lobby lobby = (_lobby = _clientController.ClientLobbyManager.Lobbies[player.LobbyId]);
			string text = MPUtility.GetPlayerDisplayName(_clientController.Players[player.Id].ClientState);
			if (lobby.LobbyState.HostId == player.Id)
			{
				text = "<color=yellow>[Host]</color> " 

BombRushMP.PluginCommon.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;
using Reptile;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BombRushMP.PluginCommon")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BombRushMP.PluginCommon")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0bf3555a-fac1-41ca-beb1-e93323c1e530")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BombRushMP.PluginCommon
{
	public class AudioCollection
	{
		public List<AudioClip> Clips = new List<AudioClip>();

		private AudioClip _lastAudioClip;

		public AudioClip GetRandom()
		{
			if (Clips.Count == 0)
			{
				return null;
			}
			if (Clips.Count == 1)
			{
				return Clips[0];
			}
			List<AudioClip> list = new List<AudioClip>(Clips);
			if ((Object)(object)_lastAudioClip != (Object)null)
			{
				list.Remove(_lastAudioClip);
			}
			return _lastAudioClip = list[Random.Range(0, list.Count)];
		}
	}
	public class AudioLibrary
	{
		public Dictionary<AudioClipID, AudioCollection> Collections = new Dictionary<AudioClipID, AudioCollection>();

		public AudioClip GetRandom(AudioClipID audioClipID)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!Collections.ContainsKey(audioClipID))
			{
				return null;
			}
			return Collections[audioClipID].GetRandom();
		}
	}
}

BombRushMP.RiptideInterface.dll

Decompiled 2 hours ago
using System;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BombRushMP.Common.Networking;
using Riptide;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BombRushMP.RiptideInterface")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BombRushMP.RiptideInterface")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f0f90b2b-9b2c-45db-b794-03743a2bf1d9")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BombRushMP.RiptideInterface;

internal class RiptideClient : INetClient
{
	private Client _riptideClient;

	public bool IsConnected => _riptideClient.IsConnected;

	public EventHandler Connected { get; set; }

	public EventHandler<MessageReceivedEventArgs> MessageReceived { get; set; }

	public EventHandler<DisconnectedEventArgs> Disconnected { get; set; }

	public EventHandler<ConnectionFailedEventArgs> ConnectionFailed { get; set; }

	public RiptideClient()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		_riptideClient = new Client("CLIENT");
		_riptideClient.Connected += InternalConnected;
		_riptideClient.MessageReceived += InternalMessageReceived;
		_riptideClient.Disconnected += InternalDisconnected;
		_riptideClient.ConnectionFailed += InternalConnectionFailed;
	}

	private void InternalConnected(object sender, EventArgs args)
	{
		Connected?.Invoke(sender, args);
	}

	private void InternalConnectionFailed(object sender, ConnectionFailedEventArgs args)
	{
		//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_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		EventHandler<ConnectionFailedEventArgs> connectionFailed = ConnectionFailed;
		if (connectionFailed != null)
		{
			RejectReason reason = args.Reason;
			connectionFailed(sender, new ConnectionFailedEventArgs(((object)(RejectReason)(ref reason)).ToString()));
		}
	}

	private void InternalDisconnected(object sender, DisconnectedEventArgs args)
	{
		//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_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		DisconnectReason reason = args.Reason;
		DisconnectedEventArgs e = new DisconnectedEventArgs(((object)(DisconnectReason)(ref reason)).ToString());
		Disconnected?.Invoke(sender, e);
	}

	private void InternalMessageReceived(object sender, MessageReceivedEventArgs args)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		MessageReceivedEventArgs e = new MessageReceivedEventArgs(args.MessageId, (IMessage)(object)new RiptideMessage(args.Message), (INetConnection)(object)new RiptideConnection(args.FromConnection));
		MessageReceived?.Invoke(sender, e);
	}

	public bool Connect(string address, int port)
	{
		IPAddress[] hostAddresses = Dns.GetHostAddresses(address);
		if (hostAddresses.Length != 0)
		{
			address = hostAddresses[0].ToString();
		}
		address += $":{port}";
		return _riptideClient.Connect(address, 5, (byte)0, (Message)null, true);
	}

	public void Disconnect()
	{
		_riptideClient.Disconnect();
	}

	public void Send(IMessage message)
	{
		_riptideClient.Send((message as RiptideMessage).InternalRiptideMessage, true);
	}

	public void Update()
	{
		((Peer)_riptideClient).Update();
	}

	public override string ToString()
	{
		return ((object)_riptideClient).ToString();
	}
}
public class RiptideConnection : INetConnection
{
	private Connection _riptideConnection;

	public bool CanQualityDisconnect
	{
		get
		{
			return _riptideConnection.CanQualityDisconnect;
		}
		set
		{
			_riptideConnection.CanQualityDisconnect = value;
		}
	}

	public ushort Id => _riptideConnection.Id;

	public string Address => ((object)_riptideConnection).ToString().Split(new char[1] { ':' })[0];

	public RiptideConnection(Connection connection)
	{
		_riptideConnection = connection;
	}

	public void Send(IMessage message)
	{
		_riptideConnection.Send((message as RiptideMessage).InternalRiptideMessage, true);
	}

	public override string ToString()
	{
		return ((object)_riptideConnection).ToString();
	}
}
public class RiptideInterface : INetworkingInterface
{
	public int MaxPayloadSize
	{
		get
		{
			return Message.MaxPayloadSize;
		}
		set
		{
			Message.MaxPayloadSize = value;
		}
	}

	public INetClient CreateClient()
	{
		return (INetClient)(object)new RiptideClient();
	}

	public INetServer CreateServer()
	{
		return (INetServer)(object)new RiptideServer();
	}

	public IMessage CreateMessage(SendModes sendMode, NetChannels channel, Enum packetId)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return (IMessage)(object)new RiptideMessage(Message.Create(RiptideUtils.SendModeToRiptide(sendMode), packetId));
	}

	public override string ToString()
	{
		return "Riptide Networking";
	}
}
public class RiptideMessage : IMessage
{
	internal Message InternalRiptideMessage { get; private set; }

	public RiptideMessage(Message sourceMessage)
	{
		InternalRiptideMessage = sourceMessage;
	}

	public byte[] GetBytes()
	{
		return InternalRiptideMessage.GetBytes();
	}

	public IMessage Add(byte[] data)
	{
		InternalRiptideMessage.Add(data, true);
		return (IMessage)(object)this;
	}

	public override string ToString()
	{
		return ((object)InternalRiptideMessage).ToString();
	}
}
public class RiptideServer : INetServer
{
	private Server _riptideServer;

	public int TimeoutTime
	{
		set
		{
			((Peer)_riptideServer).TimeoutTime = value;
		}
	}

	public EventHandler<MessageReceivedEventArgs> MessageReceived { get; set; }

	public EventHandler<ServerDisconnectedEventArgs> ClientDisconnected { get; set; }

	public EventHandler<ServerConnectedEventArgs> ClientConnected { get; set; }

	public RiptideServer()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		_riptideServer = new Server("SERVER");
		_riptideServer.MessageReceived += InternalMessageReceived;
		_riptideServer.ClientDisconnected += InternalClientDisconnected;
	}

	public void Start(ushort port, ushort maxPlayers)
	{
		_riptideServer.Start(port, maxPlayers, (byte)0, true);
	}

	private void InternalClientDisconnected(object sender, ServerDisconnectedEventArgs args)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		RiptideConnection riptideConnection = new RiptideConnection(args.Client);
		DisconnectReason reason = args.Reason;
		ServerDisconnectedEventArgs e = new ServerDisconnectedEventArgs((INetConnection)(object)riptideConnection, ((object)(DisconnectReason)(ref reason)).ToString());
		ClientDisconnected?.Invoke(sender, e);
	}

	private void InternalClientConnected(object sender, ServerConnectedEventArgs args)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		ServerConnectedEventArgs e = new ServerConnectedEventArgs((INetConnection)(object)new RiptideConnection(args.Client));
		ClientConnected?.Invoke(sender, e);
	}

	private void InternalMessageReceived(object sender, MessageReceivedEventArgs args)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		MessageReceivedEventArgs e = new MessageReceivedEventArgs(args.MessageId, (IMessage)(object)new RiptideMessage(args.Message), (INetConnection)(object)new RiptideConnection(args.FromConnection));
		MessageReceived?.Invoke(sender, e);
	}

	public void DisconnectClient(ushort id)
	{
		_riptideServer.DisconnectClient(id, (Message)null);
	}

	public void DisconnectClient(INetConnection client)
	{
		_riptideServer.DisconnectClient(client.Id, (Message)null);
	}

	public void Update()
	{
		((Peer)_riptideServer).Update();
	}

	public void Stop()
	{
		_riptideServer.Stop();
	}

	public override string ToString()
	{
		return ((object)_riptideServer).ToString();
	}
}
public static class RiptideUtils
{
	public static MessageSendMode SendModeToRiptide(SendModes sendMode)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		if ((int)sendMode != 0)
		{
			return (MessageSendMode)7;
		}
		return (MessageSendMode)0;
	}
}

BombRushMP.Server.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BombRushMP.Common;
using BombRushMP.Common.Networking;
using BombRushMP.Common.Packets;
using BombRushMP.Server.Gamemodes;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BombRushMP.Server")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BombRushMP.Server")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("dda80519-ac3f-4803-bf1f-0f1aed6887d5")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BombRushMP.Server
{
	public class AuthKeys
	{
		public Dictionary<string, AuthUser> Users = new Dictionary<string, AuthUser>();

		private AuthUser _defaultUser = new AuthUser();

		public void MakeExample()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			Users["Default"] = new AuthUser((UserKinds)0, Array.Empty<string>(), Array.Empty<int>(), "Default user");
		}

		public AuthUser GetUser(string key)
		{
			if (Users.TryGetValue(key, out var value))
			{
				return value;
			}
			if (Users.TryGetValue("Default", out var value2))
			{
				return value2;
			}
			return _defaultUser;
		}
	}
	public class BannedUser
	{
		public string NameAtTimeOfBan = "";

		public string Reason = "";
	}
	public class BannedUsers
	{
		public Dictionary<string, BannedUser> Users = new Dictionary<string, BannedUser>();

		public void MakeExample()
		{
			Users["Example"] = new BannedUser
			{
				NameAtTimeOfBan = "Goofiest Gooner",
				Reason = "Being annoying"
			};
		}

		public bool IsBanned(string address)
		{
			return Users.ContainsKey(address);
		}

		public void Ban(string address, string name = "None", string reason = "None")
		{
			Users[address] = new BannedUser
			{
				NameAtTimeOfBan = name,
				Reason = reason
			};
		}

		public void Unban(string address)
		{
			if (Users.TryGetValue(address, out var _))
			{
				Users.Remove(address);
			}
		}
	}
	public class BRCServer : IDisposable
	{
		public ServerLobbyManager ServerLobbyManager;

		public static Action<INetConnection> ClientHandshook;

		public static Action<INetConnection> ClientDisconnected;

		public static Action<INetConnection, Packets, Packet> PacketReceived;

		public static Action<float> OnTick;

		public Action RestartAction;

		public Dictionary<ushort, Player> Players = new Dictionary<ushort, Player>();

		public INetServer Server;

		private float _tickRate = 1f / 32f;

		private Stopwatch _tickStopWatch;

		private HashSet<int> _activeStages;

		private float _playerCountTickTimer;

		private IServerDatabase _database;

		public bool LogMessagesToFile;

		public bool LogMessages = true;

		public bool AllowNameChanges = true;

		public float ChatCooldown = 0.5f;

		public SendModes ClientAnimationSendMode = (SendModes)2;

		public ServerState ServerState = new ServerState();

		private const int MaxVisualUpdates = 5;

		public static BRCServer Instance { get; private set; }

		private INetworkingInterface NetworkingInterface => NetworkingEnvironment.NetworkingInterface;

		public BRCServer(int port, ushort maxPlayers, float tickRate, IServerDatabase database)
		{
			//IL_0031: 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)
			//IL_0041: Expected O, but got Unknown
			Instance = this;
			_database = database;
			_tickRate = tickRate;
			NetworkingInterface.MaxPayloadSize = 10000;
			ServerLobbyManager = new ServerLobbyManager();
			_tickStopWatch = new Stopwatch();
			_tickStopWatch.Start();
			Server = NetworkingInterface.CreateServer();
			Server.TimeoutTime = 10000;
			INetServer server = Server;
			server.ClientConnected = (EventHandler<ServerConnectedEventArgs>)Delegate.Combine(server.ClientConnected, new EventHandler<ServerConnectedEventArgs>(OnClientConnected));
			INetServer server2 = Server;
			server2.ClientDisconnected = (EventHandler<ServerDisconnectedEventArgs>)Delegate.Combine(server2.ClientDisconnected, new EventHandler<ServerDisconnectedEventArgs>(OnClientDisconnected));
			INetServer server3 = Server;
			server3.MessageReceived = (EventHandler<MessageReceivedEventArgs>)Delegate.Combine(server3.MessageReceived, new EventHandler<MessageReceivedEventArgs>(OnMessageReceived));
			Server.Start((ushort)port, maxPlayers);
			ServerLogger.Log($"Starting server on port {port} with max players {maxPlayers}, using Network Interface {NetworkingInterface}");
		}

		public void DisconnectClient(ushort id)
		{
			Server.DisconnectClient(id);
		}

		public void Update()
		{
			double totalSeconds = _tickStopWatch.Elapsed.TotalSeconds;
			if (totalSeconds >= (double)_tickRate)
			{
				Tick((float)totalSeconds);
				_tickStopWatch.Restart();
			}
		}

		private void Tick(float deltaTime)
		{
			Server.Update();
			foreach (KeyValuePair<ushort, Player> player in Players)
			{
				player.Value.Tick(deltaTime);
			}
			_activeStages = GetActiveStages();
			foreach (int activeStage in _activeStages)
			{
				TickStage(activeStage);
			}
			TickPlayerCount(deltaTime);
			OnTick?.Invoke(deltaTime);
		}

		private void TickPlayerCount(float deltaTime)
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			_playerCountTickTimer += deltaTime;
			if (!(_playerCountTickTimer >= 1f))
			{
				return;
			}
			_playerCountTickTimer = 0f;
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			foreach (KeyValuePair<ushort, Player> player in Players)
			{
				if (player.Value.ClientState != null && !player.Value.Invisible)
				{
					if (dictionary.TryGetValue(player.Value.ClientState.Stage, out var value))
					{
						dictionary[player.Value.ClientState.Stage] = value + 1;
					}
					else
					{
						dictionary[player.Value.ClientState.Stage] = 1;
					}
				}
			}
			SendPacket((Packet)new ServerPlayerCount(dictionary), (SendModes)0, (NetChannels)0);
		}

		private void TickStage(int stage)
		{
			foreach (ServerClientVisualStates item in CreateClientVisualStatesPacket(stage))
			{
				SendPacketToStage((Packet)(object)item, (SendModes)0, stage, (NetChannels)3);
			}
		}

		private HashSet<int> GetActiveStages()
		{
			HashSet<int> hashSet = new HashSet<int>();
			foreach (KeyValuePair<ushort, Player> player in Players)
			{
				if (player.Value.ClientState != null)
				{
					hashSet.Add(player.Value.ClientState.Stage);
				}
			}
			return hashSet;
		}

		public void Dispose()
		{
			Server.Stop();
		}

		public void SendPacket(Packet packet, SendModes sendMode, NetChannels channel, ushort[] except = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			IMessage val = PacketFactory.MessageFromPacket(packet, sendMode, channel);
			foreach (KeyValuePair<ushort, Player> player in Players)
			{
				if (player.Value.ClientState != null && (except == null || !except.Contains(player.Key)))
				{
					player.Value.Client.Send(val);
				}
			}
		}

		public void SendPacketToStage(Packet packet, SendModes sendMode, int stage, NetChannels channel, ushort[] except = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			IMessage val = PacketFactory.MessageFromPacket(packet, sendMode, channel);
			foreach (KeyValuePair<ushort, Player> player in Players)
			{
				if (player.Value.ClientState != null && player.Value.ClientState.Stage == stage && (except == null || !except.Contains(player.Key)))
				{
					player.Value.Client.Send(val);
				}
			}
		}

		public void SendPacketToClient(Packet packet, SendModes sendMode, INetConnection client, NetChannels channel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			IMessage val = PacketFactory.MessageFromPacket(packet, sendMode, channel);
			client.Send(val);
		}

		private void SendEliteNagChat(int stage)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			SendPacketToStage((Packet)new ServerChat("<color=yellow>Beat a Freesoul Elite in any gamemode to unlock a skateboard skin.</color>", (ChatMessageTypes)2), (SendModes)2, stage, (NetChannels)4);
		}

		public void SendMessageToPlayer(string message, Player player)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			SendPacketToClient((Packet)new ServerChat(message, (ChatMessageTypes)2), (SendModes)2, player.Client, (NetChannels)4);
		}

		private void ReloadAllUsers()
		{
			foreach (KeyValuePair<ushort, Player> player in Players)
			{
				player.Value.ClientState.User = _database.AuthKeys.GetUser(player.Value.Auth.AuthKey);
			}
			foreach (int activeStage in GetActiveStages())
			{
				ServerClientStates packet = CreateClientStatesPacket(activeStage);
				SendPacketToStage((Packet)(object)packet, (SendModes)1, activeStage, (NetChannels)2);
			}
		}

		private void ProcessCommand(string message, Player player)
		{
			//IL_0737: Unknown result type (might be due to invalid IL or missing references)
			//IL_074f: Expected O, but got Unknown
			//IL_0a22: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a34: Expected O, but got Unknown
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Expected O, but got Unknown
			//IL_08aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c2: Expected O, but got Unknown
			//IL_08e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ee: Expected O, but got Unknown
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Expected O, but got Unknown
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Expected O, but got Unknown
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Expected O, but got Unknown
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Expected O, but got Unknown
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Expected O, but got Unknown
			string[] array = message.Split(new char[1] { ' ' });
			string text = array[0].Substring(1, array[0].Length - 1);
			if (text == null)
			{
				return;
			}
			switch (text.Length)
			{
			case 12:
				switch (text[0])
				{
				case 's':
					if (text == "setservertag" && player.ClientState.User.IsModerator && array.Length > 1)
					{
						ServerState.Tags.Add(array[1]);
						SendPacket((Packet)new ServerServerStateUpdate(ServerState), (SendModes)1, (NetChannels)2);
					}
					break;
				case 'g':
				{
					if (!(text == "getaddresses") || !player.ClientState.User.IsModerator)
					{
						break;
					}
					string text4 = "";
					foreach (KeyValuePair<ushort, Player> player2 in Players)
					{
						if (player2.Value.ClientState.Stage == player.ClientState.Stage)
						{
							text4 += $"{player2.Value.Client.Address} - {TMPFilter.CloseAllTags(player2.Value.ClientState.Name)} ({player2.Key})\n";
						}
					}
					SendMessageToPlayer(text4, player);
					break;
				}
				}
				break;
			case 3:
				switch (text[0])
				{
				case 'n':
					if (text == "nag" && player.ClientState.User.HasTag("elite"))
					{
						SendEliteNagChat(player.ClientState.Stage);
					}
					break;
				case 's':
					if (text == "say" && player.ClientState.User.IsAdmin)
					{
						SendPacketToStage((Packet)new ServerChat(message.Substring(5), (ChatMessageTypes)2), (SendModes)2, player.ClientState.Stage, (NetChannels)4);
					}
					break;
				}
				break;
			case 5:
				switch (text[0])
				{
				case 'b':
				{
					if (!(text == "banid") || !player.ClientState.User.IsModerator)
					{
						break;
					}
					string[] array2 = CommandUtility.ParseArgs(message, 2);
					if (!string.IsNullOrWhiteSpace(array2[0]))
					{
						if (string.IsNullOrWhiteSpace(array2[1]))
						{
							array2[1] = "None";
						}
						if (ushort.TryParse(array2[0], out var result) && BanPlayerById(result, array2[1]))
						{
							SendMessageToPlayer("Player has been banned.", player);
						}
					}
					break;
				}
				case 'u':
					if (text == "unban" && player.ClientState.User.IsModerator && array.Length > 1 && Unban(array[1]))
					{
						SendMessageToPlayer("Player has been unbanned.", player);
					}
					break;
				case 's':
				{
					if (!(text == "stats") || !player.ClientState.User.IsModerator)
					{
						break;
					}
					int count = Players.Count;
					int count2 = ServerLobbyManager.Lobbies.Count;
					int num = 0;
					foreach (KeyValuePair<uint, Lobby> lobby in ServerLobbyManager.Lobbies)
					{
						if (lobby.Value.LobbyState.InGame)
						{
							num++;
						}
					}
					SendMessageToPlayer($"Players: {count}\nLobbies: {count2}\nLobbies in game: {num}", player);
					break;
				}
				}
				break;
			case 6:
				switch (text[0])
				{
				case 'g':
				{
					if (!(text == "getids") || !player.ClientState.User.IsModerator)
					{
						break;
					}
					string text5 = "";
					foreach (KeyValuePair<ushort, Player> player3 in Players)
					{
						if (player3.Value.ClientState.Stage == player.ClientState.Stage)
						{
							text5 += $"{player3.Key} - {TMPFilter.CloseAllTags(player3.Value.ClientState.Name)}\n";
						}
					}
					SendMessageToPlayer(text5, player);
					break;
				}
				case 's':
					if (text == "sayall" && player.ClientState.User.IsAdmin)
					{
						SendPacket((Packet)new ServerChat(message.Substring(8), (ChatMessageTypes)2), (SendModes)2, (NetChannels)4);
					}
					break;
				case 'r':
					if (text == "reload" && player.ClientState.User.IsAdmin)
					{
						SendMessageToPlayer("Reloading server database.", player);
						_database.Load();
						ReloadAllUsers();
					}
					break;
				}
				break;
			case 7:
				switch (text[0])
				{
				case 'r':
					if (text == "restart" && player.ClientState.User.IsAdmin)
					{
						SendMessageToPlayer("Restarting server.", player);
						RestartAction?.Invoke();
					}
					break;
				case 'b':
					if (text == "banlist" && player.ClientState.User.IsModerator)
					{
						SendPacketToClient((Packet)new ServerBanList(JsonConvert.SerializeObject((object)_database.BannedUsers, (Formatting)1)), (SendModes)2, player.Client, (NetChannels)0);
					}
					break;
				}
				break;
			case 13:
			{
				if (!(text == "getservertags") || !player.ClientState.User.IsModerator)
				{
					break;
				}
				string text3 = "Current server tags:\n";
				foreach (string tag in ServerState.Tags)
				{
					text3 = text3 + tag + "\n";
				}
				SendPacketToClient((Packet)new ServerChat(text3, (ChatMessageTypes)2), (SendModes)2, player.Client, (NetChannels)4);
				break;
			}
			case 15:
				if (text == "removeservertag" && player.ClientState.User.IsModerator && array.Length > 1)
				{
					ServerState.Tags.Remove(array[1]);
					SendPacket((Packet)new ServerServerStateUpdate(ServerState), (SendModes)1, (NetChannels)2);
				}
				break;
			case 16:
			{
				if (text == "makeseankingston" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result3) && Players.TryGetValue(result3, out var value2))
				{
					SendPacketToClient((Packet)new ServerSetSpecialSkin((SpecialSkins)3), (SendModes)2, value2.Client, (NetChannels)0);
				}
				break;
			}
			case 21:
			{
				if (text == "makeforkliftcertified" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result4) && Players.TryGetValue(result4, out var value3))
				{
					SendPacketToClient((Packet)new ServerSetSpecialSkin((SpecialSkins)4), (SendModes)2, value3.Client, (NetChannels)0);
				}
				break;
			}
			case 9:
			{
				if (text == "makechibi" && player.ClientState.User.IsModerator && array.Length > 1 && ushort.TryParse(array[1], out var result2) && Players.TryGetValue(result2, out var value))
				{
					SendPacketToClient((Packet)new ServerSetChibi(true), (SendModes)2, value.Client, (NetChannels)0);
				}
				break;
			}
			case 10:
			{
				if (!(text == "banaddress") || !player.ClientState.User.IsModerator)
				{
					break;
				}
				string[] array3 = CommandUtility.ParseArgs(message, 2);
				if (!string.IsNullOrWhiteSpace(array3[0]))
				{
					if (string.IsNullOrWhiteSpace(array3[1]))
					{
						array3[1] = "None";
					}
					if (BanPlayerByAddress(array3[0], array3[1]))
					{
						SendMessageToPlayer("Player has been banned.", player);
					}
				}
				break;
			}
			case 8:
				if (text == "clearall" && player.ClientState.User.IsModerator)
				{
					SendPacketToStage((Packet)new ServerChat((ChatMessageTypes)4), (SendModes)2, player.ClientState.Stage, (NetChannels)4);
				}
				break;
			case 4:
				if (text == "help")
				{
					char c = '/';
					string text2 = "\nAvailable commands:\n";
					text2 += $"{c}hide - Hide chat\n{c}show - Show chat\n{c}clear - Clear chat\n";
					if (player.ClientState.User.IsModerator)
					{
						text2 += $"{c}banlist - Downloads the ban list from the server\n{c}banaddress (ip) (reason) - Bans player by IP\n{c}banid (id) (reason) - Bans player by ID\n{c}unban (ip) - Unbans player by IP\n{c}getids - Gets IDs of players in current stage\n{c}getaddresses - Gets IP addresses of players in current stage\n{c}help\n{c}stats - Shows global player and lobby stats\n{c}makechibi (id)\n{c}makeseankingston (id)\n{c}makeforkliftcertified (id)\n{c}setservertag (tag)\n{c}removeservertag (tag)\n{c}getservertags\n{c}clearall - Clears everyones chats\n";
					}
					if (player.ClientState.User.IsAdmin)
					{
						text2 += $"{c}reload - Reloads server auth keys and banned users\n{c}restart - Restarts the server\n{c}say (announcement for stage)\n{c}sayall (global announcement)\n";
					}
					SendMessageToPlayer(text2, player);
				}
				break;
			case 11:
			case 14:
			case 17:
			case 18:
			case 19:
			case 20:
				break;
			}
		}

		private void OnPacketReceived(INetConnection client, Packets packetId, Packet packet)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Invalid comparison between Unknown and I4
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Expected O, but got Unknown
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0525: Unknown result type (might be due to invalid IL or missing references)
			//IL_053c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_0530: Unknown result type (might be due to invalid IL or missing references)
			//IL_0532: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Expected O, but got Unknown
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Expected O, but got Unknown
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Invalid comparison between Unknown and I4
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Expected O, but got Unknown
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Expected O, but got Unknown
			Player player = Players[client.Id];
			if (_database.BannedUsers.IsBanned(client.Address))
			{
				Server.DisconnectClient(client.Id);
				return;
			}
			if ((int)packetId <= 3)
			{
				if ((int)packetId == 0)
				{
					goto IL_005f;
				}
				if ((int)packetId == 3)
				{
					ClientState clientState = player.ClientState;
					ClientVisualState val = (ClientVisualState)packet;
					ClientVisualState clientVisualState = player.ClientVisualState;
					player.ClientVisualState = val;
					if (clientVisualState != null && clientVisualState.AFK != val.AFK && !player.Invisible)
					{
						if (val.AFK)
						{
							SendPacketToStage((Packet)new ServerChat(clientState.Name, "{0} is now AFK.", clientState.User.Badges, (ChatMessageTypes)3), (SendModes)2, clientState.Stage, (NetChannels)4);
						}
						else
						{
							SendPacketToStage((Packet)new ServerChat(clientState.Name, "{0} is no longer AFK.", clientState.User.Badges, (ChatMessageTypes)3), (SendModes)2, clientState.Stage, (NetChannels)4);
						}
					}
					return;
				}
			}
			else
			{
				if ((int)packetId == 31)
				{
					ClientChat val2 = (ClientChat)packet;
					string message = val2.Message;
					message = TMPFilter.Sanitize(message);
					if (message.Length > 256)
					{
						message = message.Substring(0, 256);
					}
					string text = player.ClientState.Name + "/" + TMPFilter.RemoveAllTags(player.ClientState.Name) + " (" + player.Client.Address + "): " + message;
					if (LogMessages)
					{
						ServerLogger.Log($"[Stage: {player.ClientState.Stage}] {text}");
					}
					if (LogMessagesToFile)
					{
						_database.LogChatMessage("[" + DateTime.Now.ToShortTimeString() + "] " + text, player.ClientState.Stage);
					}
					if (!TMPFilter.IsValidChatMessage(message))
					{
						return;
					}
					DateTime lastChatTime = player.LastChatTime;
					DateTime utcNow = DateTime.UtcNow;
					if (!((utcNow - lastChatTime).TotalSeconds <= (double)ChatCooldown))
					{
						player.LastChatTime = utcNow;
						if (val2.Message[0] == '/')
						{
							ProcessCommand(message, player);
						}
						else if (player.ClientState != null)
						{
							ServerChat packet2 = new ServerChat(player.ClientState.Name, message, player.ClientState.User.Badges, (ChatMessageTypes)0);
							SendPacketToStage((Packet)(object)packet2, (SendModes)2, player.ClientState.Stage, (NetChannels)4);
						}
					}
					return;
				}
				if ((int)packetId == 34)
				{
					goto IL_005f;
				}
			}
			if (!(packet is PlayerPacket))
			{
				return;
			}
			PlayerPacket val3 = (PlayerPacket)(object)((packet is PlayerPacket) ? packet : null);
			val3.ClientId = client.Id;
			if (player.ClientState != null)
			{
				NetChannels channel = (NetChannels)0;
				SendModes sendMode = (SendModes)2;
				if (packet is PlayerAnimation)
				{
					channel = (NetChannels)5;
					sendMode = PlayerAnimation.ServerSendMode;
				}
				SendPacketToStage((Packet)(object)val3, sendMode, Players[client.Id].ClientState.Stage, channel);
			}
			return;
			IL_005f:
			ClientAuth val4 = (ClientAuth)(object)((packet is ClientAuth) ? packet : null);
			ClientState val5 = (ClientState)(object)((packet is ClientState) ? packet : null);
			if (val4 != null)
			{
				val5 = val4.State;
				if (player.Auth != null)
				{
					val4 = null;
				}
				else
				{
					player.Auth = val4;
				}
			}
			if (val5.Name.Length > 64)
			{
				val5.Name = val5.Name.Substring(0, 64);
			}
			if (val5.CrewName.Length > 32)
			{
				val5.CrewName = val5.CrewName.Substring(0, 32);
			}
			ClientState clientState2 = player.ClientState;
			if (clientState2 != null)
			{
				if (!AllowNameChanges && (int)clientState2.User.UserKind == 0)
				{
					val5.Name = clientState2.Name;
				}
				val5.Stage = clientState2.Stage;
			}
			if (val4 != null)
			{
				if ((val5.User = _database.AuthKeys.GetUser(val4.AuthKey)).CanLurk)
				{
					player.Invisible = val4.Invisible;
				}
			}
			else if (clientState2 != null)
			{
				val5.User = clientState2.User;
			}
			if (val5.User.HasTag("elite"))
			{
				val5.Name = "Freesoul Elite";
				val5.CrewName = "Freesoul";
			}
			else if ((int)val5.SpecialSkin == 2)
			{
				val5.SpecialSkin = (SpecialSkins)(-1);
			}
			player.ClientState = val5;
			ServerClientStates val6 = CreatePlayerClientState(player);
			if (val6 != null)
			{
				SendPacketToStage((Packet)(object)val6, (SendModes)1, val5.Stage, (NetChannels)2);
			}
			if (clientState2 == null)
			{
				ServerLogger.Log($"Player from {client.Address} (ID: {client.Id}) connected as {val5.Name} in stage {val5.Stage}.");
				SendPacketToClient((Packet)new ServerConnectionResponse
				{
					LocalClientId = client.Id,
					TickRate = _tickRate,
					ClientAnimationSendMode = ClientAnimationSendMode,
					User = val5.User,
					ServerState = ServerState
				}, (SendModes)1, client, (NetChannels)0);
				ServerClientStates packet3 = CreateClientStatesPacket(val5.Stage);
				SendPacketToClient((Packet)(object)packet3, (SendModes)1, client, (NetChannels)2);
				string text2 = "{0} Connected.";
				if (val5.User.HasTag("elite"))
				{
					text2 = "<color=yellow>A {0} has entered the stage!</color>";
				}
				if (!player.Invisible)
				{
					SendPacketToStage((Packet)new ServerChat(val5.Name, text2, val5.User.Badges, (ChatMessageTypes)1), (SendModes)2, val5.Stage, (NetChannels)4);
				}
				ClientHandshook?.Invoke(client);
			}
		}

		private void OnMessageReceived(object sender, MessageReceivedEventArgs e)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Packets val = (Packets)e.MessageId;
				Packet val2 = PacketFactory.PacketFromMessage(val, e.Message);
				if (val2 != null && Players.TryGetValue(e.FromConnection.Id, out var _))
				{
					PacketReceived?.Invoke(e.FromConnection, val, val2);
					OnPacketReceived(e.FromConnection, val, val2);
				}
			}
			catch (Exception arg)
			{
				ServerLogger.Log($"Dropped client from {e.FromConnection} (ID: {e.FromConnection.Id}) because they sent a faulty packet. Exception:\n{arg}");
				Server.DisconnectClient(e.FromConnection);
			}
		}

		public bool BanPlayerById(ushort id, string reason = "None")
		{
			if (Players.TryGetValue(id, out var value))
			{
				return BanPlayerByAddress(value.Client.Address);
			}
			return false;
		}

		public bool Unban(string address)
		{
			_database.Load();
			if (!_database.BannedUsers.IsBanned(address))
			{
				return false;
			}
			_database.BannedUsers.Unban(address);
			ServerLogger.Log("Unbanned IP " + address);
			_database.Save();
			return true;
		}

		public bool BanPlayerByAddress(string address, string reason = "None")
		{
			_database.Load();
			string text = "None";
			ushort num = 0;
			foreach (KeyValuePair<ushort, Player> player in Players)
			{
				if (player.Value.Client.Address == address)
				{
					text = player.Value.ClientState.Name;
					num = player.Key;
					break;
				}
			}
			_database.BannedUsers.Ban(address, text, reason);
			ServerLogger.Log("Banned IP " + address + ", player name: " + text + ", reason: " + reason);
			if (num != 0)
			{
				Server.DisconnectClient(num);
			}
			_database.Save();
			return true;
		}

		private void OnClientConnected(object sender, ServerConnectedEventArgs e)
		{
			if (!_database.BannedUsers.IsBanned(e.Client.Address))
			{
				ServerLogger.Log($"Client connected from {e.Client.Address}. ID: {e.Client.Id}. Players: {Players.Count + 1}");
			}
			Player player = new Player();
			player.Client = e.Client;
			player.Server = this;
			Players[e.Client.Id] = player;
			e.Client.CanQualityDisconnect = false;
			if (_database.BannedUsers.IsBanned(e.Client.Address))
			{
				Server.DisconnectClient(e.Client.Id);
			}
		}

		private void OnClientDisconnected(object sender, ServerDisconnectedEventArgs e)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			if (!_database.BannedUsers.IsBanned(e.Client.Address))
			{
				ServerLogger.Log($"Client disconnected from {e.Client.Address}. ID: {e.Client.Id}. Reason: {e.Reason}. Players: {Players.Count - 1}");
			}
			ClientState val = null;
			if (Players.TryGetValue(e.Client.Id, out var value))
			{
				ClientDisconnected?.Invoke(e.Client);
				Players.Remove(e.Client.Id);
				val = value.ClientState;
			}
			if (val != null)
			{
				SendPacketToStage((Packet)new ServerClientDisconnected(e.Client.Id), (SendModes)1, val.Stage, (NetChannels)2);
				AuthUser user = val.User;
				string text = "{0} Disconnected.";
				if (user.HasTag("elite"))
				{
					text = "<color=yellow>A {0} has left!</color>";
				}
				if (!value.Invisible)
				{
					SendPacketToStage((Packet)new ServerChat(val.Name, text, val.User.Badges, (ChatMessageTypes)1), (SendModes)2, val.Stage, (NetChannels)4);
				}
			}
		}

		private ServerClientStates CreatePlayerClientState(Player player)
		{
			//IL_0014: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			if (player.Invisible)
			{
				return null;
			}
			if (player.ClientState == null)
			{
				return null;
			}
			return new ServerClientStates
			{
				Full = false,
				ClientStates = { [player.Client.Id] = player.ClientState }
			};
		}

		private ServerClientStates CreateClientStatesPacket(int stage)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ServerClientStates val = new ServerClientStates();
			val.Full = true;
			foreach (KeyValuePair<ushort, Player> player in Players)
			{
				if (!player.Value.Invisible && player.Value.ClientState != null && player.Value.ClientState.Stage == stage)
				{
					val.ClientStates[player.Key] = player.Value.ClientState;
				}
			}
			return val;
		}

		private List<ServerClientVisualStates> CreateClientVisualStatesPacket(int stage)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			List<ServerClientVisualStates> list = new List<ServerClientVisualStates>();
			ListExtensions.Shuffle<ServerClientVisualStates>((IList<ServerClientVisualStates>)list);
			int num = 0;
			ServerClientVisualStates val = new ServerClientVisualStates();
			foreach (KeyValuePair<ushort, Player> player in Players)
			{
				if (num >= 5)
				{
					list.Add(val);
					val = new ServerClientVisualStates();
				}
				if (!player.Value.Invisible && player.Value.ClientState != null && player.Value.ClientState.Stage == stage && player.Value.ClientVisualState != null)
				{
					val.ClientVisualStates[player.Key] = player.Value.ClientVisualState;
					num++;
				}
			}
			list.Add(val);
			return list;
		}
	}
	public interface IServerDatabase
	{
		BannedUsers BannedUsers { get; }

		AuthKeys AuthKeys { get; }

		void Load();

		void Save();

		void LogChatMessage(string message, int stage);
	}
	public class Lobby
	{
		public LobbyState LobbyState;

		public Gamemode CurrentGamemode;

		public Lobby(LobbyState lobbyState)
		{
			LobbyState = lobbyState;
		}

		public void Tick(float deltaTime)
		{
			if (CurrentGamemode != null && LobbyState.InGame)
			{
				CurrentGamemode.Tick(deltaTime);
			}
		}
	}
	public class Player
	{
		private const float SecondsToKickPlayerWithoutClientState = 5f;

		public BRCServer Server;

		public ClientAuth Auth;

		public ClientState ClientState;

		public ClientVisualState ClientVisualState;

		public float SecondsWithoutSendingClientState;

		public INetConnection Client;

		public DateTime LastChatTime = DateTime.UtcNow;

		public bool Invisible;

		public void Tick(float deltaTime)
		{
			if (ClientState == null)
			{
				SecondsWithoutSendingClientState += deltaTime;
				if (SecondsWithoutSendingClientState > 5f)
				{
					ServerLogger.Log($"Rejecting player from {Client} (ID: {Client.Id}) because they took longer than {5f} seconds to send ClientState.");
					Server.DisconnectClient(Client.Id);
				}
			}
			else
			{
				SecondsWithoutSendingClientState = 0f;
			}
		}
	}
	public static class ServerConstants
	{
		public const string JoinMessage = "{0} Connected.";

		public const string LeaveMessage = "{0} Disconnected.";

		public const string AFKMessage = "{0} is now AFK.";

		public const string LeaveAFKMessage = "{0} is no longer AFK.";

		public const float PlayerCountTickRate = 1f;
	}
	public class ServerLobbyManager : IDisposable
	{
		public Dictionary<uint, Lobby> Lobbies = new Dictionary<uint, Lobby>();

		private BRCServer _server;

		private UIDProvider _uidProvider = new UIDProvider();

		private HashSet<int> _queuedStageUpdates = new HashSet<int>();

		private List<Action> _queuedActions = new List<Action>();

		public ServerLobbyManager()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			_server = BRCServer.Instance;
			BRCServer.PacketReceived = (Action<INetConnection, Packets, Packet>)Delegate.Combine(BRCServer.PacketReceived, new Action<INetConnection, Packets, Packet>(OnPacketReceived));
			BRCServer.OnTick = (Action<float>)Delegate.Combine(BRCServer.OnTick, new Action<float>(OnTick));
			BRCServer.ClientDisconnected = (Action<INetConnection>)Delegate.Combine(BRCServer.ClientDisconnected, new Action<INetConnection>(OnClientDisconnected));
			BRCServer.ClientHandshook = (Action<INetConnection>)Delegate.Combine(BRCServer.ClientHandshook, new Action<INetConnection>(OnClientHandshook));
		}

		public void Dispose()
		{
			BRCServer.PacketReceived = (Action<INetConnection, Packets, Packet>)Delegate.Remove(BRCServer.PacketReceived, new Action<INetConnection, Packets, Packet>(OnPacketReceived));
			BRCServer.OnTick = (Action<float>)Delegate.Remove(BRCServer.OnTick, new Action<float>(OnTick));
			BRCServer.ClientDisconnected = (Action<INetConnection>)Delegate.Remove(BRCServer.ClientDisconnected, new Action<INetConnection>(OnClientDisconnected));
			BRCServer.ClientHandshook = (Action<INetConnection>)Delegate.Remove(BRCServer.ClientHandshook, new Action<INetConnection>(OnClientHandshook));
		}

		public void StartGame(uint lobbyId)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			Lobby lobby = Lobbies[lobbyId];
			lobby.CurrentGamemode = GamemodeFactory.GetGamemode(lobby.LobbyState.Gamemode);
			lobby.CurrentGamemode.Lobby = lobby;
			lobby.LobbyState.InGame = true;
			foreach (KeyValuePair<ushort, LobbyPlayer> player in lobby.LobbyState.Players)
			{
				player.Value.Score = 0f;
				player.Value.Ready = false;
			}
			ClearAllInvitesForLobby(lobbyId);
			SendLobbiesToStage(lobby.LobbyState.Stage);
			SendPacketToLobby((Packet)new ServerLobbyStart(), (SendModes)1, lobbyId, (NetChannels)1);
			lobby.CurrentGamemode.OnStart();
		}

		public void EndGame(uint lobbyId, bool cancelled)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			Lobby lobby = Lobbies[lobbyId];
			lobby.LobbyState.InGame = false;
			Gamemode currentGamemode = lobby.CurrentGamemode;
			lobby.CurrentGamemode = null;
			SendLobbiesToStage(lobby.LobbyState.Stage);
			SendPacketToLobby((Packet)new ServerLobbyEnd(cancelled), (SendModes)1, lobbyId, (NetChannels)1);
			currentGamemode.OnEnd(cancelled);
		}

		public void SetPlayerScore(ushort clientId, float score)
		{
			Lobby lobbyPlayerIsIn = GetLobbyPlayerIsIn(clientId);
			lobbyPlayerIsIn.LobbyState.Players[clientId].Score = score;
			SendLobbySoftUpdate(lobbyPlayerIsIn, clientId, score);
		}

		public Lobby GetLobbyPlayerIsIn(ushort clientId)
		{
			foreach (KeyValuePair<uint, Lobby> lobby in Lobbies)
			{
				if (lobby.Value.LobbyState.Players.Keys.Contains(clientId))
				{
					return lobby.Value;
				}
			}
			return null;
		}

		public void DeleteLobby(uint lobbyId)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			if (Lobbies.TryGetValue(lobbyId, out var value))
			{
				if (value.CurrentGamemode != null)
				{
					EndGame(lobbyId, cancelled: true);
				}
				Lobbies.Remove(lobbyId);
				_uidProvider.FreeUID(lobbyId);
				ServerLogger.Log($"Deleted Lobby with UID {lobbyId}");
				_server.SendPacketToStage((Packet)new ServerLobbyDeleted(value.LobbyState.Id), (SendModes)1, value.LobbyState.Stage, (NetChannels)2);
			}
		}

		public void AddPlayer(uint lobbyId, ushort clientId)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			if (Lobbies.TryGetValue(lobbyId, out var value))
			{
				value.LobbyState.Players[clientId] = new LobbyPlayer(lobbyId, clientId, (byte)0);
				UninvitePlayer(lobbyId, clientId);
				QueueStageUpdate(value.LobbyState.Stage);
			}
		}

		public void RemovePlayer(uint lobbyId, ushort clientId)
		{
			if (Lobbies.TryGetValue(lobbyId, out var value))
			{
				value.LobbyState.Players.Remove(clientId);
				if (value.LobbyState.HostId == clientId)
				{
					DeleteLobby(lobbyId);
				}
				QueueStageUpdate(value.LobbyState.Stage);
			}
		}

		public bool InvitePlayer(uint lobbyId, ushort inviteeId)
		{
			if (Lobbies.TryGetValue(lobbyId, out var value))
			{
				if (value.LobbyState.Players.ContainsKey(inviteeId))
				{
					return false;
				}
				if (value.LobbyState.InGame)
				{
					return false;
				}
				if (!value.LobbyState.InvitedPlayers.ContainsKey(inviteeId))
				{
					value.LobbyState.InvitedPlayers[inviteeId] = DateTime.UtcNow;
					QueueStageUpdate(value.LobbyState.Stage);
					return true;
				}
			}
			return false;
		}

		public void UninvitePlayer(uint lobbyId, ushort inviteeId)
		{
			if (Lobbies.TryGetValue(lobbyId, out var value) && value.LobbyState.InvitedPlayers.ContainsKey(inviteeId))
			{
				value.LobbyState.InvitedPlayers.Remove(inviteeId);
				QueueStageUpdate(value.LobbyState.Stage);
			}
		}

		public void ClearAllInvitesForLobby(uint lobbyId)
		{
			if (Lobbies.TryGetValue(lobbyId, out var value))
			{
				value.LobbyState.InvitedPlayers.Clear();
				QueueStageUpdate(value.LobbyState.Stage);
			}
		}

		public void ClearAllInvitesForPlayer(ushort playerId)
		{
			foreach (KeyValuePair<uint, Lobby> lobby in Lobbies)
			{
				if (lobby.Value.LobbyState.InvitedPlayers.ContainsKey(playerId))
				{
					lobby.Value.LobbyState.InvitedPlayers.Remove(playerId);
					QueueStageUpdate(lobby.Value.LobbyState.Stage);
				}
			}
		}

		private void OnTick(float deltaTime)
		{
			foreach (int queuedStageUpdate in _queuedStageUpdates)
			{
				SendLobbiesToStage(queuedStageUpdate);
			}
			_queuedStageUpdates.Clear();
			foreach (Action queuedAction in _queuedActions)
			{
				queuedAction();
			}
			_queuedActions.Clear();
			foreach (KeyValuePair<uint, Lobby> lobby in Lobbies)
			{
				lobby.Value.Tick(deltaTime);
			}
		}

		private void OnClientHandshook(INetConnection client)
		{
			SendLobbiesToClient(client);
		}

		private void OnClientDisconnected(INetConnection client)
		{
			ClearAllInvitesForPlayer(client.Id);
			Lobby lobbyPlayerIsIn = GetLobbyPlayerIsIn(client.Id);
			if (lobbyPlayerIsIn != null)
			{
				RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, client.Id);
			}
		}

		private void OnPacketReceived(INetConnection client, Packets packetId, Packet packet)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected I4, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Expected O, but got Unknown
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected I4, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Expected O, but got Unknown
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Expected O, but got Unknown
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Expected O, but got Unknown
			//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a8: Expected O, but got Unknown
			//IL_0608: Unknown result type (might be due to invalid IL or missing references)
			//IL_060f: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Expected O, but got Unknown
			ushort id = client.Id;
			Player player = _server.Players[id];
			if (player.ClientState == null)
			{
				return;
			}
			Lobby lobbyPlayerIsIn = GetLobbyPlayerIsIn(client.Id);
			if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.CurrentGamemode != null)
			{
				lobbyPlayerIsIn.CurrentGamemode.OnPacketFromLobbyReceived(packetId, packet, id);
			}
			switch (packetId - 10)
			{
			case 13:
				if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id && !lobbyPlayerIsIn.LobbyState.InGame && lobbyPlayerIsIn.CurrentGamemode == null)
				{
					lobbyPlayerIsIn.LobbyState.Gamemode = ((ClientLobbySetGamemode)packet).Gamemode;
					lobbyPlayerIsIn.LobbyState.GamemodeSettings = ((ClientLobbySetGamemode)packet).GamemodeSettings;
					QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage);
				}
				return;
			case 0:
			{
				ClientLobbyCreate val3 = (ClientLobbyCreate)packet;
				if (lobbyPlayerIsIn != null)
				{
					RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, client.Id);
				}
				Lobby lobby = new Lobby(new LobbyState(player.ClientState.Stage, _uidProvider.RequestUID(), client.Id));
				lobby.LobbyState.Gamemode = val3.GamemodeID;
				lobby.LobbyState.GamemodeSettings = val3.Settings;
				Lobbies[lobby.LobbyState.Id] = lobby;
				AddPlayer(lobby.LobbyState.Id, client.Id);
				ServerLogger.Log($"Created Lobby with UID {lobby.LobbyState.Id} with host {player.ClientState.Name}");
				QueueAction(delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: Expected O, but got Unknown
					_server.SendPacketToClient((Packet)new ServerLobbyCreateResponse(), (SendModes)2, client, (NetChannels)2);
				});
				return;
			}
			case 1:
			{
				ClientLobbyJoin val4 = (ClientLobbyJoin)packet;
				if (Lobbies.TryGetValue(val4.LobbyId, out var value) && !value.LobbyState.InGame && lobbyPlayerIsIn != value)
				{
					if (lobbyPlayerIsIn != null)
					{
						RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, id);
					}
					AddPlayer(val4.LobbyId, id);
					ServerLogger.Log($"{_server.Players[id].ClientState.Name} joined lobby UID {value.LobbyState.Id}. Now at {value.LobbyState.Players.Count} players. Hosted by {_server.Players[value.LobbyState.HostId].ClientState.Name}.");
				}
				return;
			}
			case 2:
				if (lobbyPlayerIsIn != null)
				{
					RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, id);
				}
				return;
			case 6:
				if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id && !lobbyPlayerIsIn.LobbyState.InGame)
				{
					StartGame(lobbyPlayerIsIn.LobbyState.Id);
				}
				return;
			case 11:
				if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id && lobbyPlayerIsIn.LobbyState.InGame)
				{
					EndGame(lobbyPlayerIsIn.LobbyState.Id, cancelled: true);
				}
				return;
			case 15:
				if (lobbyPlayerIsIn != null)
				{
					lobbyPlayerIsIn.LobbyState.Players[id].Ready = ((ClientLobbySetReady)packet).Ready;
					QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage);
				}
				return;
			case 16:
				if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id)
				{
					ClientLobbyInvite val2 = (ClientLobbyInvite)packet;
					if (InvitePlayer(lobbyPlayerIsIn.LobbyState.Id, val2.InviteeId))
					{
						_server.SendPacketToClient((Packet)new ServerLobbyInvite(val2.InviteeId, id, lobbyPlayerIsIn.LobbyState.Id), (SendModes)2, _server.Players[val2.InviteeId].Client, (NetChannels)2);
					}
				}
				return;
			case 18:
			{
				ClientLobbyDeclineInvite val = (ClientLobbyDeclineInvite)packet;
				UninvitePlayer(val.LobbyId, id);
				return;
			}
			case 19:
				ClearAllInvitesForPlayer(id);
				return;
			case 20:
				if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id)
				{
					ushort playerId = ((ClientLobbyKick)packet).PlayerId;
					if (lobbyPlayerIsIn.LobbyState.Players.ContainsKey(playerId))
					{
						RemovePlayer(lobbyPlayerIsIn.LobbyState.Id, playerId);
					}
				}
				return;
			case 3:
			case 4:
			case 5:
			case 7:
			case 8:
			case 9:
			case 10:
			case 12:
			case 14:
			case 17:
				return;
			}
			switch (packetId - 41)
			{
			case 0:
				if (lobbyPlayerIsIn != null && !lobbyPlayerIsIn.LobbyState.InGame && (lobbyPlayerIsIn.LobbyState.AllowTeamSwitching || lobbyPlayerIsIn.LobbyState.HostId == id))
				{
					ClientSetTeam val6 = (ClientSetTeam)packet;
					lobbyPlayerIsIn.LobbyState.Players[id].Team = val6.Team;
					QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage);
				}
				break;
			case 3:
				if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id)
				{
					ClientLobbySetAllowTeamSwitching val7 = (ClientLobbySetAllowTeamSwitching)packet;
					lobbyPlayerIsIn.LobbyState.AllowTeamSwitching = val7.Set;
					QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage);
				}
				break;
			case 4:
				if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id)
				{
					ClientLobbySetPlayerTeam val8 = (ClientLobbySetPlayerTeam)packet;
					if (lobbyPlayerIsIn.LobbyState.Players.ContainsKey(val8.PlayerId))
					{
						lobbyPlayerIsIn.LobbyState.Players[val8.PlayerId].Team = val8.TeamId;
						QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage);
					}
				}
				break;
			case 5:
				if (lobbyPlayerIsIn != null && lobbyPlayerIsIn.LobbyState.HostId == id)
				{
					ClientLobbySetChallenge val5 = (ClientLobbySetChallenge)packet;
					lobbyPlayerIsIn.LobbyState.Challenge = val5.Set;
					QueueStageUpdate(lobbyPlayerIsIn.LobbyState.Stage);
				}
				break;
			case 1:
			case 2:
				break;
			}
		}

		public void SendPacketToLobby(Packet packet, SendModes sendMode, uint lobbyId, NetChannels channel)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (!Lobbies.TryGetValue(lobbyId, out var value))
			{
				return;
			}
			foreach (KeyValuePair<ushort, LobbyPlayer> player in value.LobbyState.Players)
			{
				_server.SendPacketToClient(packet, sendMode, _server.Players[player.Key].Client, channel);
			}
		}

		private void SendLobbiesToClient(INetConnection client)
		{
			Player player = _server.Players[client.Id];
			if (!_queuedStageUpdates.Contains(player.ClientState.Stage))
			{
				Packet packet = CreateServerLobbyStatesPacket(player.ClientState.Stage);
				_server.SendPacketToClient(packet, (SendModes)1, client, (NetChannels)2);
			}
		}

		private void QueueStageUpdate(int stage)
		{
			_queuedStageUpdates.Add(stage);
		}

		private void QueueAction(Action action)
		{
			_queuedActions.Add(action);
		}

		private void SendLobbySoftUpdate(Lobby lobby, ushort playerId, float score)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			ServerLobbySoftUpdate packet = new ServerLobbySoftUpdate(lobby.LobbyState.Id, playerId, score);
			SendPacketToLobby((Packet)(object)packet, (SendModes)1, lobby.LobbyState.Id, (NetChannels)2);
		}

		private void SendLobbiesToStage(int stage)
		{
			Packet packet = CreateServerLobbyStatesPacket(stage);
			_server.SendPacketToStage(packet, (SendModes)1, stage, (NetChannels)2);
		}

		private List<LobbyState> GetLobbyStatesForStage(int stage)
		{
			List<LobbyState> list = new List<LobbyState>();
			foreach (KeyValuePair<uint, Lobby> lobby in Lobbies)
			{
				if (lobby.Value.LobbyState.Stage == stage)
				{
					list.Add(lobby.Value.LobbyState);
				}
			}
			return list;
		}

		private Packet CreateServerLobbyStatesPacket(int stage)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return (Packet)new ServerLobbies(GetLobbyStatesForStage(stage));
		}
	}
	public static class ServerLogger
	{
		public static void Log(string message)
		{
			Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] " + message);
		}
	}
}
namespace BombRushMP.Server.Gamemodes
{
	public abstract class Gamemode
	{
		public bool TeamBased;

		public Lobby Lobby;

		protected int CountdownTime = 10;

		protected BRCServer Server;

		protected ServerLobbyManager ServerLobbyManager;

		public Gamemode()
		{
			Server = BRCServer.Instance;
			ServerLobbyManager = Server.ServerLobbyManager;
		}

		public virtual void OnStart()
		{
		}

		public virtual void OnEnd(bool cancelled)
		{
		}

		public virtual void Tick(float deltaTime)
		{
		}

		public virtual void OnPacketFromLobbyReceived(Packets packetId, Packet packet, ushort playerId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)packetId == 37 && playerId == Lobby.LobbyState.HostId)
			{
				CountdownTime = ((ClientGamemodeCountdown)((packet is ClientGamemodeCountdown) ? packet : null)).CountdownSeconds;
			}
		}
	}
	public static class GamemodeFactory
	{
		private static Dictionary<GamemodeIDs, Type> Gamemodes = new Dictionary<GamemodeIDs, Type>
		{
			{
				(GamemodeIDs)0,
				typeof(ScoreBattle)
			},
			{
				(GamemodeIDs)1,
				typeof(GraffitiRace)
			},
			{
				(GamemodeIDs)2,
				typeof(TeamGraffitiRace)
			},
			{
				(GamemodeIDs)3,
				typeof(ProSkaterScoreBattle)
			},
			{
				(GamemodeIDs)4,
				typeof(TeamScoreBattle)
			},
			{
				(GamemodeIDs)5,
				typeof(TeamProSkaterScoreBattle)
			}
		};

		public static Gamemode GetGamemode(GamemodeIDs gameModeID)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Activator.CreateInstance(Gamemodes[gameModeID]) as Gamemode;
		}
	}
	public class GraffitiRace : Gamemode
	{
		public enum States
		{
			Countdown,
			Main,
			Finished
		}

		private States _state;

		private float _countdownTimer;

		private float _maxScore;

		private Dictionary<byte, HashSet<int>> _graffitisCompletedByTeam = new Dictionary<byte, HashSet<int>>();

		public override void OnEnd(bool cancelled)
		{
			base.OnEnd(cancelled);
			_maxScore = 0f;
		}

		public override void OnStart()
		{
			base.OnStart();
			_maxScore = 0f;
			_graffitisCompletedByTeam = new Dictionary<byte, HashSet<int>>();
		}

		private bool SetTagCompleted(byte team, int tag)
		{
			HashSet<int> hashSet;
			if (_graffitisCompletedByTeam.TryGetValue(team, out var value))
			{
				hashSet = value;
			}
			else
			{
				hashSet = new HashSet<int>();
				_graffitisCompletedByTeam[team] = hashSet;
			}
			if (hashSet.Contains(tag))
			{
				return false;
			}
			hashSet.Add(tag);
			return true;
		}

		public override void Tick(float deltaTime)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			if (_state == States.Countdown && _countdownTimer > (float)CountdownTime)
			{
				ServerLobbyManager.SendPacketToLobby((Packet)new ServerGamemodeBegin(), (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1);
				_state = States.Main;
			}
			_countdownTimer += deltaTime;
		}

		public override void OnPacketFromLobbyReceived(Packets packetId, Packet packet, ushort playerId)
		{
			//IL_0001: 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_000c: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			base.OnPacketFromLobbyReceived(packetId, packet, playerId);
			if ((int)packetId <= 22)
			{
				if ((int)packetId != 20)
				{
					if ((int)packetId == 22 && playerId == Lobby.LobbyState.HostId)
					{
						ClientGraffitiRaceGSpots val = (ClientGraffitiRaceGSpots)packet;
						ServerLobbyManager.SendPacketToLobby((Packet)(object)val, (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1);
						_maxScore += val.GraffitiSpots.Count;
					}
				}
				else if (!TeamBased && _state == States.Main)
				{
					ClientGamemodeScore val2 = (ClientGamemodeScore)packet;
					ServerLobbyManager.SetPlayerScore(playerId, val2.Score);
					if (val2.Score >= _maxScore)
					{
						ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false);
						_state = States.Finished;
					}
				}
			}
			else
			{
				if ((int)packetId != 36)
				{
					if ((int)packetId != 42 || !TeamBased)
					{
						return;
					}
					LobbyPlayer lobbyPlayer = Lobby.LobbyState.Players[playerId];
					if (_state != States.Main)
					{
						return;
					}
					ClientTeamGraffRaceScore val3 = (ClientTeamGraffRaceScore)packet;
					if (!SetTagCompleted(lobbyPlayer.Team, val3.TagHash))
					{
						return;
					}
					ServerLobbyManager.SetPlayerScore(playerId, lobbyPlayer.Score + 1f);
					if (Lobby.LobbyState.GetScoreForTeam(Lobby.LobbyState.Players[playerId].Team) >= _maxScore)
					{
						ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false);
						_state = States.Finished;
					}
					IEnumerable<KeyValuePair<ushort, LobbyPlayer>> enumerable = Lobby.LobbyState.Players.Where((KeyValuePair<ushort, LobbyPlayer> x) => x.Value.Team == lobbyPlayer.Team && x.Value.Id != lobbyPlayer.Id);
					ServerTeamGraffRaceScore packet2 = new ServerTeamGraffRaceScore(playerId, val3.TagHash);
					{
						foreach (KeyValuePair<ushort, LobbyPlayer> item in enumerable)
						{
							Server.SendPacketToClient((Packet)(object)packet2, (SendModes)1, Server.Players[item.Key].Client, (NetChannels)1);
						}
						return;
					}
				}
				if (playerId == Lobby.LobbyState.HostId)
				{
					ServerLobbyManager.SendPacketToLobby(packet, (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1);
				}
			}
		}
	}
	public class ProSkaterScoreBattle : ScoreBattle
	{
		public ProSkaterScoreBattle()
		{
			ComboBased = true;
		}
	}
	public class ScoreBattle : Gamemode
	{
		public enum States
		{
			Countdown,
			Main,
			Finished
		}

		private States _state;

		private float _stateTimer;

		private DateTime _startTime = DateTime.UtcNow;

		public bool ComboBased;

		private HashSet<ushort> _clientsFinishedCombo = new HashSet<ushort>();

		private float _timeElapsed;

		private float _timeLeft = 1f;

		private int _durationMinutes = 3;

		public override void Tick(float deltaTime)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			switch (_state)
			{
			case States.Countdown:
				if (_stateTimer > (float)CountdownTime)
				{
					ServerLobbyManager.SendPacketToLobby((Packet)new ServerGamemodeBegin(), (SendModes)1, Lobby.LobbyState.Id, (NetChannels)1);
					_state = States.Main;
					_startTime = DateTime.UtcNow;
				}
				break;
			case States.Main:
			{
				_timeElapsed = (float)(DateTime.UtcNow - _startTime).TotalSeconds;
				float num = (float)_durationMinutes * 60f;
				_timeLeft = num - _timeElapsed;
				if (!ComboBased)
				{
					if (_timeLeft <= 0f)
					{
						ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false);
						_state = States.Finished;
					}
				}
				else if (EveryoneFinishedComboing() && _timeLeft <= 0f)
				{
					ServerLobbyManager.EndGame(Lobby.LobbyState.Id, cancelled: false);
					_state = States.Finished;
				}
				break;
			}
			}
			_stateTimer += deltaTime;
		}

		private bool EveryoneFinishedComboing()
		{
			foreach (KeyValuePair<ushort, LobbyPlayer> player in Lobby.LobbyState.Players)
			{
				if (!_clientsFinishedCombo.Contains(player.Key))
				{
					return false;
				}
			}
			return true;
		}

		public override void OnPacketFromLobbyReceived(Packets packetId, Packet packet, ushort playerId)
		{
			//IL_0001: 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_000c: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			base.OnPacketFromLobbyReceived(packetId, packet, playerId);
			if ((int)packetId == 38 && playerId == Lobby.LobbyState.HostId)
			{
				_durationMinutes = ((ClientScoreBattleLength)((packet is ClientScoreBattleLength) ? packet : null)).Minutes;
			}
			if (_state != States.Main)
			{
				return;
			}
			if ((int)packetId != 20)
			{
				if ((int)packetId == 33 && ComboBased && !_clientsFinishedCombo.Contains(playerId))
				{
					ServerLobbyManager.SendPacketToLobby((Packet)new ServerChat(TMPFilter.CloseAllTags(BRCServer.Instance.Players[playerId].ClientState.Name), "{0} landed their combo!", BRCServer.Instance.Players[playerId].ClientState.User.Badges, (ChatMessageTypes)2), (SendModes)2, Lobby.LobbyState.Id, (NetChannels)1);
					_clientsFinishedCombo.Add(playerId);
					ServerLobbyManager.SetPlayerScore(playerId, ((ClientComboOver)packet).Score);
				}
			}
			else if (!_clientsFinishedCombo.Contains(playerId))
			{
				ClientGamemodeScore val = (ClientGamemodeScore)packet;
				ServerLobbyManager.SetPlayerScore(playerId, val.Score);
			}
		}
	}
	public class TeamGraffitiRace : GraffitiRace
	{
		public TeamGraffitiRace()
		{
			TeamBased = true;
		}
	}
	public class TeamProSkaterScoreBattle : ProSkaterScoreBattle
	{
		public TeamProSkaterScoreBattle()
		{
			TeamBased = true;
		}
	}
	public class TeamScoreBattle : ScoreBattle
	{
		public TeamScoreBattle()
		{
			TeamBased = true;
		}
	}
}

LiteNetLib.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using LiteNetLib.Layers;
using LiteNetLib.Utils;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Ruslan Pyrch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2024 Ruslan Pyrch")]
[assembly: AssemblyDescription("Lite reliable UDP library for .NET, Mono, and .NET Core")]
[assembly: AssemblyFileVersion("1.3.1")]
[assembly: AssemblyInformationalVersion("1.0.0+f57b9eafe72b924681a371d671af911478b6ab88")]
[assembly: AssemblyProduct("LiteNetLib")]
[assembly: AssemblyTitle("LiteNetLib")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/RevenantX/LiteNetLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.1.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
}
namespace LiteNetLib
{
	internal abstract class BaseChannel
	{
		protected readonly NetPeer Peer;

		protected readonly Queue<NetPacket> OutgoingQueue = new Queue<NetPacket>(64);

		private int _isAddedToPeerChannelSendQueue;

		public int PacketsInQueue => OutgoingQueue.Count;

		protected BaseChannel(NetPeer peer)
		{
			Peer = peer;
		}

		public void AddToQueue(NetPacket packet)
		{
			lock (OutgoingQueue)
			{
				OutgoingQueue.Enqueue(packet);
			}
			AddToPeerChannelSendQueue();
		}

		protected void AddToPeerChannelSendQueue()
		{
			if (Interlocked.CompareExchange(ref _isAddedToPeerChannelSendQueue, 1, 0) == 0)
			{
				Peer.AddToReliableChannelSendQueue(this);
			}
		}

		public bool SendAndCheckQueue()
		{
			bool num = SendNextPackets();
			if (!num)
			{
				Interlocked.Exchange(ref _isAddedToPeerChannelSendQueue, 0);
			}
			return num;
		}

		protected abstract bool SendNextPackets();

		public abstract bool ProcessPacket(NetPacket packet);
	}
	internal enum ConnectionRequestResult
	{
		None,
		Accept,
		Reject,
		RejectForce
	}
	public class ConnectionRequest
	{
		private readonly NetManager _listener;

		private int _used;

		internal NetConnectRequestPacket InternalPacket;

		public readonly IPEndPoint RemoteEndPoint;

		public NetDataReader Data => InternalPacket.Data;

		internal ConnectionRequestResult Result { get; private set; }

		internal void UpdateRequest(NetConnectRequestPacket connectRequest)
		{
			if (connectRequest.ConnectionTime >= InternalPacket.ConnectionTime && (connectRequest.ConnectionTime != InternalPacket.ConnectionTime || connectRequest.ConnectionNumber != InternalPacket.ConnectionNumber))
			{
				InternalPacket = connectRequest;
			}
		}

		private bool TryActivate()
		{
			return Interlocked.CompareExchange(ref _used, 1, 0) == 0;
		}

		internal ConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacket requestPacket, NetManager listener)
		{
			InternalPacket = requestPacket;
			RemoteEndPoint = remoteEndPoint;
			_listener = listener;
		}

		public NetPeer AcceptIfKey(string key)
		{
			if (!TryActivate())
			{
				return null;
			}
			try
			{
				if (Data.GetString() == key)
				{
					Result = ConnectionRequestResult.Accept;
				}
			}
			catch
			{
				NetDebug.WriteError("[AC] Invalid incoming data");
			}
			if (Result == ConnectionRequestResult.Accept)
			{
				return _listener.OnConnectionSolved(this, null, 0, 0);
			}
			Result = ConnectionRequestResult.Reject;
			_listener.OnConnectionSolved(this, null, 0, 0);
			return null;
		}

		public NetPeer Accept()
		{
			if (!TryActivate())
			{
				return null;
			}
			Result = ConnectionRequestResult.Accept;
			return _listener.OnConnectionSolved(this, null, 0, 0);
		}

		public void Reject(byte[] rejectData, int start, int length, bool force)
		{
			if (TryActivate())
			{
				Result = (force ? ConnectionRequestResult.RejectForce : ConnectionRequestResult.Reject);
				_listener.OnConnectionSolved(this, rejectData, start, length);
			}
		}

		public void Reject(byte[] rejectData, int start, int length)
		{
			Reject(rejectData, start, length, force: false);
		}

		public void RejectForce(byte[] rejectData, int start, int length)
		{
			Reject(rejectData, start, length, force: true);
		}

		public void RejectForce()
		{
			Reject(null, 0, 0, force: true);
		}

		public void RejectForce(byte[] rejectData)
		{
			Reject(rejectData, 0, rejectData.Length, force: true);
		}

		public void RejectForce(NetDataWriter rejectData)
		{
			Reject(rejectData.Data, 0, rejectData.Length, force: true);
		}

		public void Reject()
		{
			Reject(null, 0, 0, force: false);
		}

		public void Reject(byte[] rejectData)
		{
			Reject(rejectData, 0, rejectData.Length, force: false);
		}

		public void Reject(NetDataWriter rejectData)
		{
			Reject(rejectData.Data, 0, rejectData.Length, force: false);
		}
	}
	public enum UnconnectedMessageType
	{
		BasicMessage,
		Broadcast
	}
	public enum DisconnectReason
	{
		ConnectionFailed,
		Timeout,
		HostUnreachable,
		NetworkUnreachable,
		RemoteConnectionClose,
		DisconnectPeerCalled,
		ConnectionRejected,
		InvalidProtocol,
		UnknownHost,
		Reconnect,
		PeerToPeerConnection,
		PeerNotFound
	}
	public struct DisconnectInfo
	{
		public DisconnectReason Reason;

		public SocketError SocketErrorCode;

		public NetPacketReader AdditionalData;
	}
	public interface INetEventListener
	{
		void OnPeerConnected(NetPeer peer);

		void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo);

		void OnNetworkError(IPEndPoint endPoint, SocketError socketError);

		void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod);

		void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType);

		void OnNetworkLatencyUpdate(NetPeer peer, int latency);

		void OnConnectionRequest(ConnectionRequest request);
	}
	public interface IDeliveryEventListener
	{
		void OnMessageDelivered(NetPeer peer, object userData);
	}
	public interface INtpEventListener
	{
		void OnNtpResponse(NtpPacket packet);
	}
	public interface IPeerAddressChangedListener
	{
		void OnPeerAddressChanged(NetPeer peer, IPEndPoint previousAddress);
	}
	public class EventBasedNetListener : INetEventListener, IDeliveryEventListener, INtpEventListener, IPeerAddressChangedListener
	{
		public delegate void OnPeerConnected(NetPeer peer);

		public delegate void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo);

		public delegate void OnNetworkError(IPEndPoint endPoint, SocketError socketError);

		public delegate void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod);

		public delegate void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType);

		public delegate void OnNetworkLatencyUpdate(NetPeer peer, int latency);

		public delegate void OnConnectionRequest(ConnectionRequest request);

		public delegate void OnDeliveryEvent(NetPeer peer, object userData);

		public delegate void OnNtpResponseEvent(NtpPacket packet);

		public delegate void OnPeerAddressChangedEvent(NetPeer peer, IPEndPoint previousAddress);

		public event OnPeerConnected PeerConnectedEvent;

		public event OnPeerDisconnected PeerDisconnectedEvent;

		public event OnNetworkError NetworkErrorEvent;

		public event OnNetworkReceive NetworkReceiveEvent;

		public event OnNetworkReceiveUnconnected NetworkReceiveUnconnectedEvent;

		public event OnNetworkLatencyUpdate NetworkLatencyUpdateEvent;

		public event OnConnectionRequest ConnectionRequestEvent;

		public event OnDeliveryEvent DeliveryEvent;

		public event OnNtpResponseEvent NtpResponseEvent;

		public event OnPeerAddressChangedEvent PeerAddressChangedEvent;

		public void ClearPeerConnectedEvent()
		{
			this.PeerConnectedEvent = null;
		}

		public void ClearPeerDisconnectedEvent()
		{
			this.PeerDisconnectedEvent = null;
		}

		public void ClearNetworkErrorEvent()
		{
			this.NetworkErrorEvent = null;
		}

		public void ClearNetworkReceiveEvent()
		{
			this.NetworkReceiveEvent = null;
		}

		public void ClearNetworkReceiveUnconnectedEvent()
		{
			this.NetworkReceiveUnconnectedEvent = null;
		}

		public void ClearNetworkLatencyUpdateEvent()
		{
			this.NetworkLatencyUpdateEvent = null;
		}

		public void ClearConnectionRequestEvent()
		{
			this.ConnectionRequestEvent = null;
		}

		public void ClearDeliveryEvent()
		{
			this.DeliveryEvent = null;
		}

		public void ClearNtpResponseEvent()
		{
			this.NtpResponseEvent = null;
		}

		public void ClearPeerAddressChangedEvent()
		{
			this.PeerAddressChangedEvent = null;
		}

		void INetEventListener.OnPeerConnected(NetPeer peer)
		{
			if (this.PeerConnectedEvent != null)
			{
				this.PeerConnectedEvent(peer);
			}
		}

		void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
		{
			if (this.PeerDisconnectedEvent != null)
			{
				this.PeerDisconnectedEvent(peer, disconnectInfo);
			}
		}

		void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode)
		{
			if (this.NetworkErrorEvent != null)
			{
				this.NetworkErrorEvent(endPoint, socketErrorCode);
			}
		}

		void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod)
		{
			if (this.NetworkReceiveEvent != null)
			{
				this.NetworkReceiveEvent(peer, reader, channelNumber, deliveryMethod);
			}
		}

		void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
		{
			if (this.NetworkReceiveUnconnectedEvent != null)
			{
				this.NetworkReceiveUnconnectedEvent(remoteEndPoint, reader, messageType);
			}
		}

		void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency)
		{
			if (this.NetworkLatencyUpdateEvent != null)
			{
				this.NetworkLatencyUpdateEvent(peer, latency);
			}
		}

		void INetEventListener.OnConnectionRequest(ConnectionRequest request)
		{
			if (this.ConnectionRequestEvent != null)
			{
				this.ConnectionRequestEvent(request);
			}
		}

		void IDeliveryEventListener.OnMessageDelivered(NetPeer peer, object userData)
		{
			if (this.DeliveryEvent != null)
			{
				this.DeliveryEvent(peer, userData);
			}
		}

		void INtpEventListener.OnNtpResponse(NtpPacket packet)
		{
			if (this.NtpResponseEvent != null)
			{
				this.NtpResponseEvent(packet);
			}
		}

		void IPeerAddressChangedListener.OnPeerAddressChanged(NetPeer peer, IPEndPoint previousAddress)
		{
			if (this.PeerAddressChangedEvent != null)
			{
				this.PeerAddressChangedEvent(peer, previousAddress);
			}
		}
	}
	internal sealed class NetConnectRequestPacket
	{
		public const int HeaderSize = 18;

		public readonly long ConnectionTime;

		public byte ConnectionNumber;

		public readonly byte[] TargetAddress;

		public readonly NetDataReader Data;

		public readonly int PeerId;

		private NetConnectRequestPacket(long connectionTime, byte connectionNumber, int localId, byte[] targetAddress, NetDataReader data)
		{
			ConnectionTime = connectionTime;
			ConnectionNumber = connectionNumber;
			TargetAddress = targetAddress;
			Data = data;
			PeerId = localId;
		}

		public static int GetProtocolId(NetPacket packet)
		{
			return BitConverter.ToInt32(packet.RawData, 1);
		}

		public static NetConnectRequestPacket FromData(NetPacket packet)
		{
			if (packet.ConnectionNumber >= 4)
			{
				return null;
			}
			long connectionTime = BitConverter.ToInt64(packet.RawData, 5);
			int localId = BitConverter.ToInt32(packet.RawData, 13);
			int num = packet.RawData[17];
			if (num != 16 && num != 28)
			{
				return null;
			}
			byte[] array = new byte[num];
			Buffer.BlockCopy(packet.RawData, 18, array, 0, num);
			NetDataReader netDataReader = new NetDataReader(null, 0, 0);
			if (packet.Size > 18 + num)
			{
				netDataReader.SetSource(packet.RawData, 18 + num, packet.Size);
			}
			return new NetConnectRequestPacket(connectionTime, packet.ConnectionNumber, localId, array, netDataReader);
		}

		public static NetPacket Make(NetDataWriter connectData, SocketAddress addressBytes, long connectTime, int localId)
		{
			NetPacket netPacket = new NetPacket(PacketProperty.ConnectRequest, connectData.Length + addressBytes.Size);
			FastBitConverter.GetBytes(netPacket.RawData, 1, 13);
			FastBitConverter.GetBytes(netPacket.RawData, 5, connectTime);
			FastBitConverter.GetBytes(netPacket.RawData, 13, localId);
			netPacket.RawData[17] = (byte)addressBytes.Size;
			for (int i = 0; i < addressBytes.Size; i++)
			{
				netPacket.RawData[18 + i] = addressBytes[i];
			}
			Buffer.BlockCopy(connectData.Data, 0, netPacket.RawData, 18 + addressBytes.Size, connectData.Length);
			return netPacket;
		}
	}
	internal sealed class NetConnectAcceptPacket
	{
		public const int Size = 15;

		public readonly long ConnectionTime;

		public readonly byte ConnectionNumber;

		public readonly int PeerId;

		public readonly bool PeerNetworkChanged;

		private NetConnectAcceptPacket(long connectionTime, byte connectionNumber, int peerId, bool peerNetworkChanged)
		{
			ConnectionTime = connectionTime;
			ConnectionNumber = connectionNumber;
			PeerId = peerId;
			PeerNetworkChanged = peerNetworkChanged;
		}

		public static NetConnectAcceptPacket FromData(NetPacket packet)
		{
			if (packet.Size != 15)
			{
				return null;
			}
			long connectionTime = BitConverter.ToInt64(packet.RawData, 1);
			byte b = packet.RawData[9];
			if (b >= 4)
			{
				return null;
			}
			byte b2 = packet.RawData[10];
			if (b2 > 1)
			{
				return null;
			}
			int num = BitConverter.ToInt32(packet.RawData, 11);
			if (num < 0)
			{
				return null;
			}
			return new NetConnectAcceptPacket(connectionTime, b, num, b2 == 1);
		}

		public static NetPacket Make(long connectTime, byte connectNum, int localPeerId)
		{
			NetPacket netPacket = new NetPacket(PacketProperty.ConnectAccept, 0);
			FastBitConverter.GetBytes(netPacket.RawData, 1, connectTime);
			netPacket.RawData[9] = connectNum;
			FastBitConverter.GetBytes(netPacket.RawData, 11, localPeerId);
			return netPacket;
		}

		public static NetPacket MakeNetworkChanged(NetPeer peer)
		{
			NetPacket netPacket = new NetPacket(PacketProperty.PeerNotFound, 14);
			FastBitConverter.GetBytes(netPacket.RawData, 1, peer.ConnectTime);
			netPacket.RawData[9] = peer.ConnectionNum;
			netPacket.RawData[10] = 1;
			FastBitConverter.GetBytes(netPacket.RawData, 11, peer.RemoteId);
			return netPacket;
		}
	}
	internal static class NativeSocket
	{
		private static class WinSock
		{
			private const string LibName = "ws2_32.dll";

			[DllImport("ws2_32.dll", SetLastError = true)]
			public static extern int recvfrom(IntPtr socketHandle, [In][Out] byte[] pinnedBuffer, [In] int len, [In] SocketFlags socketFlags, [Out] byte[] socketAddress, [In][Out] ref int socketAddressSize);

			[DllImport("ws2_32.dll", SetLastError = true)]
			internal unsafe static extern int sendto(IntPtr socketHandle, byte* pinnedBuffer, [In] int len, [In] SocketFlags socketFlags, [In] byte[] socketAddress, [In] int socketAddressSize);
		}

		private static class UnixSock
		{
			private const string LibName = "libc";

			[DllImport("libc", SetLastError = true)]
			public static extern int recvfrom(IntPtr socketHandle, [In][Out] byte[] pinnedBuffer, [In] int len, [In] SocketFlags socketFlags, [Out] byte[] socketAddress, [In][Out] ref int socketAddressSize);

			[DllImport("libc", SetLastError = true)]
			internal unsafe static extern int sendto(IntPtr socketHandle, byte* pinnedBuffer, [In] int len, [In] SocketFlags socketFlags, [In] byte[] socketAddress, [In] int socketAddressSize);
		}

		public static readonly bool IsSupported;

		public static readonly bool UnixMode;

		public const int IPv4AddrSize = 16;

		public const int IPv6AddrSize = 28;

		public const int AF_INET = 2;

		public const int AF_INET6 = 10;

		private static readonly Dictionary<int, SocketError> NativeErrorToSocketError;

		static NativeSocket()
		{
			IsSupported = false;
			UnixMode = false;
			NativeErrorToSocketError = new Dictionary<int, SocketError>
			{
				{
					13,
					SocketError.AccessDenied
				},
				{
					98,
					SocketError.AddressAlreadyInUse
				},
				{
					99,
					SocketError.AddressNotAvailable
				},
				{
					97,
					SocketError.AddressFamilyNotSupported
				},
				{
					11,
					SocketError.WouldBlock
				},
				{
					114,
					SocketError.AlreadyInProgress
				},
				{
					9,
					SocketError.OperationAborted
				},
				{
					125,
					SocketError.OperationAborted
				},
				{
					103,
					SocketError.ConnectionAborted
				},
				{
					111,
					SocketError.ConnectionRefused
				},
				{
					104,
					SocketError.ConnectionReset
				},
				{
					89,
					SocketError.DestinationAddressRequired
				},
				{
					14,
					SocketError.Fault
				},
				{
					112,
					SocketError.HostDown
				},
				{
					6,
					SocketError.HostNotFound
				},
				{
					113,
					SocketError.HostUnreachable
				},
				{
					115,
					SocketError.InProgress
				},
				{
					4,
					SocketError.Interrupted
				},
				{
					22,
					SocketError.InvalidArgument
				},
				{
					106,
					SocketError.IsConnected
				},
				{
					24,
					SocketError.TooManyOpenSockets
				},
				{
					90,
					SocketError.MessageSize
				},
				{
					100,
					SocketError.NetworkDown
				},
				{
					102,
					SocketError.NetworkReset
				},
				{
					101,
					SocketError.NetworkUnreachable
				},
				{
					23,
					SocketError.TooManyOpenSockets
				},
				{
					105,
					SocketError.NoBufferSpaceAvailable
				},
				{
					61,
					SocketError.NoData
				},
				{
					2,
					SocketError.AddressNotAvailable
				},
				{
					92,
					SocketError.ProtocolOption
				},
				{
					107,
					SocketError.NotConnected
				},
				{
					88,
					SocketError.NotSocket
				},
				{
					3440,
					SocketError.OperationNotSupported
				},
				{
					1,
					SocketError.AccessDenied
				},
				{
					32,
					SocketError.Shutdown
				},
				{
					96,
					SocketError.ProtocolFamilyNotSupported
				},
				{
					93,
					SocketError.ProtocolNotSupported
				},
				{
					91,
					SocketError.ProtocolType
				},
				{
					94,
					SocketError.SocketNotSupported
				},
				{
					108,
					SocketError.Disconnecting
				},
				{
					110,
					SocketError.TimedOut
				},
				{
					0,
					SocketError.Success
				}
			};
			if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
			{
				IsSupported = true;
				UnixMode = true;
			}
			else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
			{
				IsSupported = true;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int RecvFrom(IntPtr socketHandle, byte[] pinnedBuffer, int len, byte[] socketAddress, ref int socketAddressSize)
		{
			if (!UnixMode)
			{
				return WinSock.recvfrom(socketHandle, pinnedBuffer, len, SocketFlags.None, socketAddress, ref socketAddressSize);
			}
			return UnixSock.recvfrom(socketHandle, pinnedBuffer, len, SocketFlags.None, socketAddress, ref socketAddressSize);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int SendTo(IntPtr socketHandle, byte* pinnedBuffer, int len, byte[] socketAddress, int socketAddressSize)
		{
			if (!UnixMode)
			{
				return WinSock.sendto(socketHandle, pinnedBuffer, len, SocketFlags.None, socketAddress, socketAddressSize);
			}
			return UnixSock.sendto(socketHandle, pinnedBuffer, len, SocketFlags.None, socketAddress, socketAddressSize);
		}

		public static SocketError GetSocketError()
		{
			int lastWin32Error = Marshal.GetLastWin32Error();
			if (UnixMode)
			{
				if (!NativeErrorToSocketError.TryGetValue(lastWin32Error, out var value))
				{
					return SocketError.SocketError;
				}
				return value;
			}
			return (SocketError)lastWin32Error;
		}

		public static SocketException GetSocketException()
		{
			int lastWin32Error = Marshal.GetLastWin32Error();
			if (UnixMode)
			{
				if (!NativeErrorToSocketError.TryGetValue(lastWin32Error, out var value))
				{
					return new SocketException(-1);
				}
				return new SocketException((int)value);
			}
			return new SocketException(lastWin32Error);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static short GetNativeAddressFamily(IPEndPoint remoteEndPoint)
		{
			if (!UnixMode)
			{
				return (short)remoteEndPoint.AddressFamily;
			}
			return (short)((remoteEndPoint.AddressFamily == AddressFamily.InterNetwork) ? 2 : 10);
		}
	}
	public enum NatAddressType
	{
		Internal,
		External
	}
	public interface INatPunchListener
	{
		void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token);

		void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token);
	}
	public class EventBasedNatPunchListener : INatPunchListener
	{
		public delegate void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token);

		public delegate void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token);

		public event OnNatIntroductionRequest NatIntroductionRequest;

		public event OnNatIntroductionSuccess NatIntroductionSuccess;

		void INatPunchListener.OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token)
		{
			if (this.NatIntroductionRequest != null)
			{
				this.NatIntroductionRequest(localEndPoint, remoteEndPoint, token);
			}
		}

		void INatPunchListener.OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token)
		{
			if (this.NatIntroductionSuccess != null)
			{
				this.NatIntroductionSuccess(targetEndPoint, type, token);
			}
		}
	}
	public sealed class NatPunchModule
	{
		private struct RequestEventData
		{
			public IPEndPoint LocalEndPoint;

			public IPEndPoint RemoteEndPoint;

			public string Token;
		}

		private struct SuccessEventData
		{
			public IPEndPoint TargetEndPoint;

			public NatAddressType Type;

			public string Token;
		}

		private class NatIntroduceRequestPacket
		{
			public IPEndPoint Internal
			{
				[Preserve]
				get;
				[Preserve]
				set;
			}

			public string Token
			{
				[Preserve]
				get;
				[Preserve]
				set;
			}
		}

		private class NatIntroduceResponsePacket
		{
			public IPEndPoint Internal
			{
				[Preserve]
				get;
				[Preserve]
				set;
			}

			public IPEndPoint External
			{
				[Preserve]
				get;
				[Preserve]
				set;
			}

			public string Token
			{
				[Preserve]
				get;
				[Preserve]
				set;
			}
		}

		private class NatPunchPacket
		{
			public string Token
			{
				[Preserve]
				get;
				[Preserve]
				set;
			}

			public bool IsExternal
			{
				[Preserve]
				get;
				[Preserve]
				set;
			}
		}

		private readonly NetManager _socket;

		private readonly ConcurrentQueue<RequestEventData> _requestEvents = new ConcurrentQueue<RequestEventData>();

		private readonly ConcurrentQueue<SuccessEventData> _successEvents = new ConcurrentQueue<SuccessEventData>();

		private readonly NetDataReader _cacheReader = new NetDataReader();

		private readonly NetDataWriter _cacheWriter = new NetDataWriter();

		private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(256);

		private INatPunchListener _natPunchListener;

		public const int MaxTokenLength = 256;

		public bool UnsyncedEvents;

		internal NatPunchModule(NetManager socket)
		{
			_socket = socket;
			_netPacketProcessor.SubscribeReusable<NatIntroduceResponsePacket>(OnNatIntroductionResponse);
			_netPacketProcessor.SubscribeReusable<NatIntroduceRequestPacket, IPEndPoint>(OnNatIntroductionRequest);
			_netPacketProcessor.SubscribeReusable<NatPunchPacket, IPEndPoint>(OnNatPunch);
		}

		internal void ProcessMessage(IPEndPoint senderEndPoint, NetPacket packet)
		{
			lock (_cacheReader)
			{
				_cacheReader.SetSource(packet.RawData, 1, packet.Size);
				_netPacketProcessor.ReadAllPackets(_cacheReader, senderEndPoint);
			}
		}

		public void Init(INatPunchListener listener)
		{
			_natPunchListener = listener;
		}

		private void Send<T>(T packet, IPEndPoint target) where T : class, new()
		{
			_cacheWriter.Reset();
			_cacheWriter.Put((byte)16);
			_netPacketProcessor.Write(_cacheWriter, packet);
			_socket.SendRaw(_cacheWriter.Data, 0, _cacheWriter.Length, target);
		}

		public void NatIntroduce(IPEndPoint hostInternal, IPEndPoint hostExternal, IPEndPoint clientInternal, IPEndPoint clientExternal, string additionalInfo)
		{
			NatIntroduceResponsePacket natIntroduceResponsePacket = new NatIntroduceResponsePacket
			{
				Token = additionalInfo
			};
			natIntroduceResponsePacket.Internal = hostInternal;
			natIntroduceResponsePacket.External = hostExternal;
			Send(natIntroduceResponsePacket, clientExternal);
			natIntroduceResponsePacket.Internal = clientInternal;
			natIntroduceResponsePacket.External = clientExternal;
			Send(natIntroduceResponsePacket, hostExternal);
		}

		public void PollEvents()
		{
			if (!UnsyncedEvents && _natPunchListener != null && (!_successEvents.IsEmpty || !_requestEvents.IsEmpty))
			{
				SuccessEventData result;
				while (_successEvents.TryDequeue(out result))
				{
					_natPunchListener.OnNatIntroductionSuccess(result.TargetEndPoint, result.Type, result.Token);
				}
				RequestEventData result2;
				while (_requestEvents.TryDequeue(out result2))
				{
					_natPunchListener.OnNatIntroductionRequest(result2.LocalEndPoint, result2.RemoteEndPoint, result2.Token);
				}
			}
		}

		public void SendNatIntroduceRequest(string host, int port, string additionalInfo)
		{
			SendNatIntroduceRequest(NetUtils.MakeEndPoint(host, port), additionalInfo);
		}

		public void SendNatIntroduceRequest(IPEndPoint masterServerEndPoint, string additionalInfo)
		{
			string localIp = NetUtils.GetLocalIp(LocalAddrType.IPv4);
			if (string.IsNullOrEmpty(localIp) || masterServerEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
			{
				localIp = NetUtils.GetLocalIp(LocalAddrType.IPv6);
			}
			Send(new NatIntroduceRequestPacket
			{
				Internal = NetUtils.MakeEndPoint(localIp, _socket.LocalPort),
				Token = additionalInfo
			}, masterServerEndPoint);
		}

		private void OnNatIntroductionRequest(NatIntroduceRequestPacket req, IPEndPoint senderEndPoint)
		{
			if (UnsyncedEvents)
			{
				_natPunchListener.OnNatIntroductionRequest(req.Internal, senderEndPoint, req.Token);
				return;
			}
			_requestEvents.Enqueue(new RequestEventData
			{
				LocalEndPoint = req.Internal,
				RemoteEndPoint = senderEndPoint,
				Token = req.Token
			});
		}

		private void OnNatIntroductionResponse(NatIntroduceResponsePacket req)
		{
			NatPunchPacket natPunchPacket = new NatPunchPacket
			{
				Token = req.Token
			};
			Send(natPunchPacket, req.Internal);
			_socket.Ttl = 2;
			_socket.SendRaw(new byte[1] { 17 }, 0, 1, req.External);
			_socket.Ttl = 255;
			natPunchPacket.IsExternal = true;
			Send(natPunchPacket, req.External);
		}

		private void OnNatPunch(NatPunchPacket req, IPEndPoint senderEndPoint)
		{
			if (UnsyncedEvents)
			{
				_natPunchListener.OnNatIntroductionSuccess(senderEndPoint, req.IsExternal ? NatAddressType.External : NatAddressType.Internal, req.Token);
				return;
			}
			_successEvents.Enqueue(new SuccessEventData
			{
				TargetEndPoint = senderEndPoint,
				Type = (req.IsExternal ? NatAddressType.External : NatAddressType.Internal),
				Token = req.Token
			});
		}
	}
	public enum DeliveryMethod : byte
	{
		Unreliable = 4,
		ReliableUnordered = 0,
		Sequenced = 1,
		ReliableOrdered = 2,
		ReliableSequenced = 3
	}
	public static class NetConstants
	{
		public const int DefaultWindowSize = 64;

		public const int SocketBufferSize = 1048576;

		public const int SocketTTL = 255;

		public const int HeaderSize = 1;

		public const int ChanneledHeaderSize = 4;

		public const int FragmentHeaderSize = 6;

		public const int FragmentedHeaderTotalSize = 10;

		public const ushort MaxSequence = 32768;

		public const ushort HalfMaxSequence = 16384;

		internal const int ProtocolId = 13;

		internal const int MaxUdpHeaderSize = 68;

		internal const int ChannelTypeCount = 4;

		internal static readonly int[] PossibleMtu = new int[6] { 1024, 1164, 1392, 1404, 1424, 1432 };

		public static readonly int InitialMtu = PossibleMtu[0];

		public static readonly int MaxPacketSize = PossibleMtu[PossibleMtu.Length - 1];

		public static readonly int MaxUnreliableDataSize = MaxPacketSize - 1;

		public const byte MaxConnectionNumber = 4;
	}
	public class InvalidPacketException : ArgumentException
	{
		public InvalidPacketException(string message)
			: base(message)
		{
		}
	}
	public class TooBigPacketException : InvalidPacketException
	{
		public TooBigPacketException(string message)
			: base(message)
		{
		}
	}
	public enum NetLogLevel
	{
		Warning,
		Error,
		Trace,
		Info
	}
	public interface INetLogger
	{
		void WriteNet(NetLogLevel level, string str, params object[] args);
	}
	public static class NetDebug
	{
		public static INetLogger Logger = null;

		private static readonly object DebugLogLock = new object();

		private static void WriteLogic(NetLogLevel logLevel, string str, params object[] args)
		{
			lock (DebugLogLock)
			{
				if (Logger == null)
				{
					Console.WriteLine(str, args);
				}
				else
				{
					Logger.WriteNet(logLevel, str, args);
				}
			}
		}

		[Conditional("DEBUG_MESSAGES")]
		internal static void Write(string str)
		{
			WriteLogic(NetLogLevel.Trace, str);
		}

		[Conditional("DEBUG_MESSAGES")]
		internal static void Write(NetLogLevel level, string str)
		{
			WriteLogic(level, str);
		}

		[Conditional("DEBUG_MESSAGES")]
		[Conditional("DEBUG")]
		internal static void WriteForce(string str)
		{
			WriteLogic(NetLogLevel.Trace, str);
		}

		[Conditional("DEBUG_MESSAGES")]
		[Conditional("DEBUG")]
		internal static void WriteForce(NetLogLevel level, string str)
		{
			WriteLogic(level, str);
		}

		internal static void WriteError(string str)
		{
			WriteLogic(NetLogLevel.Error, str);
		}
	}
	public sealed class NetPacketReader : NetDataReader
	{
		private NetPacket _packet;

		private readonly NetManager _manager;

		private readonly NetEvent _evt;

		internal NetPacketReader(NetManager manager, NetEvent evt)
		{
			_manager = manager;
			_evt = evt;
		}

		internal void SetSource(NetPacket packet, int headerSize)
		{
			if (packet != null)
			{
				_packet = packet;
				SetSource(packet.RawData, headerSize, packet.Size);
			}
		}

		internal void RecycleInternal()
		{
			Clear();
			if (_packet != null)
			{
				_manager.PoolRecycle(_packet);
			}
			_packet = null;
			_manager.RecycleEvent(_evt);
		}

		public void Recycle()
		{
			if (!_manager.AutoRecycle)
			{
				RecycleInternal();
			}
		}
	}
	internal sealed class NetEvent
	{
		public enum EType
		{
			Connect,
			Disconnect,
			Receive,
			ReceiveUnconnected,
			Error,
			ConnectionLatencyUpdated,
			Broadcast,
			ConnectionRequest,
			MessageDelivered,
			PeerAddressChanged
		}

		public NetEvent Next;

		public EType Type;

		public NetPeer Peer;

		public IPEndPoint RemoteEndPoint;

		public object UserData;

		public int Latency;

		public SocketError ErrorCode;

		public DisconnectReason DisconnectReason;

		public ConnectionRequest ConnectionRequest;

		public DeliveryMethod DeliveryMethod;

		public byte ChannelNumber;

		public readonly NetPacketReader DataReader;

		public NetEvent(NetManager manager)
		{
			DataReader = new NetPacketReader(manager, this);
		}
	}
	public class NetManager : IEnumerable<NetPeer>, IEnumerable
	{
		public struct NetPeerEnumerator : IEnumerator<NetPeer>, IEnumerator, IDisposable
		{
			private readonly NetPeer _initialPeer;

			private NetPeer _p;

			public NetPeer Current => _p;

			object IEnumerator.Current => _p;

			public NetPeerEnumerator(NetPeer p)
			{
				_initialPeer = p;
				_p = null;
			}

			public void Dispose()
			{
			}

			public bool MoveNext()
			{
				_p = ((_p == null) ? _initialPeer : _p.NextPeer);
				return _p != null;
			}

			public void Reset()
			{
				throw new NotSupportedException();
			}
		}

		private struct IncomingData
		{
			public NetPacket Data;

			public IPEndPoint EndPoint;

			public DateTime TimeWhenGet;
		}

		private struct Slot
		{
			internal int HashCode;

			internal int Next;

			internal NetPeer Value;
		}

		private readonly List<IncomingData> _pingSimulationList = new List<IncomingData>();

		private readonly Random _randomGenerator = new Random();

		private const int MinLatencyThreshold = 5;

		private Thread _logicThread;

		private bool _manualMode;

		private readonly AutoResetEvent _updateTriggerEvent = new AutoResetEvent(initialState: true);

		private NetEvent _pendingEventHead;

		private NetEvent _pendingEventTail;

		private NetEvent _netEventPoolHead;

		private readonly INetEventListener _netEventListener;

		private readonly IDeliveryEventListener _deliveryEventListener;

		private readonly INtpEventListener _ntpEventListener;

		private readonly IPeerAddressChangedListener _peerAddressChangedListener;

		private readonly Dictionary<IPEndPoint, ConnectionRequest> _requestsDict = new Dictionary<IPEndPoint, ConnectionRequest>();

		private readonly ConcurrentDictionary<IPEndPoint, NtpRequest> _ntpRequests = new ConcurrentDictionary<IPEndPoint, NtpRequest>();

		private long _connectedPeersCount;

		private readonly List<NetPeer> _connectedPeerListCache = new List<NetPeer>();

		private readonly PacketLayerBase _extraPacketLayer;

		private int _lastPeerId;

		private ConcurrentQueue<int> _peerIds = new ConcurrentQueue<int>();

		private byte _channelsCount = 1;

		private readonly object _eventLock = new object();

		private bool _dropPacket;

		public bool UnconnectedMessagesEnabled;

		public bool NatPunchEnabled;

		public int UpdateTime = 15;

		public int PingInterval = 1000;

		public int DisconnectTimeout = 5000;

		public bool SimulatePacketLoss;

		public bool SimulateLatency;

		public int SimulationPacketLossChance = 10;

		public int SimulationMinLatency = 30;

		public int SimulationMaxLatency = 100;

		public bool UnsyncedEvents;

		public bool UnsyncedReceiveEvent;

		public bool UnsyncedDeliveryEvent;

		public bool BroadcastReceiveEnabled;

		public int ReconnectDelay = 500;

		public int MaxConnectAttempts = 10;

		public bool ReuseAddress;

		public bool DontRoute;

		public readonly NetStatistics Statistics = new NetStatistics();

		public bool EnableStatistics;

		public readonly NatPunchModule NatPunchModule;

		public bool AutoRecycle;

		public bool IPv6Enabled = true;

		public int MtuOverride;

		public bool MtuDiscovery;

		public bool UseNativeSockets;

		public bool DisconnectOnUnreachable;

		public bool AllowPeerAddressChange;

		private const int MaxPrimeArrayLength = 2147483587;

		private const int HashPrime = 101;

		private const int Lower31BitMask = int.MaxValue;

		private static readonly int[] Primes;

		private int[] _buckets;

		private Slot[] _slots;

		private int _count;

		private int _lastIndex;

		private int _freeList = -1;

		private NetPeer[] _peersArray = new NetPeer[32];

		private readonly ReaderWriterLockSlim _peersLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);

		private volatile NetPeer _headPeer;

		private NetPacket _poolHead;

		private int _poolCount;

		private readonly object _poolLock = new object();

		public int PacketPoolSize = 1000;

		private const int ReceivePollingTime = 500000;

		private Socket _udpSocketv4;

		private Socket _udpSocketv6;

		private Thread _receiveThread;

		private IPEndPoint _bufferEndPointv4;

		private IPEndPoint _bufferEndPointv6;

		private const int SioUdpConnreset = -1744830452;

		private static readonly IPAddress MulticastAddressV6;

		public static readonly bool IPv6Support;

		internal bool NotConnected;

		public bool IsRunning { get; private set; }

		public int LocalPort { get; private set; }

		public NetPeer FirstPeer => _headPeer;

		public byte ChannelsCount
		{
			get
			{
				return _channelsCount;
			}
			set
			{
				if (value < 1 || value > 64)
				{
					throw new ArgumentException("Channels count must be between 1 and 64");
				}
				_channelsCount = value;
			}
		}

		public List<NetPeer> ConnectedPeerList
		{
			get
			{
				GetPeersNonAlloc(_connectedPeerListCache, ConnectionState.Connected);
				return _connectedPeerListCache;
			}
		}

		public int ConnectedPeersCount => (int)Interlocked.Read(ref _connectedPeersCount);

		public int ExtraPacketSizeForLayer => _extraPacketLayer?.ExtraPacketSizeForLayer ?? 0;

		public int PoolCount => _poolCount;

		public short Ttl
		{
			get
			{
				return _udpSocketv4.Ttl;
			}
			internal set
			{
				_udpSocketv4.Ttl = value;
			}
		}

		public NetManager(INetEventListener listener, PacketLayerBase extraPacketLayer = null)
		{
			_netEventListener = listener;
			_deliveryEventListener = listener as IDeliveryEventListener;
			_ntpEventListener = listener as INtpEventListener;
			_peerAddressChangedListener = listener as IPeerAddressChangedListener;
			NatPunchModule = new NatPunchModule(this);
			_extraPacketLayer = extraPacketLayer;
		}

		internal void ConnectionLatencyUpdated(NetPeer fromPeer, int latency)
		{
			CreateEvent(NetEvent.EType.ConnectionLatencyUpdated, fromPeer, null, SocketError.Success, latency, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0);
		}

		internal void MessageDelivered(NetPeer fromPeer, object userData)
		{
			if (_deliveryEventListener != null)
			{
				CreateEvent(NetEvent.EType.MessageDelivered, fromPeer, null, SocketError.Success, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0, null, userData);
			}
		}

		internal void DisconnectPeerForce(NetPeer peer, DisconnectReason reason, SocketError socketErrorCode, NetPacket eventData)
		{
			DisconnectPeer(peer, reason, socketErrorCode, force: true, null, 0, 0, eventData);
		}

		private void DisconnectPeer(NetPeer peer, DisconnectReason reason, SocketError socketErrorCode, bool force, byte[] data, int start, int count, NetPacket eventData)
		{
			switch (peer.Shutdown(data, start, count, force))
			{
			case ShutdownResult.None:
				return;
			case ShutdownResult.WasConnected:
				Interlocked.Decrement(ref _connectedPeersCount);
				break;
			}
			CreateEvent(NetEvent.EType.Disconnect, peer, null, socketErrorCode, 0, reason, null, DeliveryMethod.Unreliable, 0, eventData);
		}

		private void CreateEvent(NetEvent.EType type, NetPeer peer = null, IPEndPoint remoteEndPoint = null, SocketError errorCode = SocketError.Success, int latency = 0, DisconnectReason disconnectReason = DisconnectReason.ConnectionFailed, ConnectionRequest connectionRequest = null, DeliveryMethod deliveryMethod = DeliveryMethod.Unreliable, byte channelNumber = 0, NetPacket readerSource = null, object userData = null)
		{
			bool flag = UnsyncedEvents;
			switch (type)
			{
			case NetEvent.EType.Connect:
				Interlocked.Increment(ref _connectedPeersCount);
				break;
			case NetEvent.EType.MessageDelivered:
				flag = UnsyncedDeliveryEvent;
				break;
			}
			NetEvent netEvent;
			lock (_eventLock)
			{
				netEvent = _netEventPoolHead;
				if (netEvent == null)
				{
					netEvent = new NetEvent(this);
				}
				else
				{
					_netEventPoolHead = netEvent.Next;
				}
			}
			netEvent.Next = null;
			netEvent.Type = type;
			netEvent.DataReader.SetSource(readerSource, readerSource?.GetHeaderSize() ?? 0);
			netEvent.Peer = peer;
			netEvent.RemoteEndPoint = remoteEndPoint;
			netEvent.Latency = latency;
			netEvent.ErrorCode = errorCode;
			netEvent.DisconnectReason = disconnectReason;
			netEvent.ConnectionRequest = connectionRequest;
			netEvent.DeliveryMethod = deliveryMethod;
			netEvent.ChannelNumber = channelNumber;
			netEvent.UserData = userData;
			if (flag || _manualMode)
			{
				ProcessEvent(netEvent);
				return;
			}
			lock (_eventLock)
			{
				if (_pendingEventTail == null)
				{
					_pendingEventHead = netEvent;
				}
				else
				{
					_pendingEventTail.Next = netEvent;
				}
				_pendingEventTail = netEvent;
			}
		}

		private void ProcessEvent(NetEvent evt)
		{
			bool isNull = evt.DataReader.IsNull;
			switch (evt.Type)
			{
			case NetEvent.EType.Connect:
				_netEventListener.OnPeerConnected(evt.Peer);
				break;
			case NetEvent.EType.Disconnect:
			{
				DisconnectInfo disconnectInfo = default(DisconnectInfo);
				disconnectInfo.Reason = evt.DisconnectReason;
				disconnectInfo.AdditionalData = evt.DataReader;
				disconnectInfo.SocketErrorCode = evt.ErrorCode;
				DisconnectInfo disconnectInfo2 = disconnectInfo;
				_netEventListener.OnPeerDisconnected(evt.Peer, disconnectInfo2);
				break;
			}
			case NetEvent.EType.Receive:
				_netEventListener.OnNetworkReceive(evt.Peer, evt.DataReader, evt.ChannelNumber, evt.DeliveryMethod);
				break;
			case NetEvent.EType.ReceiveUnconnected:
				_netEventListener.OnNetworkReceiveUnconnected(evt.RemoteEndPoint, evt.DataReader, UnconnectedMessageType.BasicMessage);
				break;
			case NetEvent.EType.Broadcast:
				_netEventListener.OnNetworkReceiveUnconnected(evt.RemoteEndPoint, evt.DataReader, UnconnectedMessageType.Broadcast);
				break;
			case NetEvent.EType.Error:
				_netEventListener.OnNetworkError(evt.RemoteEndPoint, evt.ErrorCode);
				break;
			case NetEvent.EType.ConnectionLatencyUpdated:
				_netEventListener.OnNetworkLatencyUpdate(evt.Peer, evt.Latency);
				break;
			case NetEvent.EType.ConnectionRequest:
				_netEventListener.OnConnectionRequest(evt.ConnectionRequest);
				break;
			case NetEvent.EType.MessageDelivered:
				_deliveryEventListener.OnMessageDelivered(evt.Peer, evt.UserData);
				break;
			case NetEvent.EType.PeerAddressChanged:
			{
				_peersLock.EnterUpgradeableReadLock();
				IPEndPoint iPEndPoint = null;
				if (ContainsPeer(evt.Peer))
				{
					_peersLock.EnterWriteLock();
					RemovePeerFromSet(evt.Peer);
					iPEndPoint = new IPEndPoint(evt.Peer.Address, evt.Peer.Port);
					evt.Peer.FinishEndPointChange(evt.RemoteEndPoint);
					AddPeerToSet(evt.Peer);
					_peersLock.ExitWriteLock();
				}
				_peersLock.ExitUpgradeableReadLock();
				if (iPEndPoint != null && _peerAddressChangedListener != null)
				{
					_peerAddressChangedListener.OnPeerAddressChanged(evt.Peer, iPEndPoint);
				}
				break;
			}
			}
			if (isNull)
			{
				RecycleEvent(evt);
			}
			else if (AutoRecycle)
			{
				evt.DataReader.RecycleInternal();
			}
		}

		internal void RecycleEvent(NetEvent evt)
		{
			evt.Peer = null;
			evt.ErrorCode = SocketError.Success;
			evt.RemoteEndPoint = null;
			evt.ConnectionRequest = null;
			lock (_eventLock)
			{
				evt.Next = _netEventPoolHead;
				_netEventPoolHead = evt;
			}
		}

		private void UpdateLogic()
		{
			List<NetPeer> list = new List<NetPeer>();
			Stopwatch stopwatch = new Stopwatch();
			stopwatch.Start();
			while (IsRunning)
			{
				try
				{
					float num = (float)((double)stopwatch.ElapsedTicks / (double)Stopwatch.Frequency * 1000.0);
					num = ((num <= 0f) ? 0.001f : num);
					stopwatch.Restart();
					for (NetPeer netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer)
					{
						if (netPeer.ConnectionState == ConnectionState.Disconnected && netPeer.TimeSinceLastPacket > (float)DisconnectTimeout)
						{
							list.Add(netPeer);
						}
						else
						{
							netPeer.Update(num);
						}
					}
					if (list.Count > 0)
					{
						_peersLock.EnterWriteLock();
						for (int i = 0; i < list.Count; i++)
						{
							RemovePeer(list[i], enableWriteLock: false);
						}
						_peersLock.ExitWriteLock();
						list.Clear();
					}
					ProcessNtpRequests(num);
					int num2 = UpdateTime - (int)stopwatch.ElapsedMilliseconds;
					if (num2 > 0)
					{
						_updateTriggerEvent.WaitOne(num2);
					}
				}
				catch (ThreadAbortException)
				{
					return;
				}
				catch (Exception ex2)
				{
					NetDebug.WriteError("[NM] LogicThread error: " + ex2);
				}
			}
			stopwatch.Stop();
		}

		[Conditional("DEBUG")]
		private void ProcessDelayedPackets()
		{
			if (!SimulateLatency)
			{
				return;
			}
			DateTime utcNow = DateTime.UtcNow;
			lock (_pingSimulationList)
			{
				for (int i = 0; i < _pingSimulationList.Count; i++)
				{
					IncomingData incomingData = _pingSimulationList[i];
					if (incomingData.TimeWhenGet <= utcNow)
					{
						HandleMessageReceived(incomingData.Data, incomingData.EndPoint);
						_pingSimulationList.RemoveAt(i);
						i--;
					}
				}
			}
		}

		private void ProcessNtpRequests(float elapsedMilliseconds)
		{
			List<IPEndPoint> list = null;
			foreach (KeyValuePair<IPEndPoint, NtpRequest> ntpRequest in _ntpRequests)
			{
				ntpRequest.Value.Send(_udpSocketv4, elapsedMilliseconds);
				if (ntpRequest.Value.NeedToKill)
				{
					if (list == null)
					{
						list = new List<IPEndPoint>();
					}
					list.Add(ntpRequest.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (IPEndPoint item in list)
			{
				_ntpRequests.TryRemove(item, out var _);
			}
		}

		public void ManualUpdate(float elapsedMilliseconds)
		{
			if (!_manualMode)
			{
				return;
			}
			for (NetPeer netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer)
			{
				if (netPeer.ConnectionState == ConnectionState.Disconnected && netPeer.TimeSinceLastPacket > (float)DisconnectTimeout)
				{
					RemovePeer(netPeer, enableWriteLock: false);
				}
				else
				{
					netPeer.Update(elapsedMilliseconds);
				}
			}
			ProcessNtpRequests(elapsedMilliseconds);
		}

		internal NetPeer OnConnectionSolved(ConnectionRequest request, byte[] rejectData, int start, int length)
		{
			NetPeer actualValue = null;
			if (request.Result == ConnectionRequestResult.RejectForce)
			{
				if (rejectData != null && length > 0)
				{
					NetPacket netPacket = PoolGetWithProperty(PacketProperty.Disconnect, length);
					netPacket.ConnectionNumber = request.InternalPacket.ConnectionNumber;
					FastBitConverter.GetBytes(netPacket.RawData, 1, request.InternalPacket.ConnectionTime);
					if (netPacket.Size >= NetConstants.PossibleMtu[0])
					{
						NetDebug.WriteError("[Peer] Disconnect additional data size more than MTU!");
					}
					else
					{
						Buffer.BlockCopy(rejectData, start, netPacket.RawData, 9, length);
					}
					SendRawAndRecycle(netPacket, request.RemoteEndPoint);
				}
				lock (_requestsDict)
				{
					_requestsDict.Remove(request.RemoteEndPoint);
				}
			}
			else
			{
				lock (_requestsDict)
				{
					if (!TryGetPeer(request.RemoteEndPoint, out actualValue))
					{
						if (request.Result == ConnectionRequestResult.Reject)
						{
							actualValue = new NetPeer(this, request.RemoteEndPoint, GetNextPeerId());
							actualValue.Reject(request.InternalPacket, rejectData, start, length);
							AddPeer(actualValue);
						}
						else
						{
							actualValue = new NetPeer(this, request, GetNextPeerId());
							AddPeer(actualValue);
							CreateEvent(NetEvent.EType.Connect, actualValue, null, SocketError.Success, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0);
						}
					}
					_requestsDict.Remove(request.RemoteEndPoint);
				}
			}
			return actualValue;
		}

		private int GetNextPeerId()
		{
			if (!_peerIds.TryDequeue(out var result))
			{
				return _lastPeerId++;
			}
			return result;
		}

		private void ProcessConnectRequest(IPEndPoint remoteEndPoint, NetPeer netPeer, NetConnectRequestPacket connRequest)
		{
			if (netPeer != null)
			{
				ConnectRequestResult connectRequestResult = netPeer.ProcessConnectRequest(connRequest);
				switch (connectRequestResult)
				{
				default:
					return;
				case ConnectRequestResult.Reconnection:
					DisconnectPeerForce(netPeer, DisconnectReason.Reconnect, SocketError.Success, null);
					RemovePeer(netPeer, enableWriteLock: true);
					break;
				case ConnectRequestResult.NewConnection:
					RemovePeer(netPeer, enableWriteLock: true);
					break;
				case ConnectRequestResult.P2PLose:
					DisconnectPeerForce(netPeer, DisconnectReason.PeerToPeerConnection, SocketError.Success, null);
					RemovePeer(netPeer, enableWriteLock: true);
					break;
				}
				if (connectRequestResult != ConnectRequestResult.P2PLose)
				{
					connRequest.ConnectionNumber = (byte)((netPeer.ConnectionNum + 1) % 4);
				}
			}
			ConnectionRequest value;
			lock (_requestsDict)
			{
				if (_requestsDict.TryGetValue(remoteEndPoint, out value))
				{
					value.UpdateRequest(connRequest);
					return;
				}
				value = new ConnectionRequest(remoteEndPoint, connRequest, this);
				_requestsDict.Add(remoteEndPoint, value);
			}
			CreateEvent(NetEvent.EType.ConnectionRequest, null, null, SocketError.Success, 0, DisconnectReason.ConnectionFailed, value, DeliveryMethod.Unreliable, 0);
		}

		private void OnMessageReceived(NetPacket packet, IPEndPoint remoteEndPoint)
		{
			if (packet.Size == 0)
			{
				PoolRecycle(packet);
				return;
			}
			_dropPacket = false;
			if (!_dropPacket)
			{
				HandleMessageReceived(packet, remoteEndPoint);
			}
		}

		[Conditional("DEBUG")]
		private void HandleSimulateLatency(NetPacket packet, IPEndPoint remoteEndPoint)
		{
			if (!SimulateLatency)
			{
				return;
			}
			int num = _randomGenerator.Next(SimulationMinLatency, SimulationMaxLatency);
			if (num > 5)
			{
				lock (_pingSimulationList)
				{
					_pingSimulationList.Add(new IncomingData
					{
						Data = packet,
						EndPoint = remoteEndPoint,
						TimeWhenGet = DateTime.UtcNow.AddMilliseconds(num)
					});
				}
				_dropPacket = true;
			}
		}

		[Conditional("DEBUG")]
		private void HandleSimulatePacketLoss()
		{
			if (SimulatePacketLoss && _randomGenerator.NextDouble() * 100.0 < (double)SimulationPacketLossChance)
			{
				_dropPacket = true;
			}
		}

		private void HandleMessageReceived(NetPacket packet, IPEndPoint remoteEndPoint)
		{
			int size = packet.Size;
			if (EnableStatistics)
			{
				Statistics.IncrementPacketsReceived();
				Statistics.AddBytesReceived(size);
			}
			if (_ntpRequests.Count > 0 && _ntpRequests.TryGetValue(remoteEndPoint, out var _))
			{
				if (packet.Size >= 48)
				{
					byte[] array = new byte[packet.Size];
					Buffer.BlockCopy(packet.RawData, 0, array, 0, packet.Size);
					NtpPacket ntpPacket = NtpPacket.FromServerResponse(array, DateTime.UtcNow);
					try
					{
						ntpPacket.ValidateReply();
					}
					catch (InvalidOperationException)
					{
						ntpPacket = null;
					}
					if (ntpPacket != null)
					{
						_ntpRequests.TryRemove(remoteEndPoint, out var _);
						_ntpEventListener?.OnNtpResponse(ntpPacket);
					}
				}
				return;
			}
			if (_extraPacketLayer != null)
			{
				_extraPacketLayer.ProcessInboundPacket(ref remoteEndPoint, ref packet.RawData, ref packet.Size);
				if (packet.Size == 0)
				{
					return;
				}
			}
			if (!packet.Verify())
			{
				NetDebug.WriteError("[NM] DataReceived: bad!");
				PoolRecycle(packet);
				return;
			}
			switch (packet.Property)
			{
			case PacketProperty.ConnectRequest:
				if (NetConnectRequestPacket.GetProtocolId(packet) != 13)
				{
					SendRawAndRecycle(PoolGetWithProperty(PacketProperty.InvalidProtocol), remoteEndPoint);
					return;
				}
				break;
			case PacketProperty.Broadcast:
				if (BroadcastReceiveEnabled)
				{
					CreateEvent(NetEvent.EType.Broadcast, null, remoteEndPoint, SocketError.Success, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0, packet);
				}
				return;
			case PacketProperty.UnconnectedMessage:
				if (UnconnectedMessagesEnabled)
				{
					CreateEvent(NetEvent.EType.ReceiveUnconnected, null, remoteEndPoint, SocketError.Success, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0, packet);
				}
				return;
			case PacketProperty.NatMessage:
				if (NatPunchEnabled)
				{
					NatPunchModule.ProcessMessage(remoteEndPoint, packet);
				}
				return;
			}
			NetPeer actualValue = remoteEndPoint as NetPeer;
			bool flag = actualValue != null || TryGetPeer(remoteEndPoint, out actualValue);
			if (flag && EnableStatistics)
			{
				actualValue.Statistics.IncrementPacketsReceived();
				actualValue.Statistics.AddBytesReceived(size);
			}
			switch (packet.Property)
			{
			case PacketProperty.ConnectRequest:
			{
				NetConnectRequestPacket netConnectRequestPacket = NetConnectRequestPacket.FromData(packet);
				if (netConnectRequestPacket != null)
				{
					ProcessConnectRequest(remoteEndPoint, actualValue, netConnectRequestPacket);
				}
				break;
			}
			case PacketProperty.PeerNotFound:
				if (flag)
				{
					if (actualValue.ConnectionState == ConnectionState.Connected)
					{
						if (packet.Size == 1)
						{
							actualValue.ResetMtu();
							SendRaw(NetConnectAcceptPacket.MakeNetworkChanged(actualValue), remoteEndPoint);
						}
						else if (packet.Size == 2 && packet.RawData[1] == 1)
						{
							DisconnectPeerForce(actualValue, DisconnectReason.PeerNotFound, SocketError.Success, null);
						}
					}
				}
				else
				{
					if (packet.Size <= 1)
					{
						break;
					}
					bool flag2 = false;
					if (AllowPeerAddressChange)
					{
						NetConnectAcceptPacket netConnectAcceptPacket = NetConnectAcceptPacket.FromData(packet);
						if (netConnectAcceptPacket != null && netConnectAcceptPacket.PeerNetworkChanged && netConnectAcceptPacket.PeerId < _peersArray.Length)
						{
							_peersLock.EnterUpgradeableReadLock();
							NetPeer netPeer = _peersArray[netConnectAcceptPacket.PeerId];
							_peersLock.ExitUpgradeableReadLock();
							if (netPeer != null && netPeer.ConnectTime == netConnectAcceptPacket.ConnectionTime && netPeer.ConnectionNum == netConnectAcceptPacket.ConnectionNumber)
							{
								if (netPeer.ConnectionState == ConnectionState.Connected)
								{
									netPeer.InitiateEndPointChange();
									CreateEvent(NetEvent.EType.PeerAddressChanged, netPeer, remoteEndPoint, SocketError.Success, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0);
								}
								flag2 = true;
							}
						}
					}
					PoolRecycle(packet);
					if (!flag2)
					{
						NetPacket netPacket = PoolGetWithProperty(PacketProperty.PeerNotFound, 1);
						netPacket.RawData[1] = 1;
						SendRawAndRecycle(netPacket, remoteEndPoint);
					}
				}
				break;
			case PacketProperty.InvalidProtocol:
				if (flag && actualValue.ConnectionState == ConnectionState.Outgoing)
				{
					DisconnectPeerForce(actualValue, DisconnectReason.InvalidProtocol, SocketError.Success, null);
				}
				break;
			case PacketProperty.Disconnect:
				if (flag)
				{
					DisconnectResult disconnectResult = actualValue.ProcessDisconnect(packet);
					if (disconnectResult == DisconnectResult.None)
					{
						PoolRecycle(packet);
						break;
					}
					DisconnectPeerForce(actualValue, (disconnectResult == DisconnectResult.Disconnect) ? DisconnectReason.RemoteConnectionClose : DisconnectReason.ConnectionRejected, SocketError.Success, packet);
				}
				else
				{
					PoolRecycle(packet);
				}
				SendRawAndRecycle(PoolGetWithProperty(PacketProperty.ShutdownOk), remoteEndPoint);
				break;
			case PacketProperty.ConnectAccept:
				if (flag)
				{
					NetConnectAcceptPacket netConnectAcceptPacket2 = NetConnectAcceptPacket.FromData(packet);
					if (netConnectAcceptPacket2 != null && actualValue.ProcessConnectAccept(netConnectAcceptPacket2))
					{
						CreateEvent(NetEvent.EType.Connect, actualValue, null, SocketError.Success, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0);
					}
				}
				break;
			default:
				if (flag)
				{
					actualValue.ProcessPacket(packet);
				}
				else
				{
					SendRawAndRecycle(PoolGetWithProperty(PacketProperty.PeerNotFound), remoteEndPoint);
				}
				break;
			}
		}

		internal void CreateReceiveEvent(NetPacket packet, DeliveryMethod method, byte channelNumber, int headerSize, NetPeer fromPeer)
		{
			if (UnsyncedEvents || UnsyncedReceiveEvent || _manualMode)
			{
				NetEvent netEvent;
				lock (_eventLock)
				{
					netEvent = _netEventPoolHead;
					if (netEvent == null)
					{
						netEvent = new NetEvent(this);
					}
					else
					{
						_netEventPoolHead = netEvent.Next;
					}
				}
				netEvent.Next = null;
				netEvent.Type = NetEvent.EType.Receive;
				netEvent.DataReader.SetSource(packet, headerSize);
				netEvent.Peer = fromPeer;
				netEvent.DeliveryMethod = method;
				netEvent.ChannelNumber = channelNumber;
				ProcessEvent(netEvent);
				return;
			}
			lock (_eventLock)
			{
				NetEvent netEvent = _netEventPoolHead;
				if (netEvent == null)
				{
					netEvent = new NetEvent(this);
				}
				else
				{
					_netEventPoolHead = netEvent.Next;
				}
				netEvent.Next = null;
				netEvent.Type = NetEvent.EType.Receive;
				netEvent.DataReader.SetSource(packet, headerSize);
				netEvent.Peer = fromPeer;
				netEvent.DeliveryMethod = method;
				netEvent.ChannelNumber = channelNumber;
				if (_pendingEventTail == null)
				{
					_pendingEventHead = netEvent;
				}
				else
				{
					_pendingEventTail.Next = netEvent;
				}
				_pendingEventTail = netEvent;
			}
		}

		public void SendToAll(NetDataWriter writer, DeliveryMethod options)
		{
			SendToAll(writer.Data, 0, writer.Length, options);
		}

		public void SendToAll(byte[] data, DeliveryMethod options)
		{
			SendToAll(data, 0, data.Length, options);
		}

		public void SendToAll(byte[] data, int start, int length, DeliveryMethod options)
		{
			SendToAll(data, start, length, 0, options);
		}

		public void SendToAll(NetDataWriter writer, byte channelNumber, DeliveryMethod options)
		{
			SendToAll(writer.Data, 0, writer.Length, channelNumber, options);
		}

		public void SendToAll(byte[] data, byte channelNumber, DeliveryMethod options)
		{
			SendToAll(data, 0, data.Length, channelNumber, options);
		}

		public void SendToAll(byte[] data, int start, int length, byte channelNumber, DeliveryMethod options)
		{
			try
			{
				_peersLock.EnterReadLock();
				for (NetPeer netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer)
				{
					netPeer.Send(data, start, length, channelNumber, options);
				}
			}
			finally
			{
				_peersLock.ExitReadLock();
			}
		}

		public void SendToAll(NetDataWriter writer, DeliveryMethod options, NetPeer excludePeer)
		{
			SendToAll(writer.Data, 0, writer.Length, 0, options, excludePeer);
		}

		public void SendToAll(byte[] data, DeliveryMethod options, NetPeer excludePeer)
		{
			SendToAll(data, 0, data.Length, 0, options, excludePeer);
		}

		public void SendToAll(byte[] data, int start, int length, DeliveryMethod options, NetPeer excludePeer)
		{
			SendToAll(data, start, length, 0, options, excludePeer);
		}

		public void SendToAll(NetDataWriter writer, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
		{
			SendToAll(writer.Data, 0, writer.Length, channelNumber, options, excludePeer);
		}

		public void SendToAll(byte[] data, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
		{
			SendToAll(data, 0, data.Length, channelNumber, options, excludePeer);
		}

		public void SendToAll(byte[] data, int start, int length, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
		{
			try
			{
				_peersLock.EnterReadLock();
				for (NetPeer netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer)
				{
					if (netPeer != excludePeer)
					{
						netPeer.Send(data, start, length, channelNumber, options);
					}
				}
			}
			finally
			{
				_peersLock.ExitReadLock();
			}
		}

		public bool Start()
		{
			return Start(0);
		}

		public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port)
		{
			return Start(addressIPv4, addressIPv6, port, manualMode: false);
		}

		public bool Start(string addressIPv4, string addressIPv6, int port)
		{
			IPAddress addressIPv7 = NetUtils.ResolveAddress(addressIPv4);
			IPAddress addressIPv8 = NetUtils.ResolveAddress(addressIPv6);
			return Start(addressIPv7, addressIPv8, port);
		}

		public bool Start(int port)
		{
			return Start(IPAddress.Any, IPAddress.IPv6Any, port);
		}

		public bool StartInManualMode(IPAddress addressIPv4, IPAddress addressIPv6, int port)
		{
			return Start(addressIPv4, addressIPv6, port, manualMode: true);
		}

		public bool StartInManualMode(string addressIPv4, string addressIPv6, int port)
		{
			IPAddress addressIPv7 = NetUtils.ResolveAddress(addressIPv4);
			IPAddress addressIPv8 = NetUtils.ResolveAddress(addressIPv6);
			return StartInManualMode(addressIPv7, addressIPv8, port);
		}

		public bool StartInManualMode(int port)
		{
			return StartInManualMode(IPAddress.Any, IPAddress.IPv6Any, port);
		}

		public bool SendUnconnectedMessage(byte[] message, IPEndPoint remoteEndPoint)
		{
			return SendUnconnectedMessage(message, 0, message.Length, remoteEndPoint);
		}

		public bool SendUnconnectedMessage(NetDataWriter writer, string address, int port)
		{
			IPEndPoint remoteEndPoint = NetUtils.MakeEndPoint(address, port);
			return SendUnconnectedMessage(writer.Data, 0, writer.Length, remoteEndPoint);
		}

		public bool SendUnconnectedMessage(NetDataWriter writer, IPEndPoint remoteEndPoint)
		{
			return SendUnconnectedMessage(writer.Data, 0, writer.Length, remoteEndPoint);
		}

		public bool SendUnconnectedMessage(byte[] message, int start, int length, IPEndPoint remoteEndPoint)
		{
			NetPacket packet = PoolGetWithData(PacketProperty.UnconnectedMessage, message, start, length);
			return SendRawAndRecycle(packet, remoteEndPoint) > 0;
		}

		public void TriggerUpdate()
		{
			_updateTriggerEvent.Set();
		}

		public void PollEvents(int maxProcessedEvents = 0)
		{
			if (_manualMode)
			{
				if (_udpSocketv4 != null)
				{
					ManualReceive(_udpSocketv4, _bufferEndPointv4, maxProcessedEvents);
				}
				if (_udpSocketv6 != null && _udpSocketv6 != _udpSocketv4)
				{
					ManualReceive(_udpSocketv6, _bufferEndPointv6, maxProcessedEvents);
				}
			}
			else
			{
				if (UnsyncedEvents)
				{
					return;
				}
				NetEvent netEvent;
				lock (_eventLock)
				{
					netEvent = _pendingEventHead;
					_pendingEventHead = null;
					_pendingEventTail = null;
				}
				int num = 0;
				while (netEvent != null)
				{
					NetEvent next = netEvent.Next;
					ProcessEvent(netEvent);
					netEvent = next;
					num++;
					if (num == maxProcessedEvents)
					{
						break;
					}
				}
			}
		}

		public NetPeer Connect(string address, int port, string key)
		{
			return Connect(address, port, NetDataWriter.FromString(key));
		}

		public NetPeer Connect(string address, int port, NetDataWriter connectionData)
		{
			IPEndPoint target;
			try
			{
				target = NetUtils.MakeEndPoint(address, port);
			}
			catch
			{
				CreateEvent(NetEvent.EType.Disconnect, null, null, SocketError.Success, 0, DisconnectReason.UnknownHost, null, DeliveryMethod.Unreliable, 0);
				return null;
			}
			return Connect(target, connectionData);
		}

		public NetPeer Connect(IPEndPoint target, string key)
		{
			return Connect(target, NetDataWriter.FromString(key));
		}

		public NetPeer Connect(IPEndPoint target, NetDataWriter connectionData)
		{
			if (!IsRunning)
			{
				throw new InvalidOperationException("Client is not running");
			}
			lock (_requestsDict)
			{
				if (_requestsDict.ContainsKey(target))
				{
					return null;
				}
				byte connectNum = 0;
				if (TryGetPeer(target, out var actualValue))
				{
					ConnectionState connectionState = actualValue.ConnectionState;
					if (connectionState == ConnectionState.Outgoing || connectionState == ConnectionState.Connected)
					{
						return actualValue;
					}
					connectNum = (byte)((actualValue.ConnectionNum + 1) % 4);
					RemovePeer(actualValue, enableWriteLock: true);
				}
				actualValue = new NetPeer(this, target, GetNextPeerId(), connectNum, connectionData);
				AddPeer(actualValue);
				return actualValue;
			}
		}

		public void Stop()
		{
			Stop(sendDisconnectMessages: true);
		}

		public void Stop(bool sendDisconnectMessages)
		{
			if (IsRunning)
			{
				for (NetPeer netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer)
				{
					netPeer.Shutdown(null, 0, 0, !sendDisconnectMessages);
				}
				CloseSocket();
				_updateTriggerEvent.Set();
				if (!_manualMode)
				{
					_logicThread.Join();
					_logicThread = null;
				}
				ClearPeerSet();
				_peerIds = new ConcurrentQueue<int>();
				_lastPeerId = 0;
				_connectedPeersCount = 0L;
				_pendingEventHead = null;
				_pendingEventTail = null;
			}
		}

		[Conditional("DEBUG")]
		private void ClearPingSimulationList()
		{
			lock (_pingSimulationList)
			{
				_pingSimulationList.Clear();
			}
		}

		public int GetPeersCount(ConnectionState peerState)
		{
			int num = 0;
			_peersLock.EnterReadLock();
			for (NetPeer netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer)
			{
				if ((netPeer.ConnectionState & peerState) != 0)
				{
					num++;
				}
			}
			_peersLock.ExitReadLock();
			return num;
		}

		public void GetPeersNonAlloc(List<NetPeer> peers, ConnectionState peerState)
		{
			peers.Clear();
			_peersLock.EnterReadLock();
			for (NetPeer netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer)
			{
				if ((netPeer.ConnectionState & peerState) != 0)
				{
					peers.Add(netPeer);
				}
			}
			_peersLock.ExitReadLock();
		}

		public void DisconnectAll()
		{
			DisconnectAll(null, 0, 0);
		}

		public void DisconnectAll(byte[] data, int start, int count)
		{
			_peersLock.EnterReadLock();
			for (NetPeer netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer)
			{
				DisconnectPeer(netPeer, DisconnectReason.DisconnectPeerCalled, SocketError.Success, force: false, data, start, count, null);
			}
			_peersLock.ExitReadLock();
		}

		public void DisconnectPeerForce(NetPeer peer)
		{
			DisconnectPeerForce(peer, DisconnectReason.DisconnectPeerCalled, SocketError.Success, null);
		}

		public void DisconnectPeer(NetPeer peer)
		{
			DisconnectPeer(peer, null, 0, 0);
		}

		public void DisconnectPeer(NetPeer peer, byte[] data)
		{
			DisconnectPeer(peer, data, 0, data.Length);
		}

		public void DisconnectPeer(NetPeer peer, NetDataWriter writer)
		{
			DisconnectPeer(peer, writer.Data, 0, writer.Length);
		}

		public void DisconnectPeer(NetPeer peer, byte[] data, int start, int count)
		{
			DisconnectPeer(peer, DisconnectReason.DisconnectPeerCalled, SocketError.Success, force: false, data, start, count, null);
		}

		public void CreateNtpRequest(IPEndPoint endPoint)
		{
			_ntpRequests.TryAdd(endPoint, new NtpRequest(endPoint));
		}

		public void CreateNtpRequest(string ntpServerAddress, int port)
		{
			IPEndPoint iPEndPoint = NetUtils.MakeEndPoint(ntpServerAddress, port);
			_ntpRequests.TryAdd(iPEndPoint, new NtpRequest(iPEndPoint));
		}

		public void CreateNtpRequest(string ntpServerAddress)
		{
			IPEndPoint iPEndPoint = NetUtils.MakeEndPoint(ntpServerAddress, 123);
			_ntpRequests.TryAdd(iPEndPoint, new NtpRequest(iPEndPoint));
		}

		public NetPeerEnumerator GetEnumerator()
		{
			return new NetPeerEnumerator(_headPeer);
		}

		IEnumerator<NetPeer> IEnumerable<NetPeer>.GetEnumerator()
		{
			return new NetPeerEnumerator(_headPeer);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return new NetPeerEnumerator(_headPeer);
		}

		private static int HashSetGetPrime(int min)
		{
			int[] primes = Primes;
			foreach (int num in primes)
			{
				if (num >= min)
				{
					return num;
				}
			}
			for (int j = min | 1; j < int.MaxValue; j += 2)
			{
				if (IsPrime(j) && (j - 1) % 101 != 0)
				{
					return j;
				}
			}
			return min;
			static bool IsPrime(int candidate)
			{
				if (((uint)candidate & (true ? 1u : 0u)) != 0)
				{
					int num2 = (int)Math.Sqrt(candidate);
					for (int k = 3; k <= num2; k += 2)
					{
						if (candidate % k == 0)
						{
							return false;
						}
					}
					return true;
				}
				return candidate == 2;
			}
		}

		private void ClearPeerSet()
		{
			_peersLock.EnterWriteLock();
			_headPeer = null;
			if (_lastIndex > 0)
			{
				Array.Clear(_slots, 0, _lastIndex);
				Array.Clear(_buckets, 0, _buckets.Length);
				_lastIndex = 0;
				_count = 0;
				_freeList = -1;
			}
			_peersArray = new NetPeer[32];
			_peersLock.ExitWriteLock();
		}

		private bool ContainsPeer(NetPeer item)
		{
			if (item == null)
			{
				NetDebug.WriteError($"Contains peer null: {item}");
				return false;
			}
			if (_buckets != null)
			{
				int num = item.GetHashCode() & 0x7FFFFFFF;
				for (int num2 = _buckets[num % _buckets.Length] - 1; num2 >= 0; num2 = _slots[num2].Next)
				{
					if (_slots[num2].HashCode == num && _slots[num2].Value.Equals(item))
					{
						return true;
					}
				}
			}
			return false;
		}

		public NetPeer GetPeerById(int id)
		{
			if (id < 0 || id >= _peersArray.Length)
			{
				return null;
			}
			return _peersArray[id];
		}

		public bool TryGetPeerById(int id, out NetPeer peer)
		{
			peer = GetPeerById(id);
			return peer != null;
		}

		private void AddPeer(NetPeer peer)
		{
			if (peer == null)
			{
				NetDebug.WriteError($"Add peer null: {peer}");
				return;
			}
			_peersLock.EnterWriteLock();
			if (_headPeer != null)
			{
				peer.NextPeer = _headPeer;
				_headPeer.PrevPeer = peer;
			}
			_headPeer = peer;
			AddPeerToSet(peer);
			if (peer.Id >= _peersArray.Length)
			{
				int num = _peersArray.Length * 2;
				while (peer.Id >= num)
				{
					num *= 2;
				}
				Array.Resize(ref _peersArray, num);
			}
			_peersArray[peer.Id] = peer;
			_peersLock.ExitWriteLock();
		}

		private void RemovePeer(NetPeer peer, bool enableWriteLock)
		{
			if (enableWriteLock)
			{
				_peersLock.EnterWriteLock();
			}
			if (!RemovePeerFromSet(peer))
			{
				if (enableWriteLock)
				{
					_peersLock.ExitWriteLock();
				}
				return;
			}
			if (peer == _headPeer)
			{
				_headPeer = peer.NextPeer;
			}
			if (peer.PrevPeer != null)
			{
				peer.PrevPeer.NextPeer = peer.NextPeer;
			}
			if (peer.NextPeer != null)
			{
				peer.NextPeer.PrevPeer = peer.PrevPeer;
			}
			peer.PrevPeer = null;
			_peersArray[peer.Id] = null;
			_peerIds.Enqueue(peer.Id);
			if (enableWriteLock)
			{
				_peersLock.ExitWriteLock();
			}
		}

		private bool RemovePeerFromSet(NetPeer peer)
		{
			if (_buckets == null || peer == null)
			{
				return false;
			}
			int num = peer.GetHashCode() & 0x7FFFFFFF;
			int num2 = num % _buckets.Length;
			int num3 = -1;
			for (int num4 = _buckets[num2] - 1; num4 >= 0; num4 = _slots[num4].Next)
			{
				if (_slots[num4].HashCode == num && _slots[num4].Value.Equals(peer))
				{
					if (num3 < 0)
					{
						_buckets[num2] = _slots[num4].Next + 1;
					}
					else
					{
						_slots[num3].Next = _slots[num4].Next;
					}
					_slots[num4].HashCode = -1;
					_slots[num4].Value = null;
					_slots[num4].Next = _freeList;
					_count--;
					if (_count == 0)
					{
						_lastIndex = 0;
						_freeList = -1;
					}
					else
					{
						_freeList = num4;
					}
					return true;
				}
				num3 = num4;
			}
			return false;
		}

		private bool TryGetPeer(IPEndPoint endPoint, out NetPeer actualValue)
		{
			if (_buckets != null)
			{
				int num = endPoint.GetHashCode() & 0x7FFFFFFF;
				_peersLock.EnterReadLock();
				for (int num2 = _buckets[num % _buckets.Length] - 1; num2 >= 0; num2 = _slots[num2].Next)
				{
					if (_slots[num2].HashCode == num && _slots[num2].Value.Equals(endPoint))
					{
						actualValue = _slots[num2].Value;
						_peersLock.ExitReadLock();
						return true;
					}
				}
				_peersLock.ExitReadLock();
			}
			actualValue = null;
			return false;
		}

		private bool TryGetPeer(SocketAddress saddr, out NetPeer actualValue)
		{
			if (_buckets != null)
			{
				int num = saddr.GetHashCode() & 0x7FFFFFFF;
				_peersLock.EnterReadLock();
				for (int num2 = _buckets[num % _buckets.Length] - 1; num2 >= 0; num2 = _slots[num2].Next)
				{
					if (_slots[num2].HashCode == num && _slots[num2].Value.Serialize().Equals(saddr))
					{
						actualValue = _slots[num2].Value;
						_peersLock.ExitReadLock();
						return true;
					}
				}
				_peersLock.ExitReadLock();
			}
			actualValue = null;
			return false;
		}

		private bool AddPeerToSet(NetPeer value)
		{
			if (_buckets == null)
			{
				int num = HashSetGetPrime(0);
				_buckets = new int[num];
				_slots = new Slot[num];
			}
			int num2 = value.GetHashCode() & 0x7FFFFFFF;
			int num3 = num2 % _buckets.Length;
			for (int num4 = _buckets[num2 % _buckets.Length] - 1; num4 >= 0; num4 = _slots[num4].Next)
			{
				if (_slots[num4].HashCode == num2 && _slots[num4].Value.Equals(value))
				{
					return false;
				}
			}
			int num5;
			if (_freeList >= 0)
			{
				num5 = _freeList;
				_freeList = _slots[num5].Next;
			}
			else
			{
				if (_lastIndex == _slots.Length)
				{
					int num6 = 2 * _count;
					num6 = (((uint)num6 > 2147483587u && 2147483587 > _count) ? 2147483587 : HashSetGetPrime(num6));
					Slot[] array = new Slot[num6];
					Array.Copy(_slots, 0, array, 0, _lastIndex);
					_buckets = new int[num6];
					for (int i = 0; i < _lastIndex; i++)
					{
						int num7 = array[i].HashCode % num6;
						array[i].Next = _buckets[num7] - 1;
						_buckets[num7] = i + 1;
					}
					_slots = array;
					num3 = num2 % _buckets.Length;
				}
				num5 = _lastIndex;
				_lastIndex++;
			}
			_slots[num5].HashCode = num2;
			_slots[num5].Value = value;
			_slots[num5].Next = _buckets[num3] - 1;
			_buckets[num3] = num5 + 1;
			_count++;
			return true;
		}

		private NetPacket PoolGetWithData(PacketProperty property, byte[] data, int start, int length)
		{
			int headerSize = NetPacket.GetHeaderSize(property);
			NetPacket netPacket = PoolGetPacket(length + headerSize);
			netPacket.Property = property;
			Buffer.BlockCopy(data, start, netPacket.RawData, headerSize, length);
			return netPacket;
		}

		private NetPacket PoolGetWithProperty(PacketProperty property, int size)
		{
			NetPacket netPacket = PoolGetPacket(size + NetPacket.GetHeaderSize(property));
			netPacket.Property = property;
			return netPacket;
		}

		private NetPacket PoolGetWithProperty(PacketProperty property)
		{
			NetPacket netPacket = PoolGetPacket(NetPacket.GetHeaderSize(property));
			netPacket.Property = property;
			return netPacket;
		}

		internal NetPacket PoolGetPacket(int size)
		{
			if (size > NetConstants.MaxPacketSize)
			{
				return new NetPacket(size);
			}
			NetPacket poolHead;
			lock (_poolLock)
			{
				poolHead = _poolHead;
				if (poolHead == null)
				{
					return new NetPacket(size);
				}
				_poolHead = _poolHead.Next;
				_poolCount--;
			}
			poolHead.Size = size;
			if (poolHead.RawData.Length < size)
			{
				poolHead.RawData = new byte[size];
			}
			return poolHead;
		}

		internal void PoolRecycle(NetPacket packet)
		{
			if (packet.RawData.Length > NetConstants.MaxPacketSize || _poolCount >= PacketPoolSize)
			{
				return;
			}
			packet.RawData[0] = 0;
			lock (_poolLock)
			{
				packet.Next = _poolHead;
				_poolHead = packet;
				_poolCount++;
			}
		}

		static NetManager()
		{
			Primes = new int[72]
			{
				3, 7, 11, 17, 23, 29, 37, 47, 59, 71,
				89, 107, 131, 163, 197, 239, 293, 353, 431, 521,
				631, 761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371,
				4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, 17519, 21023,
				25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363,
				156437, 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403,
				968897, 1162687, 1395263, 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559,
				5999471, 7199369
			};
			MulticastAddressV6 = IPAddress.Parse("ff02::1");
			IPv6Support = Socket.OSSupportsIPv6;
		}

		private bool ProcessError(SocketException ex)
		{
			switch (ex.SocketErrorCode)
			{
			case SocketError.NotConnected:
				NotConnected = true;
				return true;
			case SocketError.OperationAborted:
			case SocketError.Interrupted:
			case SocketError.NotSocket:
				return true;
			default:
				NetDebug.WriteError($"[R]Error code: {(int)ex.SocketErrorCode} - {ex}");
				CreateEvent(NetEvent.EType.Error, null, null, ex.SocketErrorCode, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0);
				break;
			case SocketError.WouldBlock:
			case SocketError.MessageSize:
			case SocketError.NetworkReset:
			case SocketError.ConnectionReset:
			case SocketError.TimedOut:
				break;
			}
			return false;
		}

		private void ManualReceive(Socket socket, EndPoint bufferEndPoint, int maxReceive)
		{
			try
			{
				int num = 0;
				while (socket.Available > 0)
				{
					ReceiveFrom(socket, ref bufferEndPoint);
					num++;
					if (num == maxReceive)
					{
						break;
					}
				}
			}
			catch (SocketException ex)
			{
				ProcessError(ex);
			}
			catch (ObjectDisposedException)
			{
			}
			catch (Exception ex3)
			{
				NetDebug.WriteError("[NM] SocketReceiveThread error: " + ex3);
			}
		}

		private void NativeReceiveLogic()
		{
			IntPtr handle = _udpSocketv4.Handle;
			IntPtr s2 = _udpSocketv6?.Handle ?? IntPtr.Zero;
			byte[] address2 = new byte[16];
			byte[] address3 = new byte[28];
			IPEndPoint tempEndPoint = new IPEndPoint(IPAddress.Any, 0);
			List<Socket> list = new List<Socket>(2);
			Socket udpSocketv = _udpSocketv4;
			Socket udpSocketv2 = _udpSocketv6;
			NetPacket packet = PoolGetPacket(NetConstants.MaxPacketSize);
			while (IsRunning)
			{
				try
				{
					if (udpSocketv2 == null)
					{
						if (!NativeReceiveFrom(handle, address2))
						{
							break;
						}
						continue;
					}
					bool flag = false;
					if (udpSocketv.Available != 0 || list.Contains(udpSocketv))
					{
						if (!NativeReceiveFrom(handle, address2))
						{
							break;
						}
						flag = true;
					}
					if (udpSocketv2.Available != 0 || list.Contains(udpSocketv2))
					{
						if (!NativeReceiveFrom(s2, address3))
						{
							break;
						}
						flag = true;
					}
					list.Clear();
					if (!flag)
					{
						list.Add(udpSocketv);
						list.Add(udpSocketv2);
						Socket.Select(list, null, null, 500000);
					}
				}
				catch (SocketException ex)
				{
					if (ProcessError(ex))
					{
						break;
					}
				}
				catch (ObjectDisposedException)
				{
					break;
				}
				catch (ThreadAbortException)
				{
					break;
				}
				catch (Exception ex4)
				{
					NetDebug.WriteError("[NM] SocketReceiveThread error: " + ex4);
				}
			}
			bool NativeReceiveFrom(IntPtr s, byte[] address)
			{
				int socketAddressSize = address.Length;
				packet.Size = NativeSocket.RecvFrom(s, packet.RawData, NetConstants.MaxPacketSize, address, ref socketAddressSize);
				if (packet.Size == 0)
				{
					return true;
				}
				if (packet.Size == -1)
				{
					return !ProcessError(new SocketException((int)NativeSocket.GetSocketError()));
				}
				short num = (short)((address[1] << 8) | address[0]);
				tempEndPoint.Port = (ushort)((address[2] << 8) | address[3]);
				if ((NativeSocket.UnixMode && num == 10) || (!NativeSocket.UnixMode && num == 23))
				{
					uint num2 = (uint)((address[27] << 24) + (address[26] << 16) + (address[25] << 8) + address[24]);
					byte[] array = new byte[16];
					Buffer.BlockCopy(address, 8, array, 0, 16);
					tempEndPoint.Address = new IPAddress(array, num2);
				}
				else
				{
					long newAddress = (uint)((address[4] & 0xFF) | ((address[5] << 8) & 0xFF00) | ((address[6] << 16) & 0xFF0000) | (address[7] << 24));
					tempEndPoint.Address = new IPAddress(newAddress);
				}
				if (TryGetPeer(tempEndPoint, out var actualValue))
				{
					OnMessageReceived(packet, actualValue);
				}
				else
				{
					OnMessageReceived(packet, tempEndPoint);
					tempEndPoint = new IPEndPoint(IPAddress.Any, 0);
				}
				packet = PoolGetPacket(NetConstants.MaxPacketSize);
				return true;
			}
		}

		private void ReceiveFrom(Socket s, ref EndPoint bufferEndPoint)
		{
			NetPacket netPacket = PoolGetPacket(NetConstants.MaxPacketSize);
			netPacket.Size = s.ReceiveFrom(netPacket.RawData, 0, NetConstants.MaxPacketSize, SocketFlags.None, ref bufferEndPoint);
			OnMessageReceived(netPacket, (IPEndPoint)bufferEndPoint);
		}

		private void ReceiveLogic()
		{
			EndPoint bufferEndPoint = new IPEndPoint(IPAddress.Any, 0);
			EndPoint bufferEndPoint2 = new IPEndPoint(IPAddress.IPv6Any, 0);
			List<Socket> list = new List<Socket>(2);
			Socket udpSocketv = _udpSocketv4;
			Socket udpSocketv2 = _udpSocketv6;
			while (IsRunning)
			{
				try
				{
					if (udpSocketv2 == null)
					{
						if (udpSocketv.Available != 0 || udpSocketv.Poll(500000, SelectMode.SelectRead))
						{
							ReceiveFrom(udpSocketv, ref bufferEndPoint);
						}
						continue;
					}
					bool flag = false;
					if (udpSocketv.Available != 0 || list.Contains(udpSocketv))
					{
						ReceiveFrom(udpSocketv, ref bufferEndPoint);
						flag = true;
					}
					if (udpSocketv2.Available != 0 || list.Contains(udpSocketv2))
					{
						ReceiveFrom(udpSocketv2, ref bufferEndPoint2);
						flag = true;
					}
					list.Clear();
					if (!flag)
					{
						list.Add(udpSocketv);
						list.Add(udpSocketv2);
						Socket.Select(list, null, null, 500000);
					}
				}
				catch (SocketException ex)
				{
					if (ProcessError(ex))
					{
						break;
					}
				}
				catch (ObjectDisposedException)
				{
					break;
				}
				catch (ThreadAbortException)
				{
					break;
				}
				catch (Exception ex4)
				{
					NetDebug.WriteError("[NM] SocketReceiveThread error: " + ex4);
				}
			}
		}

		public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode)
		{
			if (IsRunning && !NotConnected)
			{
				return false;
			}
			NotConnected = false;
			_manualMode = manualMode;
			UseNativeSockets = UseNativeSockets && NativeSocket.IsSupported;
			_udpSocketv4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
			if (!BindSocket(_udpSocketv4, new IPEndPoint(addressIPv4, port)))
			{
				return false;
			}
			LocalPort = ((IPEndPoint)_udpSocketv4.LocalEndPoint).Port;
			IsRunning = true;
			if (_manualMode)
			{
				_bufferEndPointv4 = new IPEndPoint(IPAddress.Any, 0);
			}
			if (IPv6Support && IPv6Enabled)
			{
				_udpSocketv6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
				if (BindSocket(_udpSocketv6, new IPEndPoint(addressIPv6, LocalPort)))
				{
					if (_manualMode)
					{
						_bufferEndPointv6 = new IPEndPoint(IPAddress.IPv6Any, 0);
					}
				}
				else
				{
					_udpSocketv6 = null;
				}
			}
			if (!manualMode)
			{
				ThreadStart start = ReceiveLogic;
				if (UseNativeSockets)
				{
					start = NativeReceiveLogic;
				}
				_receiveThread = new Thread(start)
				{
					Name = $"ReceiveThread({LocalPort})",
					IsBackground = true
				};
				_receiveThread.Start();
				if (_logicThread == null)
				{
					_logicThread = new Thread(UpdateLogic)
					{
						Name = "LogicThread",
						IsBackground = true
					};
					_logicThread.Start();
				}
			}
			return true;
		}

		private bool BindSocket(Socket socket, IPEndPoint ep)
		{
			socket.ReceiveTimeout = 500;
			socket.SendTimeout = 500;
			socket.ReceiveBufferSize = 1048576;
			socket.SendBufferSize = 1048576;
			socket.Blocking = true;
			if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
			{
				try
				{
					socket.IOControl(-1744830452, new byte[1], null);
				}
				catch
				{
				}
			}
			try
			{
				socket.ExclusiveAddressUse = !ReuseAddress;
				socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, ReuseAddress);
				socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, DontRoute);
			}
			catch
			{
			}
			if (ep.AddressFamily == AddressFamily.InterNetwork)
			{
				Ttl = 255;
				try
				{
					socket.EnableBroadcast = true;
				}
				catch (SocketException ex)
				{
					NetDebug.WriteError($"[B]Broadcast error: {ex.SocketErrorCode}");
				}
				if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
				{
					try
					{
						socket.DontFragment = true;
					}
					catch (SocketException ex2)
					{
						NetDebug.WriteError($"[B]DontFragment error: {ex2.SocketErrorCode}");
					}
				}
			}
			try
			{
				socket.Bind(ep);
				if (ep.AddressFamily == AddressFamily.InterNetworkV6)
				{
					try
					{
						socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, new IPv6MulticastOption(MulticastAddressV6));
					}
					catch (Exception)
					{
					}
				}
			}
			catch (SocketException ex4)
			{
				switch (ex4.SocketErrorCode)
				{
				case SocketError.AddressAlreadyInUse:
					if (socket.AddressFamily == AddressFamily.InterNetworkV6)
					{
						try
						{
							socket.DualMode = false;
							socket.Bind(ep);
						}
						catch (SocketException ex5)
						{
							NetDebug.WriteError($"[B]Bind exception: {ex5}, errorCode: {ex5.SocketErrorCode}");
							return false;
						}
						return true;
					}
					break;
				case SocketError.AddressFamilyNotSupported:
					return true;
				}
				NetDebug.WriteError($"[B]Bind exception: {ex4}, errorCode: {ex4.SocketErrorCode}");
				return false;
			}
			return true;
		}

		internal int SendRawAndRecycle(NetPacket packet, IPEndPoint remoteEndPoint)
		{
			int result = SendRaw(packet.RawData, 0, packet.Size, remoteEndPoint);
			PoolRecycle(packet);
			return result;
		}

		internal int SendRaw(NetPacket packet, IPEndPoint remoteEndPoint)
		{
			return SendRaw(packet.RawData, 0, packet.Size, remoteEndPoint);
		}

		internal unsafe int SendRaw(byte[] message, int start, int length, IPEndPoint remoteEndPoint)
		{
			if (!IsRunning)
			{
				return 0;
			}
			NetPacket netPacket = null;
			if (_extraPacketLayer != null)
			{
				netPacket = PoolGetPacket(length + _extraPacketLayer.ExtraPacketSizeForLayer);
				Buffer.BlockCopy(message, start, netPacket.RawData, 0, length);
				start = 0;
				_extraPacketLayer.ProcessOutBoundPacket(ref remoteEndPoint, ref netPacket.RawData, ref start, ref length);
				message = netPacket.RawData;
			}
			Socket socket = _udpSocketv4;
			if (remoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6 && IPv6Support)
			{
				socket = _udpSocketv6;
				if (socket == null)
				{
					return 0;
				}
			}
			int num;
			try
			{
				if (UseNativeSockets && remoteEndPoint is NetPeer netPeer)
				{
					fixed (byte* pinnedBuffer = &message[start])
					{
						num = NativeSocket.SendTo(socket.Handle, pinnedBuffer, length, netPeer.NativeAddress, netPeer.NativeAddress.Length);
					}
					if (num == -1)
					{
						throw NativeSocket.GetSocketException();
					}
				}
				else
				{
					num = socket.SendTo(message, start, length, SocketFlags.None, remoteEndPoint);
				}
			}
			catch (SocketException ex)
			{
				switch (ex.SocketErrorCode)
				{
				case SocketError.Interrupted:
				case SocketError.NoBufferSpaceAvailable:
					return 0;
				case SocketError.MessageSize:
					return 0;
				case SocketError.NetworkUnreachable:
				case SocketError.HostUnreachable:
					if (DisconnectOnUnreachable && remoteEndPoint is NetPeer peer)
					{
						DisconnectPeerForce(peer, (ex.SocketErrorCode == SocketError.HostUnreachable) ? DisconnectReason.HostUnreachable : DisconnectReason.NetworkUnreachable, ex.SocketErrorCode, null);
					}
					CreateEvent(NetEvent.EType.Error, null, remoteEndPoint, ex.SocketErrorCode, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0);
					return -1;
				case SocketError.Shutdown:
					CreateEvent(NetEvent.EType.Error, null, remoteEndPoint, ex.SocketErrorCode, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0);
					return -1;
				default:
					NetDebug.WriteError($"[S] {ex}");
					return -1;
				}
			}
			catch (Exception arg)
			{
				NetDebug.WriteError($"[S] {arg}");
				return 0;
			}
			finally
			{
				if (netPacket != null)
				{
					PoolRecycle(netPacket);
				}
			}
			if (num <= 0)
			{
				return 0;
			}
			if (EnableStatistics)
			{
				Statistics.IncrementPacketsSent();
				Statistics.AddBytesSent(length);
			}
			return num;
		}

		public bool SendBroadcast(NetDataWriter writer, int port)
		{
			return SendBroadcast(writer.Data, 0, writer.Length, port);
		}

		public bool SendBroadcast(byte[] data, int port)
		{
			return SendBroadcast(data, 0, data.Length, port);
		}

		public bool SendBroadcast(byte[] data, int start, int length, int port)
		{
			if (!IsRunning)
			{
				return false;
			}
			NetPacket netPacket;
			if (_extraPacketLayer != null)
			{
				int headerSize = NetPacket.GetHeaderSize(PacketProperty.Broadcast);
				netPacket = PoolGetPacket(headerSize + length + _extraPacketLayer.ExtraPacketSizeForLayer);
				netPacket.Property = PacketProperty.Broadcast;
				Buffer.BlockCopy(data, start, netPacket.RawData, headerSize, length);
				int offset = 0;
				int length2 = length + headerSize;
				IPEndPoint endPoint = null;
				_extraPacketLayer.ProcessOutBoundPacket(ref endPoint, ref netPacket.RawData, ref offset, ref length2);
			}
			else
			{
				netPacket = PoolGetWithData(PacketProperty.Broadcast, data, start, length);
			}
			bool flag = false;
			bool flag2 = false;
			try
			{
				flag = _udpSocketv4.SendTo(netPacket.RawData, 0, netPacket.Size, SocketFlags.None, new IPEndPoint(IPAddress.Broadcast, port)) > 0;
				if (_udpSocketv6 != null)
				{
					flag2 = _udpSocketv6.SendTo(netPacket.RawData, 0, netPacket.Size, SocketFlags.None, new IPEndPoint(MulticastAddressV6, port)) > 0;
				}
			}
			catch (SocketException ex)
			{
				if (ex.SocketErrorCode == SocketError.HostUnreachable)
				{
					return flag;
				}
				NetDebug.WriteError($"[S][MCAST] {ex}");
				return flag;
			}
			catch (Exception arg)
			{
				NetDebug.WriteError($"[S][MCAST] {arg}");
				return flag;
			}
			finally
			{
				PoolRecycle(netPacket);
			}
			return flag || flag2;
		}

		private void CloseSocket()
		{
			IsRunning = false;
			_udpSocketv4?.Close();
			_udpSocketv6?.Close();
			_udpSocketv4 = null;
			_udpSocketv6 = null;
			if (_receiveThread != null && _receiveThread != Thread.CurrentThread)
			{
				_receiveThread.Join();
			}
			_receiveThread = null;
		}
	}
	internal enum PacketProperty : byte
	{
		Unreliable,
		Channeled,
		Ack,
		Ping,
		Pong,
		ConnectRequest,
		ConnectAccept,
		Disconnect,
		UnconnectedMessage,
		MtuCheck,
		MtuOk,
		Broadcast,
		Merged,
		ShutdownOk,
		PeerNotFound,
		InvalidProtocol,
		NatMessage,
		Empty
	}
	internal sealed class NetPacket
	{
		private static readonly int PropertiesCount;

		private static readonly int[] HeaderSizes;

		public byte[] RawData;

		public int Size;

		public object UserData;

		public NetPacket Next;

		public PacketProperty Property
		{
			get
			{
				return (PacketProperty)(RawData[0] & 0x1Fu);
			}
			set
			{
				RawData[0] = (byte)((RawData[0] & 0xE0u) | (uint)value);
			}
		}

		public byte ConnectionNumber
		{
			get
			{
				return (byte)((RawData[0] & 0x60) >> 5);
			}
			set
			{
				RawData[0] = (byte)((RawData[0] & 0x9Fu) | (uint)(value << 5));
			}
		}

		public ushort Sequence
		{
			get
			{
				return BitConverter.ToUInt16(RawData, 1);
			}
			set
			{
				FastBitConverter.GetBytes(RawData, 1, value);
			}
		}

		public bool IsFragmented => (RawData[0] & 0x80) != 0;

		public byte ChannelId
		{
			get
			{
				return RawData[3];
			}
			set
			{
				RawData[3] = value;
			}
		}

		public ushort FragmentId
		{
			get
			{
				return BitConverter.ToUInt16(RawData, 4);
			}
			set
			{
				FastBitConverter.GetBytes(RawData, 4, value);
			}
		}

		public ushort FragmentPart
		{
			get
			{
				return BitConverter.ToUInt16(RawData, 6);
			}
			set
			{
				FastBitConverter.GetBytes(RawData, 6, value);
			}
		}

		public ushort FragmentsTotal
		{
			get
			{
				return BitConverter.ToUInt16(RawData, 8);
			}
			set
			{
				FastBitConverter.GetBytes(RawData, 8, value);
			}
		}

		static NetPacket()
		{
			PropertiesCount = Enum.GetValues(typeof(PacketProperty)).Length;
			HeaderSizes = NetUtils.AllocatePinnedUninitializedArray<int>(PropertiesCount);
			for (int i = 0; i < HeaderSizes.Length; i++)
			{
				switch ((PacketProperty)(byte)i)
				{
				case PacketProperty.Channeled:
				case PacketProperty.Ack:
					HeaderSizes[i] = 4;
					break;
				case PacketProperty.Ping:
					HeaderSizes[i] = 3;
					break;
				case PacketProperty.ConnectRequest:
					HeaderSizes[i] = 18;
					break;
				case PacketProperty.ConnectAccept:
					HeaderSizes[i] = 15;
					break;
				case PacketProperty.Disconnect:
					HeaderSizes[i] = 9;
					break;
				case PacketProperty.Pong:
					HeaderSizes[i] = 11;
					break;
				default:
					HeaderSizes[i] = 1;
					break;
				}
			}
		}

		public void MarkFragmented()
		{
			RawData[0] |= 128;
		}

		public NetPacket(int size)
		{
			RawData = new byte[size];
			Size = size;
		}

		public NetPacket(PacketProperty property, int size)
		{
			size += GetHeaderSize(property);
			RawData = new byte[size];
			Property = property;
			Size = size;
		}

		public static int GetHeaderSize(PacketProperty property)
		{
			return HeaderSizes[(uint)property];
		}

		public int GetHeaderSize()
		{
			return HeaderSizes[RawData[0] & 0x1F];
		}

		public bool Verify()
		{
			byte b = (byte)(RawData[0] & 0x1Fu);
			if (b >= PropertiesCount)
			{
				return false;
			}
			int num = HeaderSizes[b];
			bool flag = (RawData[0] & 0x80) != 0;
			if (Size >= num)
			{
				if (flag)
				{
					return Size >= num + 6;
				}
				return true;
			}
			return false;
		}
	}
	[Flags]
	public enum ConnectionState : byte
	{
		Outgoing = 2,
		Connected = 4,
		ShutdownRequested = 8,
		Disconnected = 0x10,
		EndPointChange = 0x20,
		Any = 0x2E
	}
	internal enum ConnectRequestResult
	{
		None,
		P2PLose,
		Reconnection,
		NewConnection
	}
	internal enum DisconnectResult
	{
		None,
		Reject,
		Disconnect
	}
	internal enum ShutdownResult
	{
		None,
		Success,
		WasConnected
	}
	public class NetPeer : IPEndPoint
	{
		private class IncomingFragments
		{
			public NetPacket[] Fragments;

			public int ReceivedCount;

			public int TotalSize;

			public byte ChannelId;
		}

		private int _rtt;

		private int _avgRtt;

		private int _rttCount;

		private double _resendDelay = 27.0;

		private float _pingSendTimer;

		private float _rttResetTimer;

		private readonly Stopwatch _pingTimer = new Stopwatch();

		private volatile float _timeSinceLastPacket;

		private long _remoteDelta;

		private readonly object _shutdownLock = new object();

		internal volatile NetPeer NextPeer;

		internal NetPeer PrevPeer;

		private NetPacket[] _unreliableSecondQueue;

		private NetPacket[] _unreliableChannel;

		private int _unreliablePendingCount;

		private readonly object _unreliableChannelLock = new object();

		private readonly ConcurrentQueue<BaseChannel> _channelSendQueue;

		private readonly BaseChannel[] _channels;

		private int _mtu;

		private int _mtuIdx;

		private bool _finishMtu;

		private float _mtuCheckTimer;

		private int _mtuCheckAttempts;

		private const int MtuCheckDelay = 1000;

		private const int MaxMtuCheckAttempts = 4;

		private readonly object _mtuMutex = new object();

		private int _fragmentId;

		private readonly Dictionary<ushort, IncomingFragments> _holdedFragments;

		private readonly Dictionary<ushort, ushort> _deliveredFragments;

		private readonly NetPacket _mergeData;

		private int _mergePos;

		private int _mergeCount;

		private int _connectAttempts;

		private float _connectTimer;

		private long _connectTime;

		private byte _connectNum;

		private ConnectionState _connectionState;

		private NetPacket _shutdownPacket;

		private const int ShutdownDelay = 300;

		private float _shutdownTimer;

		private readonly NetPacket _pingPacket;

		private readonly NetPacket _pongPacket;

		private readonly NetPacket _connectRequestPacket;

		private readonly NetPacket _connectAcceptPacket;

		public readonly NetManager NetManager;

		public readonly int Id;

		public object Tag;

		public readonly NetStatistics Statistics;

		private SocketAddress _cachedSocketAddr;

		private int _cachedHashCode;

		internal byte[] NativeAddress;

		internal byte ConnectionNum
		{
			get
			{
				return _connectNum;
			}
			private set
			{
				_connectNum = value;
				_mergeData.ConnectionNumber = value;
				_pingPacket.ConnectionNumber = value;
				_pongPacket.ConnectionNumber = value;
			}
		}

		public ConnectionState ConnectionState => _connectionState;

		internal long ConnectTime => _connectTime;

		public int RemoteId { get; private set; }

		public int Ping => _avgRtt / 2;

		public int RoundTripTime => _avgRtt;

		public int Mtu => _mtu;

		public long RemoteTimeDelta => _remoteDelta;

		public DateTime RemoteUtcTime => new DateTime(DateTime.UtcNow.Ticks + _remoteDelta);

		public float TimeSinceLastPacket => _timeSinceLastPacket;

		internal double ResendDelay => _resendDelay;

		public override SocketAddress Serialize()
		{
			return _cachedSocketAddr;
		}

		public override int GetHashCode()
		{
			return _cachedHashCode;
		}

		internal NetPeer(NetManager netManager, IPEndPoint remoteEndPoint, int id)
			: base(remoteEndPoint.Address, remoteEndPoint.Port)
		{
			Id = id;
			Statistics = new NetStatistics();
			NetManager = netManager;
			_cachedSocketAddr = base.Serialize();
			if (NetManager.UseNativeSockets)
			{
				NativeAddress = new byte[_cachedSocketAddr.Size];
				for (int i = 0; i < _cachedSocketAddr.Size; i++)
				{
					NativeAddress[i] = _cachedSocketAddr[i];
				}
			}
			_cachedHashCode = base.GetHashCode();
			ResetMtu();
			_connectionState = ConnectionState.Connected;
			_mergeData = new NetPacket(PacketProperty.Merged, NetConstants.MaxPacketSize);
			_pongPacket = new NetPacket(PacketProperty.Pong, 0);
			_pingPacket = new NetPacket(PacketProperty.Ping, 0)
			{
				Sequence = 1
			};
			_unreliableSecondQueue = new NetPacket[8];
			_unreliableChannel = new NetPacket[8];
			_holdedFragments = new Dictionary<ushort, IncomingFragments>();
			_deliveredFragments = new Dictionary<ushort, ushort>();
			_channels = new BaseChannel[netManager.ChannelsCount * 4];
			_channelSendQueue = new ConcurrentQueue<BaseChannel>();
		}

		internal void InitiateEndPointChange()
		{
			ResetMtu();
			_connectionState = ConnectionState.EndPointChange;
		}

		internal void FinishEndPointChange(IPEndPoint newEndPoint)
		{
			if (_connectionState != ConnectionState.EndPointChange)
			{
				return;
			}
			_connectionState = ConnectionState.Connected;
			base.Address = newEndPoint.Address;
			base.Port = newEndPoint.Port;
			if (NetManager.UseNativeSockets)
			{
				NativeAddress = new byte[_cachedSocketAddr.Size];
				for (int i = 0; i < _cachedSocketAddr.Size; i++)
				{
					NativeAddress[i] = _cachedSocketAddr[i];
				}
			}
			_cachedSocketAddr = base.Serialize();
			_cachedHashCode = base.GetHashCode();
		}

		internal void ResetMtu()
		{
			_finishMtu = !NetManager.MtuDiscovery;
			if (NetManager.MtuOverride > 0)
			{
				OverrideMtu(NetManager.MtuOverride);
			}
			else
			{
				SetMtu(0);
			}
		}

		private void SetMtu(int mtuIdx)
		{
			_mtuIdx = mtuIdx;
			_mtu = NetConstants.PossibleMtu[mtuIdx] - NetManager.ExtraPacketSizeForLayer;
		}

		private void OverrideMtu(int mtuValue)
		{
			_mtu = mtuValue;
			_finishMtu = true;
		}

		public int GetPacketsCountInReliableQueue(byte channelNumber, bool ordered)
		{
			int num = channelNumber * 4 + (ordered ? 2 : 0);
			BaseChannel baseChannel = _channels[num];
			if (baseChannel == null)
			{
				return 0;
			}
			return ((ReliableChannel)baseChannel).PacketsInQueue;
		}

		public PooledPacket CreatePacketFromPool(DeliveryMethod deliveryMethod, byte channelNumber)
		{
			int mtu = _mtu;
			NetPacket netPacket = NetManager.PoolGetPacket(mtu);
			if (deliveryMethod == DeliveryMethod.Unreliable)
			{
				netPacket.Property = PacketProperty.Unreliable;
				return new PooledPacket(netPacket, mtu, 0);
			}
			netPacket.Property = PacketProperty.Channeled;
			return new PooledPacket(netPacket, mtu, (byte)((uint)(channelNumber * 4) + (uint)deliveryMethod));
		}

		public void SendPooledPacket(PooledPacket packet, int userDataSize)
		{
			if (_connectionState == ConnectionState.Connected)
			{
				packet._packet.Size = packet.UserDataOffset + userDataSize;
				if (packet._packet.Property == PacketProperty.Channeled)
				{
					CreateChannel(packet._channelNumber).AddToQueue(packet._packet);
				}
				else
				{
					EnqueueUnreliable(packet._packet);
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void EnqueueUnreliable(NetPacket packet)
		{
			lock (_unreliableChannelLock)
			{
				if (_unreliablePendingCount == _unreliableChannel.Length)
				{
					Array.Resize(ref _unreliableChannel, _unreliablePendingCount * 2);
				}
				_unreliableChannel[_unreliablePendingCount++] = packet;
			}
		}

		private BaseChannel CreateChannel(byte idx)
		{
			BaseChannel baseChannel = _channels[idx];
			if (baseChannel != null)
			{
				return baseChannel;
			}
			switch ((DeliveryMethod)(byte)(idx % 4))
			{
			case DeliveryMethod.ReliableUnordered:
				baseChannel = new ReliableChannel(this, ordered: false, idx);
				break;
			case DeliveryMethod.Sequenced:
				baseChannel = new SequencedChannel(this, reliable: false, idx);
				break;
			case DeliveryM

netstandard.dll

Decompiled 2 hours ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Configuration.Assemblies;
using System.Data;
using System.Data.Common;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Diagnostics.SymbolStore;
using System.Diagnostics.Tracing;
using System.Drawing;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.IO.IsolatedStorage;
using System.IO.MemoryMappedFiles;
using System.IO.Pipes;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Cache;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mail;
using System.Net.Mime;
using System.Net.NetworkInformation;
using System.Net.Security;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Authentication;
using System.Security.Authentication.ExtendedProtection;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Transactions;
using System.Web;
using System.Windows.Input;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Resolvers;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Xml.XPath;
using System.Xml.Xsl;
using Microsoft.Win32.SafeHandles;

[assembly: AssemblyTitle("netstandard")]
[assembly: AssemblyDescription("netstandard")]
[assembly: AssemblyDefaultAlias("netstandard")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyFileVersion("4.6.26011.1")]
[assembly: AssemblyInformationalVersion("4.6.26011.1")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: TypeForwardedTo(typeof(CriticalHandleMinusOneIsInvalid))]
[assembly: TypeForwardedTo(typeof(CriticalHandleZeroOrMinusOneIsInvalid))]
[assembly: TypeForwardedTo(typeof(SafeFileHandle))]
[assembly: TypeForwardedTo(typeof(SafeHandleMinusOneIsInvalid))]
[assembly: TypeForwardedTo(typeof(SafeHandleZeroOrMinusOneIsInvalid))]
[assembly: TypeForwardedTo(typeof(SafeMemoryMappedFileHandle))]
[assembly: TypeForwardedTo(typeof(SafeMemoryMappedViewHandle))]
[assembly: TypeForwardedTo(typeof(SafePipeHandle))]
[assembly: TypeForwardedTo(typeof(SafeProcessHandle))]
[assembly: TypeForwardedTo(typeof(SafeWaitHandle))]
[assembly: TypeForwardedTo(typeof(SafeX509ChainHandle))]
[assembly: TypeForwardedTo(typeof(AccessViolationException))]
[assembly: TypeForwardedTo(typeof(Action))]
[assembly: TypeForwardedTo(typeof(Action<>))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, >))]
[assembly: TypeForwardedTo(typeof(Action<, , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Action<, , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Activator))]
[assembly: TypeForwardedTo(typeof(AggregateException))]
[assembly: TypeForwardedTo(typeof(AppContext))]
[assembly: TypeForwardedTo(typeof(AppDomain))]
[assembly: TypeForwardedTo(typeof(AppDomainUnloadedException))]
[assembly: TypeForwardedTo(typeof(ApplicationException))]
[assembly: TypeForwardedTo(typeof(ApplicationId))]
[assembly: TypeForwardedTo(typeof(ArgumentException))]
[assembly: TypeForwardedTo(typeof(ArgumentNullException))]
[assembly: TypeForwardedTo(typeof(ArgumentOutOfRangeException))]
[assembly: TypeForwardedTo(typeof(ArithmeticException))]
[assembly: TypeForwardedTo(typeof(Array))]
[assembly: TypeForwardedTo(typeof(ArraySegment<>))]
[assembly: TypeForwardedTo(typeof(ArrayTypeMismatchException))]
[assembly: TypeForwardedTo(typeof(AssemblyLoadEventArgs))]
[assembly: TypeForwardedTo(typeof(AssemblyLoadEventHandler))]
[assembly: TypeForwardedTo(typeof(AsyncCallback))]
[assembly: TypeForwardedTo(typeof(Attribute))]
[assembly: TypeForwardedTo(typeof(AttributeTargets))]
[assembly: TypeForwardedTo(typeof(AttributeUsageAttribute))]
[assembly: TypeForwardedTo(typeof(BadImageFormatException))]
[assembly: TypeForwardedTo(typeof(Base64FormattingOptions))]
[assembly: TypeForwardedTo(typeof(BitConverter))]
[assembly: TypeForwardedTo(typeof(bool))]
[assembly: TypeForwardedTo(typeof(Buffer))]
[assembly: TypeForwardedTo(typeof(byte))]
[assembly: TypeForwardedTo(typeof(CannotUnloadAppDomainException))]
[assembly: TypeForwardedTo(typeof(char))]
[assembly: TypeForwardedTo(typeof(CharEnumerator))]
[assembly: TypeForwardedTo(typeof(CLSCompliantAttribute))]
[assembly: TypeForwardedTo(typeof(GeneratedCodeAttribute))]
[assembly: TypeForwardedTo(typeof(IndentedTextWriter))]
[assembly: TypeForwardedTo(typeof(ArrayList))]
[assembly: TypeForwardedTo(typeof(BitArray))]
[assembly: TypeForwardedTo(typeof(CaseInsensitiveComparer))]
[assembly: TypeForwardedTo(typeof(CaseInsensitiveHashCodeProvider))]
[assembly: TypeForwardedTo(typeof(CollectionBase))]
[assembly: TypeForwardedTo(typeof(Comparer))]
[assembly: TypeForwardedTo(typeof(BlockingCollection<>))]
[assembly: TypeForwardedTo(typeof(ConcurrentBag<>))]
[assembly: TypeForwardedTo(typeof(ConcurrentDictionary<, >))]
[assembly: TypeForwardedTo(typeof(ConcurrentQueue<>))]
[assembly: TypeForwardedTo(typeof(ConcurrentStack<>))]
[assembly: TypeForwardedTo(typeof(EnumerablePartitionerOptions))]
[assembly: TypeForwardedTo(typeof(IProducerConsumerCollection<>))]
[assembly: TypeForwardedTo(typeof(OrderablePartitioner<>))]
[assembly: TypeForwardedTo(typeof(Partitioner))]
[assembly: TypeForwardedTo(typeof(Partitioner<>))]
[assembly: TypeForwardedTo(typeof(DictionaryBase))]
[assembly: TypeForwardedTo(typeof(DictionaryEntry))]
[assembly: TypeForwardedTo(typeof(Comparer<>))]
[assembly: TypeForwardedTo(typeof(Dictionary<, >))]
[assembly: TypeForwardedTo(typeof(EqualityComparer<>))]
[assembly: TypeForwardedTo(typeof(HashSet<>))]
[assembly: TypeForwardedTo(typeof(ICollection<>))]
[assembly: TypeForwardedTo(typeof(IComparer<>))]
[assembly: TypeForwardedTo(typeof(IDictionary<, >))]
[assembly: TypeForwardedTo(typeof(IEnumerable<>))]
[assembly: TypeForwardedTo(typeof(IEnumerator<>))]
[assembly: TypeForwardedTo(typeof(IEqualityComparer<>))]
[assembly: TypeForwardedTo(typeof(IList<>))]
[assembly: TypeForwardedTo(typeof(IReadOnlyCollection<>))]
[assembly: TypeForwardedTo(typeof(IReadOnlyDictionary<, >))]
[assembly: TypeForwardedTo(typeof(IReadOnlyList<>))]
[assembly: TypeForwardedTo(typeof(ISet<>))]
[assembly: TypeForwardedTo(typeof(KeyNotFoundException))]
[assembly: TypeForwardedTo(typeof(KeyValuePair<, >))]
[assembly: TypeForwardedTo(typeof(LinkedListNode<>))]
[assembly: TypeForwardedTo(typeof(LinkedList<>))]
[assembly: TypeForwardedTo(typeof(List<>))]
[assembly: TypeForwardedTo(typeof(Queue<>))]
[assembly: TypeForwardedTo(typeof(SortedDictionary<, >))]
[assembly: TypeForwardedTo(typeof(SortedList<, >))]
[assembly: TypeForwardedTo(typeof(SortedSet<>))]
[assembly: TypeForwardedTo(typeof(Stack<>))]
[assembly: TypeForwardedTo(typeof(Hashtable))]
[assembly: TypeForwardedTo(typeof(ICollection))]
[assembly: TypeForwardedTo(typeof(IComparer))]
[assembly: TypeForwardedTo(typeof(IDictionary))]
[assembly: TypeForwardedTo(typeof(IDictionaryEnumerator))]
[assembly: TypeForwardedTo(typeof(IEnumerable))]
[assembly: TypeForwardedTo(typeof(IEnumerator))]
[assembly: TypeForwardedTo(typeof(IEqualityComparer))]
[assembly: TypeForwardedTo(typeof(IHashCodeProvider))]
[assembly: TypeForwardedTo(typeof(IList))]
[assembly: TypeForwardedTo(typeof(IStructuralComparable))]
[assembly: TypeForwardedTo(typeof(IStructuralEquatable))]
[assembly: TypeForwardedTo(typeof(Collection<>))]
[assembly: TypeForwardedTo(typeof(KeyedCollection<, >))]
[assembly: TypeForwardedTo(typeof(ObservableCollection<>))]
[assembly: TypeForwardedTo(typeof(ReadOnlyCollection<>))]
[assembly: TypeForwardedTo(typeof(ReadOnlyDictionary<, >))]
[assembly: TypeForwardedTo(typeof(ReadOnlyObservableCollection<>))]
[assembly: TypeForwardedTo(typeof(Queue))]
[assembly: TypeForwardedTo(typeof(ReadOnlyCollectionBase))]
[assembly: TypeForwardedTo(typeof(SortedList))]
[assembly: TypeForwardedTo(typeof(BitVector32))]
[assembly: TypeForwardedTo(typeof(CollectionsUtil))]
[assembly: TypeForwardedTo(typeof(HybridDictionary))]
[assembly: TypeForwardedTo(typeof(INotifyCollectionChanged))]
[assembly: TypeForwardedTo(typeof(IOrderedDictionary))]
[assembly: TypeForwardedTo(typeof(ListDictionary))]
[assembly: TypeForwardedTo(typeof(NameObjectCollectionBase))]
[assembly: TypeForwardedTo(typeof(NameValueCollection))]
[assembly: TypeForwardedTo(typeof(NotifyCollectionChangedAction))]
[assembly: TypeForwardedTo(typeof(NotifyCollectionChangedEventArgs))]
[assembly: TypeForwardedTo(typeof(NotifyCollectionChangedEventHandler))]
[assembly: TypeForwardedTo(typeof(OrderedDictionary))]
[assembly: TypeForwardedTo(typeof(StringCollection))]
[assembly: TypeForwardedTo(typeof(StringDictionary))]
[assembly: TypeForwardedTo(typeof(StringEnumerator))]
[assembly: TypeForwardedTo(typeof(Stack))]
[assembly: TypeForwardedTo(typeof(StructuralComparisons))]
[assembly: TypeForwardedTo(typeof(Comparison<>))]
[assembly: TypeForwardedTo(typeof(AddingNewEventArgs))]
[assembly: TypeForwardedTo(typeof(AddingNewEventHandler))]
[assembly: TypeForwardedTo(typeof(AmbientValueAttribute))]
[assembly: TypeForwardedTo(typeof(ArrayConverter))]
[assembly: TypeForwardedTo(typeof(AsyncCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(AsyncCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(AsyncOperation))]
[assembly: TypeForwardedTo(typeof(AsyncOperationManager))]
[assembly: TypeForwardedTo(typeof(AttributeCollection))]
[assembly: TypeForwardedTo(typeof(AttributeProviderAttribute))]
[assembly: TypeForwardedTo(typeof(BackgroundWorker))]
[assembly: TypeForwardedTo(typeof(BaseNumberConverter))]
[assembly: TypeForwardedTo(typeof(BindableAttribute))]
[assembly: TypeForwardedTo(typeof(BindableSupport))]
[assembly: TypeForwardedTo(typeof(BindingDirection))]
[assembly: TypeForwardedTo(typeof(BindingList<>))]
[assembly: TypeForwardedTo(typeof(BooleanConverter))]
[assembly: TypeForwardedTo(typeof(BrowsableAttribute))]
[assembly: TypeForwardedTo(typeof(ByteConverter))]
[assembly: TypeForwardedTo(typeof(CancelEventArgs))]
[assembly: TypeForwardedTo(typeof(CancelEventHandler))]
[assembly: TypeForwardedTo(typeof(CategoryAttribute))]
[assembly: TypeForwardedTo(typeof(CharConverter))]
[assembly: TypeForwardedTo(typeof(CollectionChangeAction))]
[assembly: TypeForwardedTo(typeof(CollectionChangeEventArgs))]
[assembly: TypeForwardedTo(typeof(CollectionChangeEventHandler))]
[assembly: TypeForwardedTo(typeof(CollectionConverter))]
[assembly: TypeForwardedTo(typeof(ComplexBindingPropertiesAttribute))]
[assembly: TypeForwardedTo(typeof(Component))]
[assembly: TypeForwardedTo(typeof(ComponentCollection))]
[assembly: TypeForwardedTo(typeof(ComponentConverter))]
[assembly: TypeForwardedTo(typeof(ComponentEditor))]
[assembly: TypeForwardedTo(typeof(ComponentResourceManager))]
[assembly: TypeForwardedTo(typeof(Container))]
[assembly: TypeForwardedTo(typeof(ContainerFilterService))]
[assembly: TypeForwardedTo(typeof(CultureInfoConverter))]
[assembly: TypeForwardedTo(typeof(CustomTypeDescriptor))]
[assembly: TypeForwardedTo(typeof(DataErrorsChangedEventArgs))]
[assembly: TypeForwardedTo(typeof(DataObjectAttribute))]
[assembly: TypeForwardedTo(typeof(DataObjectFieldAttribute))]
[assembly: TypeForwardedTo(typeof(DataObjectMethodAttribute))]
[assembly: TypeForwardedTo(typeof(DataObjectMethodType))]
[assembly: TypeForwardedTo(typeof(DateTimeConverter))]
[assembly: TypeForwardedTo(typeof(DateTimeOffsetConverter))]
[assembly: TypeForwardedTo(typeof(DecimalConverter))]
[assembly: TypeForwardedTo(typeof(DefaultBindingPropertyAttribute))]
[assembly: TypeForwardedTo(typeof(DefaultEventAttribute))]
[assembly: TypeForwardedTo(typeof(DefaultPropertyAttribute))]
[assembly: TypeForwardedTo(typeof(DefaultValueAttribute))]
[assembly: TypeForwardedTo(typeof(DescriptionAttribute))]
[assembly: TypeForwardedTo(typeof(ActiveDesignerEventArgs))]
[assembly: TypeForwardedTo(typeof(ActiveDesignerEventHandler))]
[assembly: TypeForwardedTo(typeof(CheckoutException))]
[assembly: TypeForwardedTo(typeof(CommandID))]
[assembly: TypeForwardedTo(typeof(ComponentChangedEventArgs))]
[assembly: TypeForwardedTo(typeof(ComponentChangedEventHandler))]
[assembly: TypeForwardedTo(typeof(ComponentChangingEventArgs))]
[assembly: TypeForwardedTo(typeof(ComponentChangingEventHandler))]
[assembly: TypeForwardedTo(typeof(ComponentEventArgs))]
[assembly: TypeForwardedTo(typeof(ComponentEventHandler))]
[assembly: TypeForwardedTo(typeof(ComponentRenameEventArgs))]
[assembly: TypeForwardedTo(typeof(ComponentRenameEventHandler))]
[assembly: TypeForwardedTo(typeof(DesignerCollection))]
[assembly: TypeForwardedTo(typeof(DesignerEventArgs))]
[assembly: TypeForwardedTo(typeof(DesignerEventHandler))]
[assembly: TypeForwardedTo(typeof(DesignerOptionService))]
[assembly: TypeForwardedTo(typeof(DesignerTransaction))]
[assembly: TypeForwardedTo(typeof(DesignerTransactionCloseEventArgs))]
[assembly: TypeForwardedTo(typeof(DesignerTransactionCloseEventHandler))]
[assembly: TypeForwardedTo(typeof(DesignerVerb))]
[assembly: TypeForwardedTo(typeof(DesignerVerbCollection))]
[assembly: TypeForwardedTo(typeof(DesigntimeLicenseContext))]
[assembly: TypeForwardedTo(typeof(DesigntimeLicenseContextSerializer))]
[assembly: TypeForwardedTo(typeof(HelpContextType))]
[assembly: TypeForwardedTo(typeof(HelpKeywordAttribute))]
[assembly: TypeForwardedTo(typeof(HelpKeywordType))]
[assembly: TypeForwardedTo(typeof(IComponentChangeService))]
[assembly: TypeForwardedTo(typeof(IComponentDiscoveryService))]
[assembly: TypeForwardedTo(typeof(IComponentInitializer))]
[assembly: TypeForwardedTo(typeof(IDesigner))]
[assembly: TypeForwardedTo(typeof(IDesignerEventService))]
[assembly: TypeForwardedTo(typeof(IDesignerFilter))]
[assembly: TypeForwardedTo(typeof(IDesignerHost))]
[assembly: TypeForwardedTo(typeof(IDesignerHostTransactionState))]
[assembly: TypeForwardedTo(typeof(IDesignerOptionService))]
[assembly: TypeForwardedTo(typeof(IDictionaryService))]
[assembly: TypeForwardedTo(typeof(IEventBindingService))]
[assembly: TypeForwardedTo(typeof(IExtenderListService))]
[assembly: TypeForwardedTo(typeof(IExtenderProviderService))]
[assembly: TypeForwardedTo(typeof(IHelpService))]
[assembly: TypeForwardedTo(typeof(IInheritanceService))]
[assembly: TypeForwardedTo(typeof(IMenuCommandService))]
[assembly: TypeForwardedTo(typeof(IReferenceService))]
[assembly: TypeForwardedTo(typeof(IResourceService))]
[assembly: TypeForwardedTo(typeof(IRootDesigner))]
[assembly: TypeForwardedTo(typeof(ISelectionService))]
[assembly: TypeForwardedTo(typeof(IServiceContainer))]
[assembly: TypeForwardedTo(typeof(ITreeDesigner))]
[assembly: TypeForwardedTo(typeof(ITypeDescriptorFilterService))]
[assembly: TypeForwardedTo(typeof(ITypeDiscoveryService))]
[assembly: TypeForwardedTo(typeof(ITypeResolutionService))]
[assembly: TypeForwardedTo(typeof(MenuCommand))]
[assembly: TypeForwardedTo(typeof(SelectionTypes))]
[assembly: TypeForwardedTo(typeof(ComponentSerializationService))]
[assembly: TypeForwardedTo(typeof(ContextStack))]
[assembly: TypeForwardedTo(typeof(DefaultSerializationProviderAttribute))]
[assembly: TypeForwardedTo(typeof(DesignerLoader))]
[assembly: TypeForwardedTo(typeof(DesignerSerializerAttribute))]
[assembly: TypeForwardedTo(typeof(IDesignerLoaderHost))]
[assembly: TypeForwardedTo(typeof(IDesignerLoaderHost2))]
[assembly: TypeForwardedTo(typeof(IDesignerLoaderService))]
[assembly: TypeForwardedTo(typeof(IDesignerSerializationManager))]
[assembly: TypeForwardedTo(typeof(IDesignerSerializationProvider))]
[assembly: TypeForwardedTo(typeof(IDesignerSerializationService))]
[assembly: TypeForwardedTo(typeof(INameCreationService))]
[assembly: TypeForwardedTo(typeof(InstanceDescriptor))]
[assembly: TypeForwardedTo(typeof(MemberRelationship))]
[assembly: TypeForwardedTo(typeof(MemberRelationshipService))]
[assembly: TypeForwardedTo(typeof(ResolveNameEventArgs))]
[assembly: TypeForwardedTo(typeof(ResolveNameEventHandler))]
[assembly: TypeForwardedTo(typeof(RootDesignerSerializerAttribute))]
[assembly: TypeForwardedTo(typeof(SerializationStore))]
[assembly: TypeForwardedTo(typeof(ServiceContainer))]
[assembly: TypeForwardedTo(typeof(ServiceCreatorCallback))]
[assembly: TypeForwardedTo(typeof(StandardCommands))]
[assembly: TypeForwardedTo(typeof(StandardToolWindows))]
[assembly: TypeForwardedTo(typeof(TypeDescriptionProviderService))]
[assembly: TypeForwardedTo(typeof(ViewTechnology))]
[assembly: TypeForwardedTo(typeof(DesignerAttribute))]
[assembly: TypeForwardedTo(typeof(DesignerCategoryAttribute))]
[assembly: TypeForwardedTo(typeof(DesignerSerializationVisibility))]
[assembly: TypeForwardedTo(typeof(DesignerSerializationVisibilityAttribute))]
[assembly: TypeForwardedTo(typeof(DesignOnlyAttribute))]
[assembly: TypeForwardedTo(typeof(DesignTimeVisibleAttribute))]
[assembly: TypeForwardedTo(typeof(DisplayNameAttribute))]
[assembly: TypeForwardedTo(typeof(DoubleConverter))]
[assembly: TypeForwardedTo(typeof(DoWorkEventArgs))]
[assembly: TypeForwardedTo(typeof(DoWorkEventHandler))]
[assembly: TypeForwardedTo(typeof(EditorAttribute))]
[assembly: TypeForwardedTo(typeof(EditorBrowsableAttribute))]
[assembly: TypeForwardedTo(typeof(EditorBrowsableState))]
[assembly: TypeForwardedTo(typeof(EnumConverter))]
[assembly: TypeForwardedTo(typeof(EventDescriptor))]
[assembly: TypeForwardedTo(typeof(EventDescriptorCollection))]
[assembly: TypeForwardedTo(typeof(EventHandlerList))]
[assembly: TypeForwardedTo(typeof(ExpandableObjectConverter))]
[assembly: TypeForwardedTo(typeof(ExtenderProvidedPropertyAttribute))]
[assembly: TypeForwardedTo(typeof(GuidConverter))]
[assembly: TypeForwardedTo(typeof(HandledEventArgs))]
[assembly: TypeForwardedTo(typeof(HandledEventHandler))]
[assembly: TypeForwardedTo(typeof(IBindingList))]
[assembly: TypeForwardedTo(typeof(IBindingListView))]
[assembly: TypeForwardedTo(typeof(ICancelAddNew))]
[assembly: TypeForwardedTo(typeof(IChangeTracking))]
[assembly: TypeForwardedTo(typeof(IComNativeDescriptorHandler))]
[assembly: TypeForwardedTo(typeof(IComponent))]
[assembly: TypeForwardedTo(typeof(IContainer))]
[assembly: TypeForwardedTo(typeof(ICustomTypeDescriptor))]
[assembly: TypeForwardedTo(typeof(IDataErrorInfo))]
[assembly: TypeForwardedTo(typeof(IEditableObject))]
[assembly: TypeForwardedTo(typeof(IExtenderProvider))]
[assembly: TypeForwardedTo(typeof(IIntellisenseBuilder))]
[assembly: TypeForwardedTo(typeof(IListSource))]
[assembly: TypeForwardedTo(typeof(ImmutableObjectAttribute))]
[assembly: TypeForwardedTo(typeof(INestedContainer))]
[assembly: TypeForwardedTo(typeof(INestedSite))]
[assembly: TypeForwardedTo(typeof(InheritanceAttribute))]
[assembly: TypeForwardedTo(typeof(InheritanceLevel))]
[assembly: TypeForwardedTo(typeof(InitializationEventAttribute))]
[assembly: TypeForwardedTo(typeof(INotifyDataErrorInfo))]
[assembly: TypeForwardedTo(typeof(INotifyPropertyChanged))]
[assembly: TypeForwardedTo(typeof(INotifyPropertyChanging))]
[assembly: TypeForwardedTo(typeof(InstallerTypeAttribute))]
[assembly: TypeForwardedTo(typeof(InstanceCreationEditor))]
[assembly: TypeForwardedTo(typeof(Int16Converter))]
[assembly: TypeForwardedTo(typeof(Int32Converter))]
[assembly: TypeForwardedTo(typeof(Int64Converter))]
[assembly: TypeForwardedTo(typeof(InvalidAsynchronousStateException))]
[assembly: TypeForwardedTo(typeof(InvalidEnumArgumentException))]
[assembly: TypeForwardedTo(typeof(IRaiseItemChangedEvents))]
[assembly: TypeForwardedTo(typeof(IRevertibleChangeTracking))]
[assembly: TypeForwardedTo(typeof(ISite))]
[assembly: TypeForwardedTo(typeof(ISupportInitialize))]
[assembly: TypeForwardedTo(typeof(ISupportInitializeNotification))]
[assembly: TypeForwardedTo(typeof(ISynchronizeInvoke))]
[assembly: TypeForwardedTo(typeof(ITypeDescriptorContext))]
[assembly: TypeForwardedTo(typeof(ITypedList))]
[assembly: TypeForwardedTo(typeof(License))]
[assembly: TypeForwardedTo(typeof(LicenseContext))]
[assembly: TypeForwardedTo(typeof(LicenseException))]
[assembly: TypeForwardedTo(typeof(LicenseManager))]
[assembly: TypeForwardedTo(typeof(LicenseProvider))]
[assembly: TypeForwardedTo(typeof(LicenseProviderAttribute))]
[assembly: TypeForwardedTo(typeof(LicenseUsageMode))]
[assembly: TypeForwardedTo(typeof(LicFileLicenseProvider))]
[assembly: TypeForwardedTo(typeof(ListBindableAttribute))]
[assembly: TypeForwardedTo(typeof(ListChangedEventArgs))]
[assembly: TypeForwardedTo(typeof(ListChangedEventHandler))]
[assembly: TypeForwardedTo(typeof(ListChangedType))]
[assembly: TypeForwardedTo(typeof(ListSortDescription))]
[assembly: TypeForwardedTo(typeof(ListSortDescriptionCollection))]
[assembly: TypeForwardedTo(typeof(ListSortDirection))]
[assembly: TypeForwardedTo(typeof(LocalizableAttribute))]
[assembly: TypeForwardedTo(typeof(LookupBindingPropertiesAttribute))]
[assembly: TypeForwardedTo(typeof(MarshalByValueComponent))]
[assembly: TypeForwardedTo(typeof(MaskedTextProvider))]
[assembly: TypeForwardedTo(typeof(MaskedTextResultHint))]
[assembly: TypeForwardedTo(typeof(MemberDescriptor))]
[assembly: TypeForwardedTo(typeof(MergablePropertyAttribute))]
[assembly: TypeForwardedTo(typeof(MultilineStringConverter))]
[assembly: TypeForwardedTo(typeof(NestedContainer))]
[assembly: TypeForwardedTo(typeof(NotifyParentPropertyAttribute))]
[assembly: TypeForwardedTo(typeof(NullableConverter))]
[assembly: TypeForwardedTo(typeof(ParenthesizePropertyNameAttribute))]
[assembly: TypeForwardedTo(typeof(PasswordPropertyTextAttribute))]
[assembly: TypeForwardedTo(typeof(ProgressChangedEventArgs))]
[assembly: TypeForwardedTo(typeof(ProgressChangedEventHandler))]
[assembly: TypeForwardedTo(typeof(PropertyChangedEventArgs))]
[assembly: TypeForwardedTo(typeof(PropertyChangedEventHandler))]
[assembly: TypeForwardedTo(typeof(PropertyChangingEventArgs))]
[assembly: TypeForwardedTo(typeof(PropertyChangingEventHandler))]
[assembly: TypeForwardedTo(typeof(PropertyDescriptor))]
[assembly: TypeForwardedTo(typeof(PropertyDescriptorCollection))]
[assembly: TypeForwardedTo(typeof(PropertyTabAttribute))]
[assembly: TypeForwardedTo(typeof(PropertyTabScope))]
[assembly: TypeForwardedTo(typeof(ProvidePropertyAttribute))]
[assembly: TypeForwardedTo(typeof(ReadOnlyAttribute))]
[assembly: TypeForwardedTo(typeof(RecommendedAsConfigurableAttribute))]
[assembly: TypeForwardedTo(typeof(ReferenceConverter))]
[assembly: TypeForwardedTo(typeof(RefreshEventArgs))]
[assembly: TypeForwardedTo(typeof(RefreshEventHandler))]
[assembly: TypeForwardedTo(typeof(RefreshProperties))]
[assembly: TypeForwardedTo(typeof(RefreshPropertiesAttribute))]
[assembly: TypeForwardedTo(typeof(RunInstallerAttribute))]
[assembly: TypeForwardedTo(typeof(RunWorkerCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(RunWorkerCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(SByteConverter))]
[assembly: TypeForwardedTo(typeof(SettingsBindableAttribute))]
[assembly: TypeForwardedTo(typeof(SingleConverter))]
[assembly: TypeForwardedTo(typeof(StringConverter))]
[assembly: TypeForwardedTo(typeof(SyntaxCheck))]
[assembly: TypeForwardedTo(typeof(TimeSpanConverter))]
[assembly: TypeForwardedTo(typeof(ToolboxItemAttribute))]
[assembly: TypeForwardedTo(typeof(ToolboxItemFilterAttribute))]
[assembly: TypeForwardedTo(typeof(ToolboxItemFilterType))]
[assembly: TypeForwardedTo(typeof(TypeConverter))]
[assembly: TypeForwardedTo(typeof(TypeConverterAttribute))]
[assembly: TypeForwardedTo(typeof(TypeDescriptionProvider))]
[assembly: TypeForwardedTo(typeof(TypeDescriptionProviderAttribute))]
[assembly: TypeForwardedTo(typeof(TypeDescriptor))]
[assembly: TypeForwardedTo(typeof(TypeListConverter))]
[assembly: TypeForwardedTo(typeof(UInt16Converter))]
[assembly: TypeForwardedTo(typeof(UInt32Converter))]
[assembly: TypeForwardedTo(typeof(UInt64Converter))]
[assembly: TypeForwardedTo(typeof(WarningException))]
[assembly: TypeForwardedTo(typeof(Win32Exception))]
[assembly: TypeForwardedTo(typeof(AssemblyHashAlgorithm))]
[assembly: TypeForwardedTo(typeof(AssemblyVersionCompatibility))]
[assembly: TypeForwardedTo(typeof(Console))]
[assembly: TypeForwardedTo(typeof(ConsoleCancelEventArgs))]
[assembly: TypeForwardedTo(typeof(ConsoleCancelEventHandler))]
[assembly: TypeForwardedTo(typeof(ConsoleColor))]
[assembly: TypeForwardedTo(typeof(ConsoleKey))]
[assembly: TypeForwardedTo(typeof(ConsoleKeyInfo))]
[assembly: TypeForwardedTo(typeof(ConsoleModifiers))]
[assembly: TypeForwardedTo(typeof(ConsoleSpecialKey))]
[assembly: TypeForwardedTo(typeof(ContextBoundObject))]
[assembly: TypeForwardedTo(typeof(ContextMarshalException))]
[assembly: TypeForwardedTo(typeof(ContextStaticAttribute))]
[assembly: TypeForwardedTo(typeof(Convert))]
[assembly: TypeForwardedTo(typeof(Converter<, >))]
[assembly: TypeForwardedTo(typeof(AcceptRejectRule))]
[assembly: TypeForwardedTo(typeof(CommandBehavior))]
[assembly: TypeForwardedTo(typeof(CommandType))]
[assembly: TypeForwardedTo(typeof(CatalogLocation))]
[assembly: TypeForwardedTo(typeof(DataAdapter))]
[assembly: TypeForwardedTo(typeof(DataColumnMapping))]
[assembly: TypeForwardedTo(typeof(DataColumnMappingCollection))]
[assembly: TypeForwardedTo(typeof(DataTableMapping))]
[assembly: TypeForwardedTo(typeof(DataTableMappingCollection))]
[assembly: TypeForwardedTo(typeof(DbColumn))]
[assembly: TypeForwardedTo(typeof(DbCommand))]
[assembly: TypeForwardedTo(typeof(DbCommandBuilder))]
[assembly: TypeForwardedTo(typeof(DbConnection))]
[assembly: TypeForwardedTo(typeof(DbConnectionStringBuilder))]
[assembly: TypeForwardedTo(typeof(DbDataAdapter))]
[assembly: TypeForwardedTo(typeof(DbDataReader))]
[assembly: TypeForwardedTo(typeof(DbDataReaderExtensions))]
[assembly: TypeForwardedTo(typeof(DbDataRecord))]
[assembly: TypeForwardedTo(typeof(DbDataSourceEnumerator))]
[assembly: TypeForwardedTo(typeof(DbEnumerator))]
[assembly: TypeForwardedTo(typeof(DbException))]
[assembly: TypeForwardedTo(typeof(DbMetaDataCollectionNames))]
[assembly: TypeForwardedTo(typeof(DbMetaDataColumnNames))]
[assembly: TypeForwardedTo(typeof(DbParameter))]
[assembly: TypeForwardedTo(typeof(DbParameterCollection))]
[assembly: TypeForwardedTo(typeof(DbProviderFactory))]
[assembly: TypeForwardedTo(typeof(DbProviderSpecificTypePropertyAttribute))]
[assembly: TypeForwardedTo(typeof(DbTransaction))]
[assembly: TypeForwardedTo(typeof(GroupByBehavior))]
[assembly: TypeForwardedTo(typeof(IDbColumnSchemaGenerator))]
[assembly: TypeForwardedTo(typeof(IdentifierCase))]
[assembly: TypeForwardedTo(typeof(RowUpdatedEventArgs))]
[assembly: TypeForwardedTo(typeof(RowUpdatingEventArgs))]
[assembly: TypeForwardedTo(typeof(SchemaTableColumn))]
[assembly: TypeForwardedTo(typeof(SchemaTableOptionalColumn))]
[assembly: TypeForwardedTo(typeof(SupportedJoinOperators))]
[assembly: TypeForwardedTo(typeof(ConflictOption))]
[assembly: TypeForwardedTo(typeof(ConnectionState))]
[assembly: TypeForwardedTo(typeof(Constraint))]
[assembly: TypeForwardedTo(typeof(ConstraintCollection))]
[assembly: TypeForwardedTo(typeof(ConstraintException))]
[assembly: TypeForwardedTo(typeof(DataColumn))]
[assembly: TypeForwardedTo(typeof(DataColumnChangeEventArgs))]
[assembly: TypeForwardedTo(typeof(DataColumnChangeEventHandler))]
[assembly: TypeForwardedTo(typeof(DataColumnCollection))]
[assembly: TypeForwardedTo(typeof(DataException))]
[assembly: TypeForwardedTo(typeof(DataRelation))]
[assembly: TypeForwardedTo(typeof(DataRelationCollection))]
[assembly: TypeForwardedTo(typeof(DataRow))]
[assembly: TypeForwardedTo(typeof(DataRowAction))]
[assembly: TypeForwardedTo(typeof(DataRowBuilder))]
[assembly: TypeForwardedTo(typeof(DataRowChangeEventArgs))]
[assembly: TypeForwardedTo(typeof(DataRowChangeEventHandler))]
[assembly: TypeForwardedTo(typeof(DataRowCollection))]
[assembly: TypeForwardedTo(typeof(DataRowState))]
[assembly: TypeForwardedTo(typeof(DataRowVersion))]
[assembly: TypeForwardedTo(typeof(DataRowView))]
[assembly: TypeForwardedTo(typeof(DataSet))]
[assembly: TypeForwardedTo(typeof(DataSetDateTime))]
[assembly: TypeForwardedTo(typeof(DataSysDescriptionAttribute))]
[assembly: TypeForwardedTo(typeof(DataTable))]
[assembly: TypeForwardedTo(typeof(DataTableClearEventArgs))]
[assembly: TypeForwardedTo(typeof(DataTableClearEventHandler))]
[assembly: TypeForwardedTo(typeof(DataTableCollection))]
[assembly: TypeForwardedTo(typeof(DataTableNewRowEventArgs))]
[assembly: TypeForwardedTo(typeof(DataTableNewRowEventHandler))]
[assembly: TypeForwardedTo(typeof(DataTableReader))]
[assembly: TypeForwardedTo(typeof(DataView))]
[assembly: TypeForwardedTo(typeof(DataViewManager))]
[assembly: TypeForwardedTo(typeof(DataViewRowState))]
[assembly: TypeForwardedTo(typeof(DataViewSetting))]
[assembly: TypeForwardedTo(typeof(DataViewSettingCollection))]
[assembly: TypeForwardedTo(typeof(DBConcurrencyException))]
[assembly: TypeForwardedTo(typeof(DbType))]
[assembly: TypeForwardedTo(typeof(DeletedRowInaccessibleException))]
[assembly: TypeForwardedTo(typeof(DuplicateNameException))]
[assembly: TypeForwardedTo(typeof(EvaluateException))]
[assembly: TypeForwardedTo(typeof(FillErrorEventArgs))]
[assembly: TypeForwardedTo(typeof(FillErrorEventHandler))]
[assembly: TypeForwardedTo(typeof(ForeignKeyConstraint))]
[assembly: TypeForwardedTo(typeof(IColumnMapping))]
[assembly: TypeForwardedTo(typeof(IColumnMappingCollection))]
[assembly: TypeForwardedTo(typeof(IDataAdapter))]
[assembly: TypeForwardedTo(typeof(IDataParameter))]
[assembly: TypeForwardedTo(typeof(IDataParameterCollection))]
[assembly: TypeForwardedTo(typeof(IDataReader))]
[assembly: TypeForwardedTo(typeof(IDataRecord))]
[assembly: TypeForwardedTo(typeof(IDbCommand))]
[assembly: TypeForwardedTo(typeof(IDbConnection))]
[assembly: TypeForwardedTo(typeof(IDbDataAdapter))]
[assembly: TypeForwardedTo(typeof(IDbDataParameter))]
[assembly: TypeForwardedTo(typeof(IDbTransaction))]
[assembly: TypeForwardedTo(typeof(InRowChangingEventException))]
[assembly: TypeForwardedTo(typeof(InternalDataCollectionBase))]
[assembly: TypeForwardedTo(typeof(InvalidConstraintException))]
[assembly: TypeForwardedTo(typeof(InvalidExpressionException))]
[assembly: TypeForwardedTo(typeof(System.Data.IsolationLevel))]
[assembly: TypeForwardedTo(typeof(ITableMapping))]
[assembly: TypeForwardedTo(typeof(ITableMappingCollection))]
[assembly: TypeForwardedTo(typeof(KeyRestrictionBehavior))]
[assembly: TypeForwardedTo(typeof(LoadOption))]
[assembly: TypeForwardedTo(typeof(MappingType))]
[assembly: TypeForwardedTo(typeof(MergeFailedEventArgs))]
[assembly: TypeForwardedTo(typeof(MergeFailedEventHandler))]
[assembly: TypeForwardedTo(typeof(MissingMappingAction))]
[assembly: TypeForwardedTo(typeof(MissingPrimaryKeyException))]
[assembly: TypeForwardedTo(typeof(MissingSchemaAction))]
[assembly: TypeForwardedTo(typeof(NoNullAllowedException))]
[assembly: TypeForwardedTo(typeof(ParameterDirection))]
[assembly: TypeForwardedTo(typeof(PropertyCollection))]
[assembly: TypeForwardedTo(typeof(ReadOnlyException))]
[assembly: TypeForwardedTo(typeof(RowNotInTableException))]
[assembly: TypeForwardedTo(typeof(Rule))]
[assembly: TypeForwardedTo(typeof(SchemaSerializationMode))]
[assembly: TypeForwardedTo(typeof(SchemaType))]
[assembly: TypeForwardedTo(typeof(SerializationFormat))]
[assembly: TypeForwardedTo(typeof(SqlDbType))]
[assembly: TypeForwardedTo(typeof(INullable))]
[assembly: TypeForwardedTo(typeof(SqlAlreadyFilledException))]
[assembly: TypeForwardedTo(typeof(SqlBinary))]
[assembly: TypeForwardedTo(typeof(SqlBoolean))]
[assembly: TypeForwardedTo(typeof(SqlByte))]
[assembly: TypeForwardedTo(typeof(SqlBytes))]
[assembly: TypeForwardedTo(typeof(SqlChars))]
[assembly: TypeForwardedTo(typeof(SqlCompareOptions))]
[assembly: TypeForwardedTo(typeof(SqlDateTime))]
[assembly: TypeForwardedTo(typeof(SqlDecimal))]
[assembly: TypeForwardedTo(typeof(SqlDouble))]
[assembly: TypeForwardedTo(typeof(SqlGuid))]
[assembly: TypeForwardedTo(typeof(SqlInt16))]
[assembly: TypeForwardedTo(typeof(SqlInt32))]
[assembly: TypeForwardedTo(typeof(SqlInt64))]
[assembly: TypeForwardedTo(typeof(SqlMoney))]
[assembly: TypeForwardedTo(typeof(SqlNotFilledException))]
[assembly: TypeForwardedTo(typeof(SqlNullValueException))]
[assembly: TypeForwardedTo(typeof(SqlSingle))]
[assembly: TypeForwardedTo(typeof(SqlString))]
[assembly: TypeForwardedTo(typeof(SqlTruncateException))]
[assembly: TypeForwardedTo(typeof(SqlTypeException))]
[assembly: TypeForwardedTo(typeof(SqlXml))]
[assembly: TypeForwardedTo(typeof(StorageState))]
[assembly: TypeForwardedTo(typeof(StateChangeEventArgs))]
[assembly: TypeForwardedTo(typeof(StateChangeEventHandler))]
[assembly: TypeForwardedTo(typeof(StatementCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(StatementCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(StatementType))]
[assembly: TypeForwardedTo(typeof(StrongTypingException))]
[assembly: TypeForwardedTo(typeof(SyntaxErrorException))]
[assembly: TypeForwardedTo(typeof(UniqueConstraint))]
[assembly: TypeForwardedTo(typeof(UpdateRowSource))]
[assembly: TypeForwardedTo(typeof(UpdateStatus))]
[assembly: TypeForwardedTo(typeof(VersionNotFoundException))]
[assembly: TypeForwardedTo(typeof(XmlReadMode))]
[assembly: TypeForwardedTo(typeof(XmlWriteMode))]
[assembly: TypeForwardedTo(typeof(DataMisalignedException))]
[assembly: TypeForwardedTo(typeof(DateTime))]
[assembly: TypeForwardedTo(typeof(DateTimeKind))]
[assembly: TypeForwardedTo(typeof(DateTimeOffset))]
[assembly: TypeForwardedTo(typeof(DayOfWeek))]
[assembly: TypeForwardedTo(typeof(DBNull))]
[assembly: TypeForwardedTo(typeof(decimal))]
[assembly: TypeForwardedTo(typeof(Delegate))]
[assembly: TypeForwardedTo(typeof(BooleanSwitch))]
[assembly: TypeForwardedTo(typeof(ExcludeFromCodeCoverageAttribute))]
[assembly: TypeForwardedTo(typeof(SuppressMessageAttribute))]
[assembly: TypeForwardedTo(typeof(ConditionalAttribute))]
[assembly: TypeForwardedTo(typeof(Contract))]
[assembly: TypeForwardedTo(typeof(ContractAbbreviatorAttribute))]
[assembly: TypeForwardedTo(typeof(ContractArgumentValidatorAttribute))]
[assembly: TypeForwardedTo(typeof(ContractClassAttribute))]
[assembly: TypeForwardedTo(typeof(ContractClassForAttribute))]
[assembly: TypeForwardedTo(typeof(ContractFailedEventArgs))]
[assembly: TypeForwardedTo(typeof(ContractFailureKind))]
[assembly: TypeForwardedTo(typeof(ContractInvariantMethodAttribute))]
[assembly: TypeForwardedTo(typeof(ContractOptionAttribute))]
[assembly: TypeForwardedTo(typeof(ContractPublicPropertyNameAttribute))]
[assembly: TypeForwardedTo(typeof(ContractReferenceAssemblyAttribute))]
[assembly: TypeForwardedTo(typeof(ContractRuntimeIgnoredAttribute))]
[assembly: TypeForwardedTo(typeof(ContractVerificationAttribute))]
[assembly: TypeForwardedTo(typeof(PureAttribute))]
[assembly: TypeForwardedTo(typeof(CorrelationManager))]
[assembly: TypeForwardedTo(typeof(DataReceivedEventArgs))]
[assembly: TypeForwardedTo(typeof(DataReceivedEventHandler))]
[assembly: TypeForwardedTo(typeof(Debug))]
[assembly: TypeForwardedTo(typeof(DebuggableAttribute))]
[assembly: TypeForwardedTo(typeof(Debugger))]
[assembly: TypeForwardedTo(typeof(DebuggerBrowsableAttribute))]
[assembly: TypeForwardedTo(typeof(DebuggerBrowsableState))]
[assembly: TypeForwardedTo(typeof(DebuggerDisplayAttribute))]
[assembly: TypeForwardedTo(typeof(DebuggerHiddenAttribute))]
[assembly: TypeForwardedTo(typeof(DebuggerNonUserCodeAttribute))]
[assembly: TypeForwardedTo(typeof(DebuggerStepperBoundaryAttribute))]
[assembly: TypeForwardedTo(typeof(DebuggerStepThroughAttribute))]
[assembly: TypeForwardedTo(typeof(DebuggerTypeProxyAttribute))]
[assembly: TypeForwardedTo(typeof(DebuggerVisualizerAttribute))]
[assembly: TypeForwardedTo(typeof(DefaultTraceListener))]
[assembly: TypeForwardedTo(typeof(DelimitedListTraceListener))]
[assembly: TypeForwardedTo(typeof(EventTypeFilter))]
[assembly: TypeForwardedTo(typeof(FileVersionInfo))]
[assembly: TypeForwardedTo(typeof(MonitoringDescriptionAttribute))]
[assembly: TypeForwardedTo(typeof(Process))]
[assembly: TypeForwardedTo(typeof(ProcessModule))]
[assembly: TypeForwardedTo(typeof(ProcessModuleCollection))]
[assembly: TypeForwardedTo(typeof(ProcessPriorityClass))]
[assembly: TypeForwardedTo(typeof(ProcessStartInfo))]
[assembly: TypeForwardedTo(typeof(ProcessThread))]
[assembly: TypeForwardedTo(typeof(ProcessThreadCollection))]
[assembly: TypeForwardedTo(typeof(ProcessWindowStyle))]
[assembly: TypeForwardedTo(typeof(SourceFilter))]
[assembly: TypeForwardedTo(typeof(SourceLevels))]
[assembly: TypeForwardedTo(typeof(SourceSwitch))]
[assembly: TypeForwardedTo(typeof(StackFrame))]
[assembly: TypeForwardedTo(typeof(StackFrameExtensions))]
[assembly: TypeForwardedTo(typeof(StackTrace))]
[assembly: TypeForwardedTo(typeof(Stopwatch))]
[assembly: TypeForwardedTo(typeof(Switch))]
[assembly: TypeForwardedTo(typeof(SwitchAttribute))]
[assembly: TypeForwardedTo(typeof(SwitchLevelAttribute))]
[assembly: TypeForwardedTo(typeof(ISymbolBinder))]
[assembly: TypeForwardedTo(typeof(ISymbolBinder1))]
[assembly: TypeForwardedTo(typeof(ISymbolDocument))]
[assembly: TypeForwardedTo(typeof(ISymbolDocumentWriter))]
[assembly: TypeForwardedTo(typeof(ISymbolMethod))]
[assembly: TypeForwardedTo(typeof(ISymbolNamespace))]
[assembly: TypeForwardedTo(typeof(ISymbolReader))]
[assembly: TypeForwardedTo(typeof(ISymbolScope))]
[assembly: TypeForwardedTo(typeof(ISymbolVariable))]
[assembly: TypeForwardedTo(typeof(ISymbolWriter))]
[assembly: TypeForwardedTo(typeof(SymAddressKind))]
[assembly: TypeForwardedTo(typeof(SymbolToken))]
[assembly: TypeForwardedTo(typeof(SymDocumentType))]
[assembly: TypeForwardedTo(typeof(SymLanguageType))]
[assembly: TypeForwardedTo(typeof(SymLanguageVendor))]
[assembly: TypeForwardedTo(typeof(TextWriterTraceListener))]
[assembly: TypeForwardedTo(typeof(ThreadPriorityLevel))]
[assembly: TypeForwardedTo(typeof(System.Diagnostics.ThreadState))]
[assembly: TypeForwardedTo(typeof(ThreadWaitReason))]
[assembly: TypeForwardedTo(typeof(Trace))]
[assembly: TypeForwardedTo(typeof(TraceEventCache))]
[assembly: TypeForwardedTo(typeof(TraceEventType))]
[assembly: TypeForwardedTo(typeof(TraceFilter))]
[assembly: TypeForwardedTo(typeof(TraceLevel))]
[assembly: TypeForwardedTo(typeof(TraceListener))]
[assembly: TypeForwardedTo(typeof(TraceListenerCollection))]
[assembly: TypeForwardedTo(typeof(TraceOptions))]
[assembly: TypeForwardedTo(typeof(TraceSource))]
[assembly: TypeForwardedTo(typeof(TraceSwitch))]
[assembly: TypeForwardedTo(typeof(EventActivityOptions))]
[assembly: TypeForwardedTo(typeof(EventAttribute))]
[assembly: TypeForwardedTo(typeof(EventChannel))]
[assembly: TypeForwardedTo(typeof(EventCommand))]
[assembly: TypeForwardedTo(typeof(EventCommandEventArgs))]
[assembly: TypeForwardedTo(typeof(EventCounter))]
[assembly: TypeForwardedTo(typeof(EventDataAttribute))]
[assembly: TypeForwardedTo(typeof(EventFieldAttribute))]
[assembly: TypeForwardedTo(typeof(EventFieldFormat))]
[assembly: TypeForwardedTo(typeof(EventFieldTags))]
[assembly: TypeForwardedTo(typeof(EventIgnoreAttribute))]
[assembly: TypeForwardedTo(typeof(EventKeywords))]
[assembly: TypeForwardedTo(typeof(EventLevel))]
[assembly: TypeForwardedTo(typeof(EventListener))]
[assembly: TypeForwardedTo(typeof(EventManifestOptions))]
[assembly: TypeForwardedTo(typeof(EventOpcode))]
[assembly: TypeForwardedTo(typeof(EventSource))]
[assembly: TypeForwardedTo(typeof(EventSourceAttribute))]
[assembly: TypeForwardedTo(typeof(EventSourceException))]
[assembly: TypeForwardedTo(typeof(EventSourceOptions))]
[assembly: TypeForwardedTo(typeof(EventSourceSettings))]
[assembly: TypeForwardedTo(typeof(EventTags))]
[assembly: TypeForwardedTo(typeof(EventTask))]
[assembly: TypeForwardedTo(typeof(EventWrittenEventArgs))]
[assembly: TypeForwardedTo(typeof(NonEventAttribute))]
[assembly: TypeForwardedTo(typeof(DivideByZeroException))]
[assembly: TypeForwardedTo(typeof(DllNotFoundException))]
[assembly: TypeForwardedTo(typeof(double))]
[assembly: TypeForwardedTo(typeof(Color))]
[assembly: TypeForwardedTo(typeof(Point))]
[assembly: TypeForwardedTo(typeof(PointF))]
[assembly: TypeForwardedTo(typeof(Rectangle))]
[assembly: TypeForwardedTo(typeof(RectangleF))]
[assembly: TypeForwardedTo(typeof(Size))]
[assembly: TypeForwardedTo(typeof(SizeF))]
[assembly: TypeForwardedTo(typeof(DuplicateWaitObjectException))]
[assembly: TypeForwardedTo(typeof(BinaryOperationBinder))]
[assembly: TypeForwardedTo(typeof(BindingRestrictions))]
[assembly: TypeForwardedTo(typeof(CallInfo))]
[assembly: TypeForwardedTo(typeof(ConvertBinder))]
[assembly: TypeForwardedTo(typeof(CreateInstanceBinder))]
[assembly: TypeForwardedTo(typeof(DeleteIndexBinder))]
[assembly: TypeForwardedTo(typeof(DeleteMemberBinder))]
[assembly: TypeForwardedTo(typeof(DynamicMetaObject))]
[assembly: TypeForwardedTo(typeof(DynamicMetaObjectBinder))]
[assembly: TypeForwardedTo(typeof(DynamicObject))]
[assembly: TypeForwardedTo(typeof(ExpandoObject))]
[assembly: TypeForwardedTo(typeof(GetIndexBinder))]
[assembly: TypeForwardedTo(typeof(GetMemberBinder))]
[assembly: TypeForwardedTo(typeof(IDynamicMetaObjectProvider))]
[assembly: TypeForwardedTo(typeof(IInvokeOnGetBinder))]
[assembly: TypeForwardedTo(typeof(InvokeBinder))]
[assembly: TypeForwardedTo(typeof(InvokeMemberBinder))]
[assembly: TypeForwardedTo(typeof(SetIndexBinder))]
[assembly: TypeForwardedTo(typeof(SetMemberBinder))]
[assembly: TypeForwardedTo(typeof(UnaryOperationBinder))]
[assembly: TypeForwardedTo(typeof(EntryPointNotFoundException))]
[assembly: TypeForwardedTo(typeof(Enum))]
[assembly: TypeForwardedTo(typeof(Environment))]
[assembly: TypeForwardedTo(typeof(EnvironmentVariableTarget))]
[assembly: TypeForwardedTo(typeof(EventArgs))]
[assembly: TypeForwardedTo(typeof(EventHandler))]
[assembly: TypeForwardedTo(typeof(EventHandler<>))]
[assembly: TypeForwardedTo(typeof(Exception))]
[assembly: TypeForwardedTo(typeof(ExecutionEngineException))]
[assembly: TypeForwardedTo(typeof(FieldAccessException))]
[assembly: TypeForwardedTo(typeof(FileStyleUriParser))]
[assembly: TypeForwardedTo(typeof(FlagsAttribute))]
[assembly: TypeForwardedTo(typeof(FormatException))]
[assembly: TypeForwardedTo(typeof(FormattableString))]
[assembly: TypeForwardedTo(typeof(FtpStyleUriParser))]
[assembly: TypeForwardedTo(typeof(Func<>))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , , , , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, >))]
[assembly: TypeForwardedTo(typeof(Func<, , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , >))]
[assembly: TypeForwardedTo(typeof(Func<, , , , , , , , >))]
[assembly: TypeForwardedTo(typeof(GC))]
[assembly: TypeForwardedTo(typeof(GCCollectionMode))]
[assembly: TypeForwardedTo(typeof(GCNotificationStatus))]
[assembly: TypeForwardedTo(typeof(GenericUriParser))]
[assembly: TypeForwardedTo(typeof(GenericUriParserOptions))]
[assembly: TypeForwardedTo(typeof(Calendar))]
[assembly: TypeForwardedTo(typeof(CalendarAlgorithmType))]
[assembly: TypeForwardedTo(typeof(CalendarWeekRule))]
[assembly: TypeForwardedTo(typeof(CharUnicodeInfo))]
[assembly: TypeForwardedTo(typeof(ChineseLunisolarCalendar))]
[assembly: TypeForwardedTo(typeof(CompareInfo))]
[assembly: TypeForwardedTo(typeof(CompareOptions))]
[assembly: TypeForwardedTo(typeof(CultureInfo))]
[assembly: TypeForwardedTo(typeof(CultureNotFoundException))]
[assembly: TypeForwardedTo(typeof(CultureTypes))]
[assembly: TypeForwardedTo(typeof(DateTimeFormatInfo))]
[assembly: TypeForwardedTo(typeof(DateTimeStyles))]
[assembly: TypeForwardedTo(typeof(DaylightTime))]
[assembly: TypeForwardedTo(typeof(DigitShapes))]
[assembly: TypeForwardedTo(typeof(EastAsianLunisolarCalendar))]
[assembly: TypeForwardedTo(typeof(GlobalizationExtensions))]
[assembly: TypeForwardedTo(typeof(GregorianCalendar))]
[assembly: TypeForwardedTo(typeof(GregorianCalendarTypes))]
[assembly: TypeForwardedTo(typeof(HebrewCalendar))]
[assembly: TypeForwardedTo(typeof(HijriCalendar))]
[assembly: TypeForwardedTo(typeof(IdnMapping))]
[assembly: TypeForwardedTo(typeof(JapaneseCalendar))]
[assembly: TypeForwardedTo(typeof(JapaneseLunisolarCalendar))]
[assembly: TypeForwardedTo(typeof(JulianCalendar))]
[assembly: TypeForwardedTo(typeof(KoreanCalendar))]
[assembly: TypeForwardedTo(typeof(KoreanLunisolarCalendar))]
[assembly: TypeForwardedTo(typeof(NumberFormatInfo))]
[assembly: TypeForwardedTo(typeof(NumberStyles))]
[assembly: TypeForwardedTo(typeof(PersianCalendar))]
[assembly: TypeForwardedTo(typeof(RegionInfo))]
[assembly: TypeForwardedTo(typeof(SortKey))]
[assembly: TypeForwardedTo(typeof(SortVersion))]
[assembly: TypeForwardedTo(typeof(StringInfo))]
[assembly: TypeForwardedTo(typeof(TaiwanCalendar))]
[assembly: TypeForwardedTo(typeof(TaiwanLunisolarCalendar))]
[assembly: TypeForwardedTo(typeof(TextElementEnumerator))]
[assembly: TypeForwardedTo(typeof(TextInfo))]
[assembly: TypeForwardedTo(typeof(ThaiBuddhistCalendar))]
[assembly: TypeForwardedTo(typeof(TimeSpanStyles))]
[assembly: TypeForwardedTo(typeof(UmAlQuraCalendar))]
[assembly: TypeForwardedTo(typeof(UnicodeCategory))]
[assembly: TypeForwardedTo(typeof(GopherStyleUriParser))]
[assembly: TypeForwardedTo(typeof(Guid))]
[assembly: TypeForwardedTo(typeof(HttpStyleUriParser))]
[assembly: TypeForwardedTo(typeof(IAsyncResult))]
[assembly: TypeForwardedTo(typeof(ICloneable))]
[assembly: TypeForwardedTo(typeof(IComparable))]
[assembly: TypeForwardedTo(typeof(IComparable<>))]
[assembly: TypeForwardedTo(typeof(IConvertible))]
[assembly: TypeForwardedTo(typeof(ICustomFormatter))]
[assembly: TypeForwardedTo(typeof(IDisposable))]
[assembly: TypeForwardedTo(typeof(IEquatable<>))]
[assembly: TypeForwardedTo(typeof(IFormatProvider))]
[assembly: TypeForwardedTo(typeof(IFormattable))]
[assembly: TypeForwardedTo(typeof(IndexOutOfRangeException))]
[assembly: TypeForwardedTo(typeof(InsufficientExecutionStackException))]
[assembly: TypeForwardedTo(typeof(InsufficientMemoryException))]
[assembly: TypeForwardedTo(typeof(short))]
[assembly: TypeForwardedTo(typeof(int))]
[assembly: TypeForwardedTo(typeof(long))]
[assembly: TypeForwardedTo(typeof(IntPtr))]
[assembly: TypeForwardedTo(typeof(InvalidCastException))]
[assembly: TypeForwardedTo(typeof(InvalidOperationException))]
[assembly: TypeForwardedTo(typeof(InvalidProgramException))]
[assembly: TypeForwardedTo(typeof(InvalidTimeZoneException))]
[assembly: TypeForwardedTo(typeof(BinaryReader))]
[assembly: TypeForwardedTo(typeof(BinaryWriter))]
[assembly: TypeForwardedTo(typeof(BufferedStream))]
[assembly: TypeForwardedTo(typeof(CompressionLevel))]
[assembly: TypeForwardedTo(typeof(CompressionMode))]
[assembly: TypeForwardedTo(typeof(DeflateStream))]
[assembly: TypeForwardedTo(typeof(GZipStream))]
[assembly: TypeForwardedTo(typeof(ZipArchive))]
[assembly: TypeForwardedTo(typeof(ZipArchiveEntry))]
[assembly: TypeForwardedTo(typeof(ZipArchiveMode))]
[assembly: TypeForwardedTo(typeof(ZipFile))]
[assembly: TypeForwardedTo(typeof(ZipFileExtensions))]
[assembly: TypeForwardedTo(typeof(Directory))]
[assembly: TypeForwardedTo(typeof(DirectoryInfo))]
[assembly: TypeForwardedTo(typeof(DirectoryNotFoundException))]
[assembly: TypeForwardedTo(typeof(DriveInfo))]
[assembly: TypeForwardedTo(typeof(DriveNotFoundException))]
[assembly: TypeForwardedTo(typeof(DriveType))]
[assembly: TypeForwardedTo(typeof(EndOfStreamException))]
[assembly: TypeForwardedTo(typeof(ErrorEventArgs))]
[assembly: TypeForwardedTo(typeof(ErrorEventHandler))]
[assembly: TypeForwardedTo(typeof(File))]
[assembly: TypeForwardedTo(typeof(FileAccess))]
[assembly: TypeForwardedTo(typeof(FileAttributes))]
[assembly: TypeForwardedTo(typeof(FileInfo))]
[assembly: TypeForwardedTo(typeof(FileLoadException))]
[assembly: TypeForwardedTo(typeof(FileMode))]
[assembly: TypeForwardedTo(typeof(FileNotFoundException))]
[assembly: TypeForwardedTo(typeof(FileOptions))]
[assembly: TypeForwardedTo(typeof(FileShare))]
[assembly: TypeForwardedTo(typeof(FileStream))]
[assembly: TypeForwardedTo(typeof(FileSystemEventArgs))]
[assembly: TypeForwardedTo(typeof(FileSystemEventHandler))]
[assembly: TypeForwardedTo(typeof(FileSystemInfo))]
[assembly: TypeForwardedTo(typeof(FileSystemWatcher))]
[assembly: TypeForwardedTo(typeof(HandleInheritability))]
[assembly: TypeForwardedTo(typeof(InternalBufferOverflowException))]
[assembly: TypeForwardedTo(typeof(InvalidDataException))]
[assembly: TypeForwardedTo(typeof(IOException))]
[assembly: TypeForwardedTo(typeof(INormalizeForIsolatedStorage))]
[assembly: TypeForwardedTo(typeof(IsolatedStorage))]
[assembly: TypeForwardedTo(typeof(IsolatedStorageException))]
[assembly: TypeForwardedTo(typeof(IsolatedStorageFile))]
[assembly: TypeForwardedTo(typeof(IsolatedStorageFileStream))]
[assembly: TypeForwardedTo(typeof(IsolatedStorageScope))]
[assembly: TypeForwardedTo(typeof(MemoryMappedFile))]
[assembly: TypeForwardedTo(typeof(MemoryMappedFileAccess))]
[assembly: TypeForwardedTo(typeof(MemoryMappedFileOptions))]
[assembly: TypeForwardedTo(typeof(MemoryMappedFileRights))]
[assembly: TypeForwardedTo(typeof(MemoryMappedViewAccessor))]
[assembly: TypeForwardedTo(typeof(MemoryMappedViewStream))]
[assembly: TypeForwardedTo(typeof(MemoryStream))]
[assembly: TypeForwardedTo(typeof(NotifyFilters))]
[assembly: TypeForwardedTo(typeof(Path))]
[assembly: TypeForwardedTo(typeof(PathTooLongException))]
[assembly: TypeForwardedTo(typeof(AnonymousPipeClientStream))]
[assembly: TypeForwardedTo(typeof(AnonymousPipeServerStream))]
[assembly: TypeForwardedTo(typeof(NamedPipeClientStream))]
[assembly: TypeForwardedTo(typeof(NamedPipeServerStream))]
[assembly: TypeForwardedTo(typeof(PipeDirection))]
[assembly: TypeForwardedTo(typeof(PipeOptions))]
[assembly: TypeForwardedTo(typeof(PipeStream))]
[assembly: TypeForwardedTo(typeof(PipeStreamImpersonationWorker))]
[assembly: TypeForwardedTo(typeof(PipeTransmissionMode))]
[assembly: TypeForwardedTo(typeof(RenamedEventArgs))]
[assembly: TypeForwardedTo(typeof(RenamedEventHandler))]
[assembly: TypeForwardedTo(typeof(SearchOption))]
[assembly: TypeForwardedTo(typeof(SeekOrigin))]
[assembly: TypeForwardedTo(typeof(Stream))]
[assembly: TypeForwardedTo(typeof(StreamReader))]
[assembly: TypeForwardedTo(typeof(StreamWriter))]
[assembly: TypeForwardedTo(typeof(StringReader))]
[assembly: TypeForwardedTo(typeof(StringWriter))]
[assembly: TypeForwardedTo(typeof(TextReader))]
[assembly: TypeForwardedTo(typeof(TextWriter))]
[assembly: TypeForwardedTo(typeof(UnmanagedMemoryAccessor))]
[assembly: TypeForwardedTo(typeof(UnmanagedMemoryStream))]
[assembly: TypeForwardedTo(typeof(WaitForChangedResult))]
[assembly: TypeForwardedTo(typeof(WatcherChangeTypes))]
[assembly: TypeForwardedTo(typeof(IObservable<>))]
[assembly: TypeForwardedTo(typeof(IObserver<>))]
[assembly: TypeForwardedTo(typeof(IProgress<>))]
[assembly: TypeForwardedTo(typeof(IServiceProvider))]
[assembly: TypeForwardedTo(typeof(Lazy<>))]
[assembly: TypeForwardedTo(typeof(Lazy<, >))]
[assembly: TypeForwardedTo(typeof(LdapStyleUriParser))]
[assembly: TypeForwardedTo(typeof(Enumerable))]
[assembly: TypeForwardedTo(typeof(EnumerableExecutor))]
[assembly: TypeForwardedTo(typeof(EnumerableExecutor<>))]
[assembly: TypeForwardedTo(typeof(EnumerableQuery))]
[assembly: TypeForwardedTo(typeof(EnumerableQuery<>))]
[assembly: TypeForwardedTo(typeof(BinaryExpression))]
[assembly: TypeForwardedTo(typeof(BlockExpression))]
[assembly: TypeForwardedTo(typeof(CatchBlock))]
[assembly: TypeForwardedTo(typeof(ConditionalExpression))]
[assembly: TypeForwardedTo(typeof(ConstantExpression))]
[assembly: TypeForwardedTo(typeof(DebugInfoExpression))]
[assembly: TypeForwardedTo(typeof(DefaultExpression))]
[assembly: TypeForwardedTo(typeof(DynamicExpression))]
[assembly: TypeForwardedTo(typeof(DynamicExpressionVisitor))]
[assembly: TypeForwardedTo(typeof(ElementInit))]
[assembly: TypeForwardedTo(typeof(Expression))]
[assembly: TypeForwardedTo(typeof(ExpressionType))]
[assembly: TypeForwardedTo(typeof(ExpressionVisitor))]
[assembly: TypeForwardedTo(typeof(Expression<>))]
[assembly: TypeForwardedTo(typeof(GotoExpression))]
[assembly: TypeForwardedTo(typeof(GotoExpressionKind))]
[assembly: TypeForwardedTo(typeof(IArgumentProvider))]
[assembly: TypeForwardedTo(typeof(IDynamicExpression))]
[assembly: TypeForwardedTo(typeof(IndexExpression))]
[assembly: TypeForwardedTo(typeof(InvocationExpression))]
[assembly: TypeForwardedTo(typeof(LabelExpression))]
[assembly: TypeForwardedTo(typeof(LabelTarget))]
[assembly: TypeForwardedTo(typeof(LambdaExpression))]
[assembly: TypeForwardedTo(typeof(ListInitExpression))]
[assembly: TypeForwardedTo(typeof(LoopExpression))]
[assembly: TypeForwardedTo(typeof(MemberAssignment))]
[assembly: TypeForwardedTo(typeof(MemberBinding))]
[assembly: TypeForwardedTo(typeof(MemberBindingType))]
[assembly: TypeForwardedTo(typeof(MemberExpression))]
[assembly: TypeForwardedTo(typeof(MemberInitExpression))]
[assembly: TypeForwardedTo(typeof(MemberListBinding))]
[assembly: TypeForwardedTo(typeof(MemberMemberBinding))]
[assembly: TypeForwardedTo(typeof(MethodCallExpression))]
[assembly: TypeForwardedTo(typeof(NewArrayExpression))]
[assembly: TypeForwardedTo(typeof(NewExpression))]
[assembly: TypeForwardedTo(typeof(ParameterExpression))]
[assembly: TypeForwardedTo(typeof(RuntimeVariablesExpression))]
[assembly: TypeForwardedTo(typeof(SwitchCase))]
[assembly: TypeForwardedTo(typeof(SwitchExpression))]
[assembly: TypeForwardedTo(typeof(SymbolDocumentInfo))]
[assembly: TypeForwardedTo(typeof(TryExpression))]
[assembly: TypeForwardedTo(typeof(TypeBinaryExpression))]
[assembly: TypeForwardedTo(typeof(UnaryExpression))]
[assembly: TypeForwardedTo(typeof(IGrouping<, >))]
[assembly: TypeForwardedTo(typeof(ILookup<, >))]
[assembly: TypeForwardedTo(typeof(IOrderedEnumerable<>))]
[assembly: TypeForwardedTo(typeof(IOrderedQueryable))]
[assembly: TypeForwardedTo(typeof(IOrderedQueryable<>))]
[assembly: TypeForwardedTo(typeof(IQueryable))]
[assembly: TypeForwardedTo(typeof(IQueryable<>))]
[assembly: TypeForwardedTo(typeof(IQueryProvider))]
[assembly: TypeForwardedTo(typeof(Lookup<, >))]
[assembly: TypeForwardedTo(typeof(OrderedParallelQuery<>))]
[assembly: TypeForwardedTo(typeof(ParallelEnumerable))]
[assembly: TypeForwardedTo(typeof(ParallelExecutionMode))]
[assembly: TypeForwardedTo(typeof(ParallelMergeOptions))]
[assembly: TypeForwardedTo(typeof(ParallelQuery))]
[assembly: TypeForwardedTo(typeof(ParallelQuery<>))]
[assembly: TypeForwardedTo(typeof(Queryable))]
[assembly: TypeForwardedTo(typeof(LoaderOptimization))]
[assembly: TypeForwardedTo(typeof(LoaderOptimizationAttribute))]
[assembly: TypeForwardedTo(typeof(LocalDataStoreSlot))]
[assembly: TypeForwardedTo(typeof(MarshalByRefObject))]
[assembly: TypeForwardedTo(typeof(Math))]
[assembly: TypeForwardedTo(typeof(MemberAccessException))]
[assembly: TypeForwardedTo(typeof(MethodAccessException))]
[assembly: TypeForwardedTo(typeof(MidpointRounding))]
[assembly: TypeForwardedTo(typeof(MissingFieldException))]
[assembly: TypeForwardedTo(typeof(MissingMemberException))]
[assembly: TypeForwardedTo(typeof(MissingMethodException))]
[assembly: TypeForwardedTo(typeof(ModuleHandle))]
[assembly: TypeForwardedTo(typeof(MTAThreadAttribute))]
[assembly: TypeForwardedTo(typeof(MulticastDelegate))]
[assembly: TypeForwardedTo(typeof(MulticastNotSupportedException))]
[assembly: TypeForwardedTo(typeof(AuthenticationManager))]
[assembly: TypeForwardedTo(typeof(AuthenticationSchemes))]
[assembly: TypeForwardedTo(typeof(AuthenticationSchemeSelector))]
[assembly: TypeForwardedTo(typeof(Authorization))]
[assembly: TypeForwardedTo(typeof(BindIPEndPoint))]
[assembly: TypeForwardedTo(typeof(HttpCacheAgeControl))]
[assembly: TypeForwardedTo(typeof(HttpRequestCacheLevel))]
[assembly: TypeForwardedTo(typeof(HttpRequestCachePolicy))]
[assembly: TypeForwardedTo(typeof(RequestCacheLevel))]
[assembly: TypeForwardedTo(typeof(RequestCachePolicy))]
[assembly: TypeForwardedTo(typeof(Cookie))]
[assembly: TypeForwardedTo(typeof(CookieCollection))]
[assembly: TypeForwardedTo(typeof(CookieContainer))]
[assembly: TypeForwardedTo(typeof(CookieException))]
[assembly: TypeForwardedTo(typeof(CredentialCache))]
[assembly: TypeForwardedTo(typeof(DecompressionMethods))]
[assembly: TypeForwardedTo(typeof(Dns))]
[assembly: TypeForwardedTo(typeof(DnsEndPoint))]
[assembly: TypeForwardedTo(typeof(DownloadDataCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(DownloadDataCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(DownloadProgressChangedEventArgs))]
[assembly: TypeForwardedTo(typeof(DownloadProgressChangedEventHandler))]
[assembly: TypeForwardedTo(typeof(DownloadStringCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(DownloadStringCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(EndPoint))]
[assembly: TypeForwardedTo(typeof(FileWebRequest))]
[assembly: TypeForwardedTo(typeof(FileWebResponse))]
[assembly: TypeForwardedTo(typeof(FtpStatusCode))]
[assembly: TypeForwardedTo(typeof(FtpWebRequest))]
[assembly: TypeForwardedTo(typeof(FtpWebResponse))]
[assembly: TypeForwardedTo(typeof(GlobalProxySelection))]
[assembly: TypeForwardedTo(typeof(ByteArrayContent))]
[assembly: TypeForwardedTo(typeof(ClientCertificateOption))]
[assembly: TypeForwardedTo(typeof(DelegatingHandler))]
[assembly: TypeForwardedTo(typeof(FormUrlEncodedContent))]
[assembly: TypeForwardedTo(typeof(AuthenticationHeaderValue))]
[assembly: TypeForwardedTo(typeof(CacheControlHeaderValue))]
[assembly: TypeForwardedTo(typeof(ContentDispositionHeaderValue))]
[assembly: TypeForwardedTo(typeof(ContentRangeHeaderValue))]
[assembly: TypeForwardedTo(typeof(EntityTagHeaderValue))]
[assembly: TypeForwardedTo(typeof(HttpContentHeaders))]
[assembly: TypeForwardedTo(typeof(HttpHeaders))]
[assembly: TypeForwardedTo(typeof(HttpHeaderValueCollection<>))]
[assembly: TypeForwardedTo(typeof(HttpRequestHeaders))]
[assembly: TypeForwardedTo(typeof(HttpResponseHeaders))]
[assembly: TypeForwardedTo(typeof(MediaTypeHeaderValue))]
[assembly: TypeForwardedTo(typeof(MediaTypeWithQualityHeaderValue))]
[assembly: TypeForwardedTo(typeof(NameValueHeaderValue))]
[assembly: TypeForwardedTo(typeof(NameValueWithParametersHeaderValue))]
[assembly: TypeForwardedTo(typeof(ProductHeaderValue))]
[assembly: TypeForwardedTo(typeof(ProductInfoHeaderValue))]
[assembly: TypeForwardedTo(typeof(RangeConditionHeaderValue))]
[assembly: TypeForwardedTo(typeof(RangeHeaderValue))]
[assembly: TypeForwardedTo(typeof(RangeItemHeaderValue))]
[assembly: TypeForwardedTo(typeof(RetryConditionHeaderValue))]
[assembly: TypeForwardedTo(typeof(StringWithQualityHeaderValue))]
[assembly: TypeForwardedTo(typeof(TransferCodingHeaderValue))]
[assembly: TypeForwardedTo(typeof(TransferCodingWithQualityHeaderValue))]
[assembly: TypeForwardedTo(typeof(ViaHeaderValue))]
[assembly: TypeForwardedTo(typeof(WarningHeaderValue))]
[assembly: TypeForwardedTo(typeof(HttpClient))]
[assembly: TypeForwardedTo(typeof(HttpClientHandler))]
[assembly: TypeForwardedTo(typeof(HttpCompletionOption))]
[assembly: TypeForwardedTo(typeof(HttpContent))]
[assembly: TypeForwardedTo(typeof(HttpMessageHandler))]
[assembly: TypeForwardedTo(typeof(HttpMessageInvoker))]
[assembly: TypeForwardedTo(typeof(HttpMethod))]
[assembly: TypeForwardedTo(typeof(HttpRequestException))]
[assembly: TypeForwardedTo(typeof(HttpRequestMessage))]
[assembly: TypeForwardedTo(typeof(HttpResponseMessage))]
[assembly: TypeForwardedTo(typeof(MessageProcessingHandler))]
[assembly: TypeForwardedTo(typeof(MultipartContent))]
[assembly: TypeForwardedTo(typeof(MultipartFormDataContent))]
[assembly: TypeForwardedTo(typeof(StreamContent))]
[assembly: TypeForwardedTo(typeof(StringContent))]
[assembly: TypeForwardedTo(typeof(HttpContinueDelegate))]
[assembly: TypeForwardedTo(typeof(HttpListener))]
[assembly: TypeForwardedTo(typeof(HttpListenerBasicIdentity))]
[assembly: TypeForwardedTo(typeof(HttpListenerContext))]
[assembly: TypeForwardedTo(typeof(HttpListenerException))]
[assembly: TypeForwardedTo(typeof(HttpListenerPrefixCollection))]
[assembly: TypeForwardedTo(typeof(HttpListenerRequest))]
[assembly: TypeForwardedTo(typeof(HttpListenerResponse))]
[assembly: TypeForwardedTo(typeof(HttpListenerTimeoutManager))]
[assembly: TypeForwardedTo(typeof(HttpRequestHeader))]
[assembly: TypeForwardedTo(typeof(HttpResponseHeader))]
[assembly: TypeForwardedTo(typeof(HttpStatusCode))]
[assembly: TypeForwardedTo(typeof(HttpVersion))]
[assembly: TypeForwardedTo(typeof(HttpWebRequest))]
[assembly: TypeForwardedTo(typeof(HttpWebResponse))]
[assembly: TypeForwardedTo(typeof(IAuthenticationModule))]
[assembly: TypeForwardedTo(typeof(ICredentialPolicy))]
[assembly: TypeForwardedTo(typeof(ICredentials))]
[assembly: TypeForwardedTo(typeof(ICredentialsByHost))]
[assembly: TypeForwardedTo(typeof(IPAddress))]
[assembly: TypeForwardedTo(typeof(IPEndPoint))]
[assembly: TypeForwardedTo(typeof(IPHostEntry))]
[assembly: TypeForwardedTo(typeof(IWebProxy))]
[assembly: TypeForwardedTo(typeof(IWebProxyScript))]
[assembly: TypeForwardedTo(typeof(IWebRequestCreate))]
[assembly: TypeForwardedTo(typeof(AlternateView))]
[assembly: TypeForwardedTo(typeof(AlternateViewCollection))]
[assembly: TypeForwardedTo(typeof(Attachment))]
[assembly: TypeForwardedTo(typeof(AttachmentBase))]
[assembly: TypeForwardedTo(typeof(AttachmentCollection))]
[assembly: TypeForwardedTo(typeof(DeliveryNotificationOptions))]
[assembly: TypeForwardedTo(typeof(LinkedResource))]
[assembly: TypeForwardedTo(typeof(LinkedResourceCollection))]
[assembly: TypeForwardedTo(typeof(MailAddress))]
[assembly: TypeForwardedTo(typeof(MailAddressCollection))]
[assembly: TypeForwardedTo(typeof(MailMessage))]
[assembly: TypeForwardedTo(typeof(MailPriority))]
[assembly: TypeForwardedTo(typeof(SendCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(SmtpClient))]
[assembly: TypeForwardedTo(typeof(SmtpDeliveryFormat))]
[assembly: TypeForwardedTo(typeof(SmtpDeliveryMethod))]
[assembly: TypeForwardedTo(typeof(SmtpException))]
[assembly: TypeForwardedTo(typeof(SmtpFailedRecipientException))]
[assembly: TypeForwardedTo(typeof(SmtpFailedRecipientsException))]
[assembly: TypeForwardedTo(typeof(SmtpStatusCode))]
[assembly: TypeForwardedTo(typeof(ContentDisposition))]
[assembly: TypeForwardedTo(typeof(ContentType))]
[assembly: TypeForwardedTo(typeof(DispositionTypeNames))]
[assembly: TypeForwardedTo(typeof(MediaTypeNames))]
[assembly: TypeForwardedTo(typeof(TransferEncoding))]
[assembly: TypeForwardedTo(typeof(NetworkCredential))]
[assembly: TypeForwardedTo(typeof(DuplicateAddressDetectionState))]
[assembly: TypeForwardedTo(typeof(GatewayIPAddressInformation))]
[assembly: TypeForwardedTo(typeof(GatewayIPAddressInformationCollection))]
[assembly: TypeForwardedTo(typeof(IcmpV4Statistics))]
[assembly: TypeForwardedTo(typeof(IcmpV6Statistics))]
[assembly: TypeForwardedTo(typeof(IPAddressCollection))]
[assembly: TypeForwardedTo(typeof(IPAddressInformation))]
[assembly: TypeForwardedTo(typeof(IPAddressInformationCollection))]
[assembly: TypeForwardedTo(typeof(IPGlobalProperties))]
[assembly: TypeForwardedTo(typeof(IPGlobalStatistics))]
[assembly: TypeForwardedTo(typeof(IPInterfaceProperties))]
[assembly: TypeForwardedTo(typeof(IPInterfaceStatistics))]
[assembly: TypeForwardedTo(typeof(IPStatus))]
[assembly: TypeForwardedTo(typeof(IPv4InterfaceProperties))]
[assembly: TypeForwardedTo(typeof(IPv4InterfaceStatistics))]
[assembly: TypeForwardedTo(typeof(IPv6InterfaceProperties))]
[assembly: TypeForwardedTo(typeof(MulticastIPAddressInformation))]
[assembly: TypeForwardedTo(typeof(MulticastIPAddressInformationCollection))]
[assembly: TypeForwardedTo(typeof(NetBiosNodeType))]
[assembly: TypeForwardedTo(typeof(NetworkAddressChangedEventHandler))]
[assembly: TypeForwardedTo(typeof(NetworkAvailabilityChangedEventHandler))]
[assembly: TypeForwardedTo(typeof(NetworkAvailabilityEventArgs))]
[assembly: TypeForwardedTo(typeof(NetworkChange))]
[assembly: TypeForwardedTo(typeof(NetworkInformationException))]
[assembly: TypeForwardedTo(typeof(NetworkInterface))]
[assembly: TypeForwardedTo(typeof(NetworkInterfaceComponent))]
[assembly: TypeForwardedTo(typeof(NetworkInterfaceType))]
[assembly: TypeForwardedTo(typeof(OperationalStatus))]
[assembly: TypeForwardedTo(typeof(PhysicalAddress))]
[assembly: TypeForwardedTo(typeof(Ping))]
[assembly: TypeForwardedTo(typeof(PingCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(PingCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(PingException))]
[assembly: TypeForwardedTo(typeof(PingOptions))]
[assembly: TypeForwardedTo(typeof(PingReply))]
[assembly: TypeForwardedTo(typeof(PrefixOrigin))]
[assembly: TypeForwardedTo(typeof(ScopeLevel))]
[assembly: TypeForwardedTo(typeof(SuffixOrigin))]
[assembly: TypeForwardedTo(typeof(TcpConnectionInformation))]
[assembly: TypeForwardedTo(typeof(TcpState))]
[assembly: TypeForwardedTo(typeof(TcpStatistics))]
[assembly: TypeForwardedTo(typeof(UdpStatistics))]
[assembly: TypeForwardedTo(typeof(UnicastIPAddressInformation))]
[assembly: TypeForwardedTo(typeof(UnicastIPAddressInformationCollection))]
[assembly: TypeForwardedTo(typeof(OpenReadCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(OpenReadCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(OpenWriteCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(OpenWriteCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(ProtocolViolationException))]
[assembly: TypeForwardedTo(typeof(AuthenticatedStream))]
[assembly: TypeForwardedTo(typeof(AuthenticationLevel))]
[assembly: TypeForwardedTo(typeof(EncryptionPolicy))]
[assembly: TypeForwardedTo(typeof(LocalCertificateSelectionCallback))]
[assembly: TypeForwardedTo(typeof(NegotiateStream))]
[assembly: TypeForwardedTo(typeof(ProtectionLevel))]
[assembly: TypeForwardedTo(typeof(RemoteCertificateValidationCallback))]
[assembly: TypeForwardedTo(typeof(SslPolicyErrors))]
[assembly: TypeForwardedTo(typeof(SslStream))]
[assembly: TypeForwardedTo(typeof(SecurityProtocolType))]
[assembly: TypeForwardedTo(typeof(ServicePoint))]
[assembly: TypeForwardedTo(typeof(ServicePointManager))]
[assembly: TypeForwardedTo(typeof(SocketAddress))]
[assembly: TypeForwardedTo(typeof(AddressFamily))]
[assembly: TypeForwardedTo(typeof(IOControlCode))]
[assembly: TypeForwardedTo(typeof(IPPacketInformation))]
[assembly: TypeForwardedTo(typeof(IPProtectionLevel))]
[assembly: TypeForwardedTo(typeof(IPv6MulticastOption))]
[assembly: TypeForwardedTo(typeof(LingerOption))]
[assembly: TypeForwardedTo(typeof(MulticastOption))]
[assembly: TypeForwardedTo(typeof(NetworkStream))]
[assembly: TypeForwardedTo(typeof(ProtocolFamily))]
[assembly: TypeForwardedTo(typeof(ProtocolType))]
[assembly: TypeForwardedTo(typeof(SelectMode))]
[assembly: TypeForwardedTo(typeof(SendPacketsElement))]
[assembly: TypeForwardedTo(typeof(Socket))]
[assembly: TypeForwardedTo(typeof(SocketAsyncEventArgs))]
[assembly: TypeForwardedTo(typeof(SocketAsyncOperation))]
[assembly: TypeForwardedTo(typeof(SocketError))]
[assembly: TypeForwardedTo(typeof(SocketException))]
[assembly: TypeForwardedTo(typeof(SocketFlags))]
[assembly: TypeForwardedTo(typeof(SocketInformation))]
[assembly: TypeForwardedTo(typeof(SocketInformationOptions))]
[assembly: TypeForwardedTo(typeof(SocketOptionLevel))]
[assembly: TypeForwardedTo(typeof(SocketOptionName))]
[assembly: TypeForwardedTo(typeof(SocketReceiveFromResult))]
[assembly: TypeForwardedTo(typeof(SocketReceiveMessageFromResult))]
[assembly: TypeForwardedTo(typeof(SocketShutdown))]
[assembly: TypeForwardedTo(typeof(SocketTaskExtensions))]
[assembly: TypeForwardedTo(typeof(SocketType))]
[assembly: TypeForwardedTo(typeof(TcpClient))]
[assembly: TypeForwardedTo(typeof(TcpListener))]
[assembly: TypeForwardedTo(typeof(TransmitFileOptions))]
[assembly: TypeForwardedTo(typeof(UdpClient))]
[assembly: TypeForwardedTo(typeof(UdpReceiveResult))]
[assembly: TypeForwardedTo(typeof(TransportContext))]
[assembly: TypeForwardedTo(typeof(UploadDataCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(UploadDataCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(UploadFileCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(UploadFileCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(UploadProgressChangedEventArgs))]
[assembly: TypeForwardedTo(typeof(UploadProgressChangedEventHandler))]
[assembly: TypeForwardedTo(typeof(UploadStringCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(UploadStringCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(UploadValuesCompletedEventArgs))]
[assembly: TypeForwardedTo(typeof(UploadValuesCompletedEventHandler))]
[assembly: TypeForwardedTo(typeof(WebClient))]
[assembly: TypeForwardedTo(typeof(WebException))]
[assembly: TypeForwardedTo(typeof(WebExceptionStatus))]
[assembly: TypeForwardedTo(typeof(WebHeaderCollection))]
[assembly: TypeForwardedTo(typeof(WebProxy))]
[assembly: TypeForwardedTo(typeof(WebRequest))]
[assembly: TypeForwardedTo(typeof(WebRequestMethods))]
[assembly: TypeForwardedTo(typeof(WebResponse))]
[assembly: TypeForwardedTo(typeof(ClientWebSocket))]
[assembly: TypeForwardedTo(typeof(ClientWebSocketOptions))]
[assembly: TypeForwardedTo(typeof(HttpListenerWebSocketContext))]
[assembly: TypeForwardedTo(typeof(WebSocket))]
[assembly: TypeForwardedTo(typeof(WebSocketCloseStatus))]
[assembly: TypeForwardedTo(typeof(WebSocketContext))]
[assembly: TypeForwardedTo(typeof(WebSocketError))]
[assembly: TypeForwardedTo(typeof(WebSocketException))]
[assembly: TypeForwardedTo(typeof(WebSocketMessageType))]
[assembly: TypeForwardedTo(typeof(WebSocketReceiveResult))]
[assembly: TypeForwardedTo(typeof(WebSocketState))]
[assembly: TypeForwardedTo(typeof(WebUtility))]
[assembly: TypeForwardedTo(typeof(NetPipeStyleUriParser))]
[assembly: TypeForwardedTo(typeof(NetTcpStyleUriParser))]
[assembly: TypeForwardedTo(typeof(NewsStyleUriParser))]
[assembly: TypeForwardedTo(typeof(NonSerializedAttribute))]
[assembly: TypeForwardedTo(typeof(NotFiniteNumberException))]
[assembly: TypeForwardedTo(typeof(NotImplementedException))]
[assembly: TypeForwardedTo(typeof(NotSupportedException))]
[assembly: TypeForwardedTo(typeof(Nullable))]
[assembly: TypeForwardedTo(typeof(Nullable<>))]
[assembly: TypeForwardedTo(typeof(NullReferenceException))]
[assembly: TypeForwardedTo(typeof(BigInteger))]
[assembly: TypeForwardedTo(typeof(Complex))]
[assembly: TypeForwardedTo(typeof(object))]
[assembly: TypeForwardedTo(typeof(ObjectDisposedException))]
[assembly: TypeForwardedTo(typeof(ObsoleteAttribute))]
[assembly: TypeForwardedTo(typeof(OperatingSystem))]
[assembly: TypeForwardedTo(typeof(OperationCanceledException))]
[assembly: TypeForwardedTo(typeof(OutOfMemoryException))]
[assembly: TypeForwardedTo(typeof(OverflowException))]
[assembly: TypeForwardedTo(typeof(ParamArrayAttribute))]
[assembly: TypeForwardedTo(typeof(PlatformID))]
[assembly: TypeForwardedTo(typeof(PlatformNotSupportedException))]
[assembly: TypeForwardedTo(typeof(Predicate<>))]
[assembly: TypeForwardedTo(typeof(Progress<>))]
[assembly: TypeForwardedTo(typeof(Random))]
[assembly: TypeForwardedTo(typeof(RankException))]
[assembly: TypeForwardedTo(typeof(AmbiguousMatchException))]
[assembly: TypeForwardedTo(typeof(Assembly))]
[assembly: TypeForwardedTo(typeof(AssemblyAlgorithmIdAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyCompanyAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyConfigurationAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyContentType))]
[assembly: TypeForwardedTo(typeof(AssemblyCopyrightAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyCultureAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyDefaultAliasAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyDelaySignAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyDescriptionAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyFileVersionAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyFlagsAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyInformationalVersionAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyKeyFileAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyKeyNameAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyMetadataAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyName))]
[assembly: TypeForwardedTo(typeof(AssemblyNameFlags))]
[assembly: TypeForwardedTo(typeof(AssemblyNameProxy))]
[assembly: TypeForwardedTo(typeof(AssemblyProductAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblySignatureKeyAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyTitleAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyTrademarkAttribute))]
[assembly: TypeForwardedTo(typeof(AssemblyVersionAttribute))]
[assembly: TypeForwardedTo(typeof(Binder))]
[assembly: TypeForwardedTo(typeof(BindingFlags))]
[assembly: TypeForwardedTo(typeof(CallingConventions))]
[assembly: TypeForwardedTo(typeof(ConstructorInfo))]
[assembly: TypeForwardedTo(typeof(CustomAttributeData))]
[assembly: TypeForwardedTo(typeof(CustomAttributeExtensions))]
[assembly: TypeForwardedTo(typeof(CustomAttributeFormatException))]
[assembly: TypeForwardedTo(typeof(CustomAttributeNamedArgument))]
[assembly: TypeForwardedTo(typeof(CustomAttributeTypedArgument))]
[assembly: TypeForwardedTo(typeof(DefaultMemberAttribute))]
[assembly: TypeForwardedTo(typeof(FlowControl))]
[assembly: TypeForwardedTo(typeof(OpCode))]
[assembly: TypeForwardedTo(typeof(OpCodes))]
[assembly: TypeForwardedTo(typeof(OpCodeType))]
[assembly: TypeForwardedTo(typeof(OperandType))]
[assembly: TypeForwardedTo(typeof(PackingSize))]
[assembly: TypeForwardedTo(typeof(StackBehaviour))]
[assembly: TypeForwardedTo(typeof(EventAttributes))]
[assembly: TypeForwardedTo(typeof(EventInfo))]
[assembly: TypeForwardedTo(typeof(ExceptionHandlingClause))]
[assembly: TypeForwardedTo(typeof(ExceptionHandlingClauseOptions))]
[assembly: TypeForwardedTo(typeof(FieldAttributes))]
[assembly: TypeForwardedTo(typeof(FieldInfo))]
[assembly: TypeForwardedTo(typeof(GenericParameterAttributes))]
[assembly: TypeForwardedTo(typeof(ICustomAttributeProvider))]
[assembly: TypeForwardedTo(typeof(ImageFileMachine))]
[assembly: TypeForwardedTo(typeof(InterfaceMapping))]
[assembly: TypeForwardedTo(typeof(IntrospectionExtensions))]
[assembly: TypeForwardedTo(typeof(InvalidFilterCriteriaException))]
[assembly: TypeForwardedTo(typeof(IReflect))]
[assembly: TypeForwardedTo(typeof(IReflectableType))]
[assembly: TypeForwardedTo(typeof(LocalVariableInfo))]
[assembly: TypeForwardedTo(typeof(ManifestResourceInfo))]
[assembly: TypeForwardedTo(typeof(MemberFilter))]
[assembly: TypeForwardedTo(typeof(MemberInfo))]
[assembly: TypeForwardedTo(typeof(MemberTypes))]
[assembly: TypeForwardedTo(typeof(MethodAttributes))]
[assembly: TypeForwardedTo(typeof(MethodBase))]
[assembly: TypeForwardedTo(typeof(MethodBody))]
[assembly: TypeForwardedTo(typeof(MethodImplAttributes))]
[assembly: TypeForwardedTo(typeof(MethodInfo))]
[assembly: TypeForwardedTo(typeof(Missing))]
[assembly: TypeForwardedTo(typeof(Module))]
[assembly: TypeForwardedTo(typeof(ModuleResolveEventHandler))]
[assembly: TypeForwardedTo(typeof(ObfuscateAssemblyAttribute))]
[assembly: TypeForwardedTo(typeof(ObfuscationAttribute))]
[assembly: TypeForwardedTo(typeof(ParameterAttributes))]
[assembly: TypeForwardedTo(typeof(ParameterInfo))]
[assembly: TypeForwardedTo(typeof(ParameterModifier))]
[assembly: TypeForwardedTo(typeof(Pointer))]
[assembly: TypeForwardedTo(typeof(PortableExecutableKinds))]
[assembly: TypeForwardedTo(typeof(ProcessorArchitecture))]
[assembly: TypeForwardedTo(typeof(PropertyAttributes))]
[assembly: TypeForwardedTo(typeof(PropertyInfo))]
[assembly: TypeForwardedTo(typeof(ReflectionContext))]
[assembly: TypeForwardedTo(typeof(ReflectionTypeLoadException))]
[assembly: TypeForwardedTo(typeof(ResourceAttributes))]
[assembly: TypeForwardedTo(typeof(ResourceLocation))]
[assembly: TypeForwardedTo(typeof(RuntimeReflectionExtensions))]
[assembly: TypeForwardedTo(typeof(StrongNameKeyPair))]
[assembly: TypeForwardedTo(typeof(TargetException))]
[assembly: TypeForwardedTo(typeof(TargetInvocationException))]
[assembly: TypeForwardedTo(typeof(TargetParameterCountException))]
[assembly: TypeForwardedTo(typeof(TypeAttributes))]
[assembly: TypeForwardedTo(typeof(TypeDelegator))]
[assembly: TypeForwardedTo(typeof(TypeFilter))]
[assembly: TypeForwardedTo(typeof(TypeInfo))]
[assembly: TypeForwardedTo(typeof(ResolveEventArgs))]
[assembly: TypeForwardedTo(typeof(ResolveEventHandler))]
[assembly: TypeForwardedTo(typeof(IResourceReader))]
[assembly: TypeForwardedTo(typeof(IResourceWriter))]
[assembly: TypeForwardedTo(typeof(MissingManifestResourceException))]
[assembly: TypeForwardedTo(typeof(MissingSatelliteAssemblyException))]
[assembly: TypeForwardedTo(typeof(NeutralResourcesLanguageAttribute))]
[assembly: TypeForwardedTo(typeof(ResourceManager))]
[assembly: TypeForwardedTo(typeof(ResourceReader))]
[assembly: TypeForwardedTo(typeof(ResourceSet))]
[assembly: TypeForwardedTo(typeof(ResourceWriter))]
[assembly: TypeForwardedTo(typeof(SatelliteContractVersionAttribute))]
[assembly: TypeForwardedTo(typeof(UltimateResourceFallbackLocation))]
[assembly: TypeForwardedTo(typeof(AssemblyTargetedPatchBandAttribute))]
[assembly: TypeForwardedTo(typeof(AccessedThroughPropertyAttribute))]
[assembly: TypeForwardedTo(typeof(AsyncStateMachineAttribute))]
[assembly: TypeForwardedTo(typeof(AsyncTaskMethodBuilder))]
[assembly: TypeForwardedTo(typeof(AsyncTaskMethodBuilder<>))]
[assembly: TypeForwardedTo(typeof(AsyncVoidMethodBuilder))]
[assembly: TypeForwardedTo(typeof(CallConvCdecl))]
[assembly: TypeForwardedTo(typeof(CallConvFastcall))]
[assembly: TypeForwardedTo(typeof(CallConvStdcall))]
[assembly: TypeForwardedTo(typeof(CallConvThiscall))]
[assembly: TypeForwardedTo(typeof(CallerFilePathAttribute))]
[assembly: TypeForwardedTo(typeof(CallerLineNumberAttribute))]
[assembly: TypeForwardedTo(typeof(CallerMemberNameAttribute))]
[assembly: TypeForwardedTo(typeof(CallSite))]
[assembly: TypeForwardedTo(typeof(CallSiteBinder))]
[assembly: TypeForwardedTo(typeof(CallSiteHelpers))]
[assembly: TypeForwardedTo(typeof(CallSite<>))]
[assembly: TypeForwardedTo(typeof(CompilationRelaxations))]
[assembly: TypeForwardedTo(typeof(CompilationRelaxationsAttribute))]
[assembly: TypeForwardedTo(typeof(CompilerGeneratedAttribute))]
[assembly: TypeForwardedTo(typeof(CompilerGlobalScopeAttribute))]
[assembly: TypeForwardedTo(typeof(CompilerMarshalOverride))]
[assembly: TypeForwardedTo(typeof(ConditionalWeakTable<, >))]
[assembly: TypeForwardedTo(typeof(ConfiguredTaskAwaitable))]
[assembly: TypeForwardedTo(typeof(ConfiguredTaskAwaitable<>))]
[assembly: TypeForwardedTo(typeof(ContractHelper))]
[assembly: TypeForwardedTo(typeof(CustomConstantAttribute))]
[assembly: TypeForwardedTo(typeof(DateTimeConstantAttribute))]
[assembly: TypeForwardedTo(typeof(DebugInfoGenerator))]
[assembly: TypeForwardedTo(typeof(DecimalConstantAttribute))]
[assembly: TypeForwardedTo(typeof(DefaultDependencyAttribute))]
[assembly: TypeForwardedTo(typeof(DependencyAttribute))]
[assembly: TypeForwardedTo(typeof(DisablePrivateReflectionAttribute))]
[assembly: TypeForwardedTo(typeof(DiscardableAttribute))]
[assembly: TypeForwardedTo(typeof(DynamicAttribute))]
[assembly: TypeForwardedTo(typeof(ExtensionAttribute))]
[assembly: TypeForwardedTo(typeof(FixedAddressValueTypeAttribute))]
[assembly: TypeForwardedTo(typeof(FixedBufferAttribute))]
[assembly: TypeForwardedTo(typeof(FormattableStringFactory))]
[assembly: TypeForwardedTo(typeof(HasCopySemanticsAttribute))]
[assembly: TypeForwardedTo(typeof(IAsyncStateMachine))]
[assembly: TypeForwardedTo(typeof(ICriticalNotifyCompletion))]
[assembly: TypeForwardedTo(typeof(IndexerNameAttribute))]
[assembly: TypeForwardedTo(typeof(INotifyCompletion))]
[assembly: TypeForwardedTo(typeof(InternalsVisibleToAttribute))]
[assembly: TypeForwardedTo(typeof(IRuntimeVariables))]
[assembly: TypeForwardedTo(typeof(IsBoxed))]
[assembly: TypeForwardedTo(typeof(IsByValue))]
[assembly: TypeForwardedTo(typeof(IsConst))]
[assembly: TypeForwardedTo(typeof(IsCopyConstructed))]
[assembly: TypeForwardedTo(typeof(IsExplicitlyDereferenced))]
[assembly: TypeForwardedTo(typeof(IsImplicitlyDereferenced))]
[assembly: TypeForwardedTo(typeof(IsJitIntrinsic))]
[assembly: TypeForwardedTo(typeof(IsLong))]
[assembly: TypeForwardedTo(typeof(IsPinned))]
[assembly: TypeForwardedTo(typeof(IsSignUnspecifiedByte))]
[assembly: TypeForwardedTo(typeof(IStrongBox))]
[assembly: TypeForwardedTo(typeof(IsUdtReturn))]
[assembly: TypeForwardedTo(typeof(IsVolatile))]
[assembly: TypeForwardedTo(typeof(IteratorStateMachineAttribute))]
[assembly: TypeForwardedTo(typeof(IUnknownConstantAttribute))]
[assembly: TypeForwardedTo(typeof(LoadHint))]
[assembly: TypeForwardedTo(typeof(MethodCodeType))]
[assembly: TypeForwardedTo(typeof(MethodImplAttribute))]
[assembly: TypeForwardedTo(typeof(MethodImplOptions))]
[assembly: TypeForwardedTo(typeof(NativeCppClassAttribute))]
[assembly: TypeForwardedTo(typeof(ReadOnlyCollectionBuilder<>))]
[assembly: TypeForwardedTo(typeof(ReferenceAssemblyAttribute))]
[assembly: TypeForwardedTo(typeof(RequiredAttributeAttribute))]
[assembly: TypeForwardedTo(typeof(RuleCache<>))]
[assembly: TypeForwardedTo(typeof(RuntimeCompatibilityAttribute))]
[assembly: TypeForwardedTo(typeof(RuntimeHelpers))]
[assembly: TypeForwardedTo(typeof(RuntimeWrappedException))]
[assembly: TypeForwardedTo(typeof(ScopelessEnumAttribute))]
[assembly: TypeForwardedTo(typeof(SpecialNameAttribute))]
[assembly: TypeForwardedTo(typeof(StateMachineAttribute))]
[assembly: TypeForwardedTo(typeof(StringFreezingAttribute))]
[assembly: TypeForwardedTo(typeof(StrongBox<>))]
[assembly: TypeForwardedTo(typeof(SuppressIldasmAttribute))]
[assembly: TypeForwardedTo(typeof(TaskAwaiter))]
[assembly: TypeForwardedTo(typeof(TaskAwaiter<>))]
[assembly: TypeForwardedTo(typeof(TupleElementNamesAttribute))]
[assembly: TypeForwardedTo(typeof(TypeForwardedFromAttribute))]
[assembly: TypeForwardedTo(typeof(TypeForwardedToAttribute))]
[assembly: TypeForwardedTo(typeof(UnsafeValueTypeAttribute))]
[assembly: TypeForwardedTo(typeof(YieldAwaitable))]
[assembly: TypeForwardedTo(typeof(Cer))]
[assembly: TypeForwardedTo(typeof(Consistency))]
[assembly: TypeForwardedTo(typeof(CriticalFinalizerObject))]
[assembly: TypeForwardedTo(typeof(PrePrepareMethodAttribute))]
[assembly: TypeForwardedTo(typeof(ReliabilityContractAttribute))]
[assembly: TypeForwardedTo(typeof(ExceptionDispatchInfo))]
[assembly: TypeForwardedTo(typeof(FirstChanceExceptionEventArgs))]
[assembly: TypeForwardedTo(typeof(HandleProcessCorruptedStateExceptionsAttribute))]
[assembly: TypeForwardedTo(typeof(GCLargeObjectHeapCompactionMode))]
[assembly: TypeForwardedTo(typeof(GCLatencyMode))]
[assembly: TypeForwardedTo(typeof(GCSettings))]
[assembly: TypeForwardedTo(typeof(AllowReversePInvokeCallsAttribute))]
[assembly: TypeForwardedTo(typeof(Architecture))]
[assembly: TypeForwardedTo(typeof(ArrayWithOffset))]
[assembly: TypeForwardedTo(typeof(BestFitMappingAttribute))]
[assembly: TypeForwardedTo(typeof(BStrWrapper))]
[assembly: TypeForwardedTo(typeof(CallingConvention))]
[assembly: TypeForwardedTo(typeof(CharSet))]
[assembly: TypeForwardedTo(typeof(ClassInterfaceAttribute))]
[assembly: TypeForwardedTo(typeof(ClassInterfaceType))]
[assembly: TypeForwardedTo(typeof(CoClassAttribute))]
[assembly: TypeForwardedTo(typeof(ComAliasNameAttribute))]
[assembly: TypeForwardedTo(typeof(ComAwareEventInfo))]
[assembly: TypeForwardedTo(typeof(ComCompatibleVersionAttribute))]
[assembly: TypeForwardedTo(typeof(ComConversionLossAttribute))]
[assembly: TypeForwardedTo(typeof(ComDefaultInterfaceAttribute))]
[assembly: TypeForwardedTo(typeof(ComEventInterfaceAttribute))]
[assembly: TypeForwardedTo(typeof(ComEventsHelper))]
[assembly: TypeForwardedTo(typeof(COMException))]
[assembly: TypeForwardedTo(typeof(ComImportAttribute))]
[assembly: TypeForwardedTo(typeof(ComInterfaceType))]
[assembly: TypeForwardedTo(typeof(ComMemberType))]
[assembly: TypeForwardedTo(typeof(ComRegisterFunctionAttribute))]
[assembly: TypeForwardedTo(typeof(ComSourceInterfacesAttribute))]
[assembly: TypeForwardedTo(typeof(ADVF))]
[assembly: TypeForwardedTo(typeof(BINDPTR))]
[assembly: TypeForwardedTo(typeof(BIND_OPTS))]
[assembly: TypeForwardedTo(typeof(CALLCONV))]
[assembly: TypeForwardedTo(typeof(CONNECTDATA))]
[assembly: TypeForwardedTo(typeof(DATADIR))]
[assembly: TypeForwardedTo(typeof(DESCKIND))]
[assembly: TypeForwardedTo(typeof(DISPPARAMS))]
[assembly: TypeForwardedTo(typeof(DVASPECT))]
[assembly: TypeForwardedTo(typeof(ELEMDESC))]
[assembly: TypeForwardedTo(typeof(EXCEPINFO))]
[assembly: TypeForwardedTo(typeof(FILETIME))]
[assembly: TypeForwardedTo(typeof(FORMATETC))]
[assembly: TypeForwardedTo(typeof(FUNCDESC))]
[assembly: TypeForwardedTo(typeof(FUNCFLAGS))]
[assembly: TypeForwardedTo(typeof(FUNCKIND))]
[assembly: TypeForwardedTo(typeof(IAdviseSink))]
[assembly: TypeForwardedTo(typeof(IBindCtx))]
[assembly: TypeForwardedTo(typeof(IConnectionPoint))]
[assembly: TypeForwardedTo(typeof(IConnectionPointContainer))]
[assembly: TypeForwardedTo(typeof(IDataObject))]
[assembly: TypeForwardedTo(typeof(IDLDESC))]
[assembly: TypeForwardedTo(typeof(IDLFLAG))]
[assembly: TypeForwardedTo(typeof(IEnumConnectionPoints))]
[assembly: TypeForwardedTo(typeof(IEnumConnections))]
[assembly: TypeForwardedTo(typeof(IEnumFORMATETC))]
[assembly: TypeForwardedTo(typeof(IEnumMoniker))]
[assembly: TypeForwardedTo(typeof(IEnumSTATDATA))]
[assembly: TypeForwardedTo(typeof(IEnumString))]
[assembly: TypeForwardedTo(typeof(IEnumVARIANT))]
[assembly: TypeForwardedTo(typeof(IMoniker))]
[assembly: TypeForwardedTo(typeof(IMPLTYPEFLAGS))]
[assembly: TypeForwardedTo(typeof(INVOKEKIND))]
[assembly: TypeForwardedTo(typeof(IPersistFile))]
[assembly: TypeForwardedTo(typeof(IRunningObjectTable))]
[assembly: TypeForwardedTo(typeof(IStream))]
[assembly: TypeForwardedTo(typeof(ITypeComp))]
[assembly: TypeForwardedTo(typeof(ITypeInfo))]
[assembly: TypeForwardedTo(typeof(ITypeInfo2))]
[assembly: TypeForwardedTo(typeof(ITypeLib))]
[assembly: TypeForwardedTo(typeof(ITypeLib2))]
[assembly: TypeForwardedTo(typeof(LIBFLAGS))]
[assembly: TypeForwardedTo(typeof(PARAMDESC))]
[assembly: TypeForwardedTo(typeof(PARAMFLAG))]
[assembly: TypeForwardedTo(typeof(STATDATA))]
[assembly: TypeForwardedTo(typeof(STATSTG))]
[assembly: TypeForwardedTo(typeof(STGMEDIUM))]
[assembly: TypeForwardedTo(typeof(SYSKIND))]
[assembly: TypeForwardedTo(typeof(TYMED))]
[assembly: TypeForwardedTo(typeof(TYPEATTR))]
[assembly: TypeForwardedTo(typeof(TYPEDESC))]
[assembly: TypeForwardedTo(typeof(TYPEFLAGS))]
[assembly: TypeForwardedTo(typeof(TYPEKIND))]
[assembly: TypeForwardedTo(typeof(TYPELIBATTR))]
[assembly: TypeForwardedTo(typeof(VARDESC))]
[assembly: TypeForwardedTo(typeof(VARFLAGS))]
[assembly: TypeForwardedTo(typeof(VARKIND))]
[assembly: TypeForwardedTo(typeof(ComUnregisterFunctionAttribute))]
[assembly: TypeForwardedTo(typeof(ComVisibleAttribute))]
[assembly: TypeForwardedTo(typeof(CriticalHandle))]
[assembly: TypeForwardedTo(typeof(CurrencyWrapper))]
[assembly: TypeForwardedTo(typeof(CustomQueryInterfaceMode))]
[assembly: TypeForwardedTo(typeof(CustomQueryInterfaceResult))]
[assembly: TypeForwardedTo(typeof(DefaultCharSetAttribute))]
[assembly: TypeForwardedTo(typeof(DefaultDllImportSearchPathsAttribute))]
[assembly: TypeForwardedTo(typeof(DefaultParameterValueAttribute))]
[assembly: TypeForwardedTo(typeof(DispatchWrapper))]
[assembly: TypeForwardedTo(typeof(DispIdAttribute))]
[assembly: TypeForwardedTo(typeof(DllImportAttribute))]
[assembly: TypeForwardedTo(typeof(DllImportSearchPath))]
[assembly: TypeForwardedTo(typeof(ErrorWrapper))]
[assembly: TypeForwardedTo(typeof(ExternalException))]
[assembly: TypeForwardedTo(typeof(FieldOffsetAttribute))]
[assembly: TypeForwardedTo(typeof(GCHandle))]
[assembly: TypeForwardedTo(typeof(GCHandleType))]
[assembly: TypeForwardedTo(typeof(GuidAttribute))]
[assembly: TypeForwardedTo(typeof(HandleCollector))]
[assembly: TypeForwardedTo(typeof(HandleRef))]
[assembly: TypeForwardedTo(typeof(ICustomAdapter))]
[assembly: TypeForwardedTo(typeof(ICustomFactory))]
[assembly: TypeForwardedTo(typeof(ICustomMarshaler))]
[assembly: TypeForwardedTo(typeof(ICustomQueryInterface))]
[assembly: TypeForwardedTo(typeof(InAttribute))]
[assembly: TypeForwardedTo(typeof(InterfaceTypeAttribute))]
[assembly: TypeForwardedTo(typeof(InvalidComObjectException))]
[assembly: TypeForwardedTo(typeof(InvalidOleVariantTypeException))]
[assembly: TypeForwardedTo(typeof(LayoutKind))]
[assembly: TypeForwardedTo(typeof(LCIDConversionAttribute))]
[assembly: TypeForwardedTo(typeof(Marshal))]
[assembly: TypeForwardedTo(typeof(MarshalAsAttribute))]
[assembly: TypeForwardedTo(typeof(MarshalDirectiveException))]
[assembly: TypeForwardedTo(typeof(OptionalAttribute))]
[assembly: TypeForwardedTo(typeof(OSPlatform))]
[assembly: TypeForwardedTo(typeof(OutAttribute))]
[assembly: TypeForwardedTo(typeof(PreserveSigAttribute))]
[assembly: TypeForwardedTo(typeof(PrimaryInteropAssemblyAttribute))]
[assembly: TypeForwardedTo(typeof(ProgIdAttribute))]
[assembly: TypeForwardedTo(typeof(RuntimeEnvironment))]
[assembly: TypeForwardedTo(typeof(RuntimeInformation))]
[assembly: TypeForwardedTo(typeof(SafeArrayRankMismatchException))]
[assembly: TypeForwardedTo(typeof(SafeArrayTypeMismatchException))]
[assembly: TypeForwardedTo(typeof(SafeBuffer))]
[assembly: TypeForwardedTo(typeof(SafeHandle))]
[assembly: TypeForwardedTo(typeof(SEHException))]
[assembly: TypeForwardedTo(typeof(StructLayoutAttribute))]
[assembly: TypeForwardedTo(typeof(TypeIdentifierAttribute))]
[assembly: TypeForwardedTo(typeof(UnknownWrapper))]
[assembly: TypeForwardedTo(typeof(UnmanagedFunctionPointerAttribute))]
[assembly: TypeForwardedTo(typeof(UnmanagedType))]
[assembly: TypeForwardedTo(typeof(VarEnum))]
[assembly: TypeForwardedTo(typeof(VariantWrapper))]
[assembly: TypeForwardedTo(typeof(MemoryFailPoint))]
[assembly: TypeForwardedTo(typeof(CollectionDataContractAttribute))]
[assembly: TypeForwardedTo(typeof(ContractNamespaceAttribute))]
[assembly: TypeForwardedTo(typeof(DataContractAttribute))]
[assembly: TypeForwardedTo(typeof(DataContractResolver))]
[assembly: TypeForwardedTo(typeof(DataContractSerializer))]
[assembly: TypeForwardedTo(typeof(DataContractSerializerExtensions))]
[assembly: TypeForwardedTo(typeof(DataContractSerializerSettings))]
[assembly: TypeForwardedTo(typeof(DataMemberAttribute))]
[assembly: TypeForwardedTo(typeof(DateTimeFormat))]
[assembly: TypeForwardedTo(typeof(EmitTypeInformation))]
[assembly: TypeForwardedTo(typeof(EnumMemberAttribute))]
[assembly: TypeForwardedTo(typeof(ExportOptions))]
[assembly: TypeForwardedTo(typeof(ExtensionDataObject))]
[assembly: TypeForwardedTo(typeof(Formatter))]
[assembly: TypeForwardedTo(typeof(FormatterConverter))]
[assembly: TypeForwardedTo(typeof(BinaryFormatter))]
[assembly: TypeForwardedTo(typeof(FormatterAssemblyStyle))]
[assembly: TypeForwardedTo(typeof(FormatterTypeStyle))]
[assembly: TypeForwardedTo(typeof(TypeFilterLevel))]
[assembly: TypeForwardedTo(typeof(FormatterServices))]
[assembly: TypeForwardedTo(typeof(IDeserializationCallback))]
[assembly: TypeForwardedTo(typeof(IExtensibleDataObject))]
[assembly: TypeForwardedTo(typeof(IFormatter))]
[assembly: TypeForwardedTo(typeof(IFormatterConverter))]
[assembly: TypeForwardedTo(typeof(IgnoreDataMemberAttribute))]
[assembly: TypeForwardedTo(typeof(InvalidDataContractException))]
[assembly: TypeForwardedTo(typeof(IObjectReference))]
[assembly: TypeForwardedTo(typeof(ISafeSerializationData))]
[assembly: TypeForwardedTo(typeof(ISerializable))]
[assembly: TypeForwardedTo(typeof(ISerializationSurrogate))]
[assembly: TypeForwardedTo(typeof(ISerializationSurrogateProvider))]
[assembly: TypeForwardedTo(typeof(ISurrogateSelector))]
[assembly: TypeForwardedTo(typeof(DataContractJsonSerializer))]
[assembly: TypeForwardedTo(typeof(DataContractJsonSerializerSettings))]
[assembly: TypeForwardedTo(typeof(IXmlJsonReaderInitializer))]
[assembly: TypeForwardedTo(typeof(IXmlJsonWriterInitializer))]
[assembly: TypeForwardedTo(typeof(JsonReaderWriterFactory))]
[assembly: TypeForwardedTo(typeof(KnownTypeAttribute))]
[assembly: TypeForwardedTo(typeof(ObjectIDGenerator))]
[assembly: TypeForwardedTo(typeof(ObjectManager))]
[assembly: TypeForwardedTo(typeof(OnDeserializedAttribute))]
[assembly: TypeForwardedTo(typeof(OnDeserializingAttribute))]
[assembly: TypeForwardedTo(typeof(OnSerializedAttribute))]
[assembly: TypeForwardedTo(typeof(OnSerializingAttribute))]
[assembly: TypeForwardedTo(typeof(OptionalFieldAttribute))]
[assembly: TypeForwardedTo(typeof(SafeSerializationEventArgs))]
[assembly: TypeForwardedTo(typeof(SerializationBinder))]
[assembly: TypeForwardedTo(typeof(SerializationEntry))]
[assembly: TypeForwardedTo(typeof(SerializationException))]
[assembly: TypeForwardedTo(typeof(SerializationInfo))]
[assembly: TypeForwardedTo(typeof(SerializationInfoEnumerator))]
[assembly: TypeForwardedTo(typeof(SerializationObjectManager))]
[assembly: TypeForwardedTo(typeof(StreamingContext))]
[assembly: TypeForwardedTo(typeof(StreamingContextStates))]
[assembly: TypeForwardedTo(typeof(SurrogateSelector))]
[assembly: TypeForwardedTo(typeof(XmlObjectSerializer))]
[assembly: TypeForwardedTo(typeof(XmlSerializableServices))]
[assembly: TypeForwardedTo(typeof(XPathQueryGenerator))]
[assembly: TypeForwardedTo(typeof(XsdDataContractExporter))]
[assembly: TypeForwardedTo(typeof(TargetedPatchingOptOutAttribute))]
[assembly: TypeForwardedTo(typeof(ComponentGuaranteesAttribute))]
[assembly: TypeForwardedTo(typeof(ComponentGuaranteesOptions))]
[assembly: TypeForwardedTo(typeof(FrameworkName))]
[assembly: TypeForwardedTo(typeof(ResourceConsumptionAttribute))]
[assembly: TypeForwardedTo(typeof(ResourceExposureAttribute))]
[assembly: TypeForwardedTo(typeof(ResourceScope))]
[assembly: TypeForwardedTo(typeof(TargetFrameworkAttribute))]
[assembly: TypeForwardedTo(typeof(VersioningHelper))]
[assembly: TypeForwardedTo(typeof(RuntimeArgumentHandle))]
[assembly: TypeForwardedTo(typeof(RuntimeFieldHandle))]
[assembly: TypeForwardedTo(typeof(RuntimeMethodHandle))]
[assembly: TypeForwardedTo(typeof(RuntimeTypeHandle))]
[assembly: TypeForwardedTo(typeof(sbyte))]
[assembly: TypeForwardedTo(typeof(AllowPartiallyTrustedCallersAttribute))]
[assembly: TypeForwardedTo(typeof(AuthenticationException))]
[assembly: TypeForwardedTo(typeof(CipherAlgorithmType))]
[assembly: TypeForwardedTo(typeof(ExchangeAlgorithmType))]
[assembly: TypeForwardedTo(typeof(ChannelBinding))]
[assembly: TypeForwardedTo(typeof(ChannelBindingKind))]
[assembly: TypeForwardedTo(typeof(ExtendedProtectionPolicy))]
[assembly: TypeForwardedTo(typeof(ExtendedProtectionPolicyTypeConverter))]
[assembly: TypeForwardedTo(typeof(PolicyEnforcement))]
[assembly: TypeForwardedTo(typeof(ProtectionScenario))]
[assembly: TypeForwardedTo(typeof(ServiceNameCollection))]
[assembly: TypeForwardedTo(typeof(HashAlgorithmType))]
[assembly: TypeForwardedTo(typeof(InvalidCredentialException))]
[assembly: TypeForwardedTo(typeof(SslProtocols))]
[assembly: TypeForwardedTo(typeof(Claim))]
[assembly: TypeForwardedTo(typeof(ClaimsIdentity))]
[assembly: TypeForwardedTo(typeof(ClaimsPrincipal))]
[assembly: TypeForwardedTo(typeof(ClaimTypes))]
[assembly: TypeForwardedTo(typeof(ClaimValueTypes))]
[assembly: TypeForwardedTo(typeof(Aes))]
[assembly: TypeForwardedTo(typeof(AesCryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(AesManaged))]
[assembly: TypeForwardedTo(typeof(AsnEncodedData))]
[assembly: TypeForwardedTo(typeof(AsnEncodedDataCollection))]
[assembly: TypeForwardedTo(typeof(AsnEncodedDataEnumerator))]
[assembly: TypeForwardedTo(typeof(AsymmetricAlgorithm))]
[assembly: TypeForwardedTo(typeof(AsymmetricKeyExchangeDeformatter))]
[assembly: TypeForwardedTo(typeof(AsymmetricKeyExchangeFormatter))]
[assembly: TypeForwardedTo(typeof(AsymmetricSignatureDeformatter))]
[assembly: TypeForwardedTo(typeof(AsymmetricSignatureFormatter))]
[assembly: TypeForwardedTo(typeof(CipherMode))]
[assembly: TypeForwardedTo(typeof(CryptoConfig))]
[assembly: TypeForwardedTo(typeof(CryptographicException))]
[assembly: TypeForwardedTo(typeof(CryptographicUnexpectedOperationException))]
[assembly: TypeForwardedTo(typeof(CryptoStream))]
[assembly: TypeForwardedTo(typeof(CryptoStreamMode))]
[assembly: TypeForwardedTo(typeof(CspKeyContainerInfo))]
[assembly: TypeForwardedTo(typeof(CspParameters))]
[assembly: TypeForwardedTo(typeof(CspProviderFlags))]
[assembly: TypeForwardedTo(typeof(DeriveBytes))]
[assembly: TypeForwardedTo(typeof(DES))]
[assembly: TypeForwardedTo(typeof(DESCryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(DSA))]
[assembly: TypeForwardedTo(typeof(DSACryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(DSAParameters))]
[assembly: TypeForwardedTo(typeof(DSASignatureDeformatter))]
[assembly: TypeForwardedTo(typeof(DSASignatureFormatter))]
[assembly: TypeForwardedTo(typeof(ECCurve))]
[assembly: TypeForwardedTo(typeof(ECDiffieHellmanPublicKey))]
[assembly: TypeForwardedTo(typeof(ECDsa))]
[assembly: TypeForwardedTo(typeof(ECParameters))]
[assembly: TypeForwardedTo(typeof(ECPoint))]
[assembly: TypeForwardedTo(typeof(FromBase64Transform))]
[assembly: TypeForwardedTo(typeof(FromBase64TransformMode))]
[assembly: TypeForwardedTo(typeof(HashAlgorithm))]
[assembly: TypeForwardedTo(typeof(HashAlgorithmName))]
[assembly: TypeForwardedTo(typeof(HMAC))]
[assembly: TypeForwardedTo(typeof(HMACMD5))]
[assembly: TypeForwardedTo(typeof(HMACSHA1))]
[assembly: TypeForwardedTo(typeof(HMACSHA256))]
[assembly: TypeForwardedTo(typeof(HMACSHA384))]
[assembly: TypeForwardedTo(typeof(HMACSHA512))]
[assembly: TypeForwardedTo(typeof(ICryptoTransform))]
[assembly: TypeForwardedTo(typeof(ICspAsymmetricAlgorithm))]
[assembly: TypeForwardedTo(typeof(IncrementalHash))]
[assembly: TypeForwardedTo(typeof(KeyedHashAlgorithm))]
[assembly: TypeForwardedTo(typeof(KeyNumber))]
[assembly: TypeForwardedTo(typeof(KeySizes))]
[assembly: TypeForwardedTo(typeof(MaskGenerationMethod))]
[assembly: TypeForwardedTo(typeof(MD5))]
[assembly: TypeForwardedTo(typeof(MD5CryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(Oid))]
[assembly: TypeForwardedTo(typeof(OidCollection))]
[assembly: TypeForwardedTo(typeof(OidEnumerator))]
[assembly: TypeForwardedTo(typeof(OidGroup))]
[assembly: TypeForwardedTo(typeof(PaddingMode))]
[assembly: TypeForwardedTo(typeof(PasswordDeriveBytes))]
[assembly: TypeForwardedTo(typeof(PKCS1MaskGenerationMethod))]
[assembly: TypeForwardedTo(typeof(RandomNumberGenerator))]
[assembly: TypeForwardedTo(typeof(RC2))]
[assembly: TypeForwardedTo(typeof(RC2CryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(Rfc2898DeriveBytes))]
[assembly: TypeForwardedTo(typeof(Rijndael))]
[assembly: TypeForwardedTo(typeof(RijndaelManaged))]
[assembly: TypeForwardedTo(typeof(RNGCryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(RSA))]
[assembly: TypeForwardedTo(typeof(RSACryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(RSAEncryptionPadding))]
[assembly: TypeForwardedTo(typeof(RSAEncryptionPaddingMode))]
[assembly: TypeForwardedTo(typeof(RSAOAEPKeyExchangeDeformatter))]
[assembly: TypeForwardedTo(typeof(RSAOAEPKeyExchangeFormatter))]
[assembly: TypeForwardedTo(typeof(RSAParameters))]
[assembly: TypeForwardedTo(typeof(RSAPKCS1KeyExchangeDeformatter))]
[assembly: TypeForwardedTo(typeof(RSAPKCS1KeyExchangeFormatter))]
[assembly: TypeForwardedTo(typeof(RSAPKCS1SignatureDeformatter))]
[assembly: TypeForwardedTo(typeof(RSAPKCS1SignatureFormatter))]
[assembly: TypeForwardedTo(typeof(RSASignaturePadding))]
[assembly: TypeForwardedTo(typeof(RSASignaturePaddingMode))]
[assembly: TypeForwardedTo(typeof(SHA1))]
[assembly: TypeForwardedTo(typeof(SHA1CryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(SHA1Managed))]
[assembly: TypeForwardedTo(typeof(SHA256))]
[assembly: TypeForwardedTo(typeof(SHA256CryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(SHA256Managed))]
[assembly: TypeForwardedTo(typeof(SHA384))]
[assembly: TypeForwardedTo(typeof(SHA384CryptoServiceProvider))]
[assembly: TypeForwardedTo(typeof(SHA384Managed))]
[assembly: TypeForwardedTo(typeof(SHA512))]
[assembly: TypeForwar

Newtonsoft.Json.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Schema, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: CLSCompliant(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
[assembly: AssemblyFileVersion("13.0.3.27908")]
[assembly: AssemblyInformationalVersion("13.0.3+0a2e291c0d9c0c7675d445703e51750363a549ef")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyTitle("Json.NET .NET 4.5")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JamesNK/Newtonsoft.Json")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("13.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
}
namespace Newtonsoft.Json
{
	public enum ConstructorHandling
	{
		Default,
		AllowNonPublicDefaultConstructor
	}
	public enum DateFormatHandling
	{
		IsoDateFormat,
		MicrosoftDateFormat
	}
	public enum DateParseHandling
	{
		None,
		DateTime,
		DateTimeOffset
	}
	public enum DateTimeZoneHandling
	{
		Local,
		Utc,
		Unspecified,
		RoundtripKind
	}
	public class DefaultJsonNameTable : JsonNameTable
	{
		private class Entry
		{
			internal readonly string Value;

			internal readonly int HashCode;

			internal Entry Next;

			internal Entry(string value, int hashCode, Entry next)
			{
				Value = value;
				HashCode = hashCode;
				Next = next;
			}
		}

		private static readonly int HashCodeRandomizer;

		private int _count;

		private Entry[] _entries;

		private int _mask = 31;

		static DefaultJsonNameTable()
		{
			HashCodeRandomizer = Environment.TickCount;
		}

		public DefaultJsonNameTable()
		{
			_entries = new Entry[_mask + 1];
		}

		public override string? Get(char[] key, int start, int length)
		{
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			num += (num << 7) ^ key[start];
			int num2 = start + length;
			for (int i = start + 1; i < num2; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			int num3 = Volatile.Read(ref _mask);
			int num4 = num & num3;
			for (Entry entry = _entries[num4]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && TextEquals(entry.Value, key, start, length))
				{
					return entry.Value;
				}
			}
			return null;
		}

		public string Add(string key)
		{
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			int length = key.Length;
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			for (int i = 0; i < key.Length; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal))
				{
					return entry.Value;
				}
			}
			return AddEntry(key, num);
		}

		private string AddEntry(string str, int hashCode)
		{
			int num = hashCode & _mask;
			Entry entry = new Entry(str, hashCode, _entries[num]);
			_entries[num] = entry;
			if (_count++ == _mask)
			{
				Grow();
			}
			return entry.Value;
		}

		private void Grow()
		{
			Entry[] entries = _entries;
			int num = _mask * 2 + 1;
			Entry[] array = new Entry[num + 1];
			for (int i = 0; i < entries.Length; i++)
			{
				Entry entry = entries[i];
				while (entry != null)
				{
					int num2 = entry.HashCode & num;
					Entry next = entry.Next;
					entry.Next = array[num2];
					array[num2] = entry;
					entry = next;
				}
			}
			_entries = array;
			Volatile.Write(ref _mask, num);
		}

		private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length)
		{
			if (str1.Length != str2Length)
			{
				return false;
			}
			for (int i = 0; i < str1.Length; i++)
			{
				if (str1[i] != str2[str2Start + i])
				{
					return false;
				}
			}
			return true;
		}
	}
	[Flags]
	public enum DefaultValueHandling
	{
		Include = 0,
		Ignore = 1,
		Populate = 2,
		IgnoreAndPopulate = 3
	}
	public enum FloatFormatHandling
	{
		String,
		Symbol,
		DefaultValue
	}
	public enum FloatParseHandling
	{
		Double,
		Decimal
	}
	public enum Formatting
	{
		None,
		Indented
	}
	public interface IArrayPool<T>
	{
		T[] Rent(int minimumLength);

		void Return(T[]? array);
	}
	public interface IJsonLineInfo
	{
		int LineNumber { get; }

		int LinePosition { get; }

		bool HasLineInfo();
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonArrayAttribute : JsonContainerAttribute
	{
		private bool _allowNullItems;

		public bool AllowNullItems
		{
			get
			{
				return _allowNullItems;
			}
			set
			{
				_allowNullItems = value;
			}
		}

		public JsonArrayAttribute()
		{
		}

		public JsonArrayAttribute(bool allowNullItems)
		{
			_allowNullItems = allowNullItems;
		}

		public JsonArrayAttribute(string id)
			: base(id)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
	public sealed class JsonConstructorAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public abstract class JsonContainerAttribute : Attribute
	{
		internal bool? _isReference;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		private Type? _namingStrategyType;

		private object[]? _namingStrategyParameters;

		public string? Id { get; set; }

		public string? Title { get; set; }

		public string? Description { get; set; }

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType
		{
			get
			{
				return _namingStrategyType;
			}
			set
			{
				_namingStrategyType = value;
				NamingStrategyInstance = null;
			}
		}

		public object[]? NamingStrategyParameters
		{
			get
			{
				return _namingStrategyParameters;
			}
			set
			{
				_namingStrategyParameters = value;
				NamingStrategyInstance = null;
			}
		}

		internal NamingStrategy? NamingStrategyInstance { get; set; }

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		protected JsonContainerAttribute()
		{
		}

		protected JsonContainerAttribute(string id)
		{
			Id = id;
		}
	}
	public static class JsonConvert
	{
		public static readonly string True = "true";

		public static readonly string False = "false";

		public static readonly string Null = "null";

		public static readonly string Undefined = "undefined";

		public static readonly string PositiveInfinity = "Infinity";

		public static readonly string NegativeInfinity = "-Infinity";

		public static readonly string NaN = "NaN";

		public static Func<JsonSerializerSettings>? DefaultSettings { get; set; }

		public static string ToString(DateTime value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
		}

		public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
		{
			DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling);
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(DateTimeOffset value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat);
		}

		public static string ToString(DateTimeOffset value, DateFormatHandling format)
		{
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(bool value)
		{
			if (!value)
			{
				return False;
			}
			return True;
		}

		public static string ToString(char value)
		{
			return ToString(char.ToString(value));
		}

		public static string ToString(Enum value)
		{
			return value.ToString("D");
		}

		public static string ToString(int value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(short value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ushort value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(uint value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(long value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		private static string ToStringInternal(BigInteger value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ulong value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(float value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value)))
			{
				return text;
			}
			if (floatFormatHandling == FloatFormatHandling.DefaultValue)
			{
				if (nullable)
				{
					return Null;
				}
				return "0.0";
			}
			return quoteChar + text + quoteChar;
		}

		public static string ToString(double value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureDecimalPlace(double value, string text)
		{
			if (double.IsNaN(value) || double.IsInfinity(value) || StringUtils.IndexOf(text, '.') != -1 || StringUtils.IndexOf(text, 'E') != -1 || StringUtils.IndexOf(text, 'e') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		private static string EnsureDecimalPlace(string text)
		{
			if (StringUtils.IndexOf(text, '.') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		public static string ToString(byte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(sbyte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(decimal value)
		{
			return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
		}

		public static string ToString(Guid value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(Guid value, char quoteChar)
		{
			string text = value.ToString("D", CultureInfo.InvariantCulture);
			string text2 = quoteChar.ToString(CultureInfo.InvariantCulture);
			return text2 + text + text2;
		}

		public static string ToString(TimeSpan value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(TimeSpan value, char quoteChar)
		{
			return ToString(value.ToString(), quoteChar);
		}

		public static string ToString(Uri? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ToString(value, '"');
		}

		internal static string ToString(Uri value, char quoteChar)
		{
			return ToString(value.OriginalString, quoteChar);
		}

		public static string ToString(string? value)
		{
			return ToString(value, '"');
		}

		public static string ToString(string? value, char delimiter)
		{
			return ToString(value, delimiter, StringEscapeHandling.Default);
		}

		public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling)
		{
			if (delimiter != '"' && delimiter != '\'')
			{
				throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter");
			}
			return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling);
		}

		public static string ToString(object? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ConvertUtils.GetTypeCode(value.GetType()) switch
			{
				PrimitiveTypeCode.String => ToString((string)value), 
				PrimitiveTypeCode.Char => ToString((char)value), 
				PrimitiveTypeCode.Boolean => ToString((bool)value), 
				PrimitiveTypeCode.SByte => ToString((sbyte)value), 
				PrimitiveTypeCode.Int16 => ToString((short)value), 
				PrimitiveTypeCode.UInt16 => ToString((ushort)value), 
				PrimitiveTypeCode.Int32 => ToString((int)value), 
				PrimitiveTypeCode.Byte => ToString((byte)value), 
				PrimitiveTypeCode.UInt32 => ToString((uint)value), 
				PrimitiveTypeCode.Int64 => ToString((long)value), 
				PrimitiveTypeCode.UInt64 => ToString((ulong)value), 
				PrimitiveTypeCode.Single => ToString((float)value), 
				PrimitiveTypeCode.Double => ToString((double)value), 
				PrimitiveTypeCode.DateTime => ToString((DateTime)value), 
				PrimitiveTypeCode.Decimal => ToString((decimal)value), 
				PrimitiveTypeCode.DBNull => Null, 
				PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), 
				PrimitiveTypeCode.Guid => ToString((Guid)value), 
				PrimitiveTypeCode.Uri => ToString((Uri)value), 
				PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), 
				PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value), 
				_ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), 
			};
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value)
		{
			return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting)
		{
			return SerializeObject(value, formatting, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			jsonSerializer.Formatting = formatting;
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer)
		{
			StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture);
			using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))
			{
				jsonTextWriter.Formatting = jsonSerializer.Formatting;
				jsonSerializer.Serialize(jsonTextWriter, value, type);
			}
			return stringWriter.ToString();
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value)
		{
			return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, JsonSerializerSettings settings)
		{
			return DeserializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type)
		{
			return DeserializeObject(value, type, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value)
		{
			return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
		{
			return DeserializeObject<T>(value);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings)
		{
			return DeserializeObject<T>(value, settings);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, params JsonConverter[] converters)
		{
			return (T)DeserializeObject(value, typeof(T), converters);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings)
		{
			return (T)DeserializeObject(value, typeof(T), settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return DeserializeObject(value, type, settings);
		}

		public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings)
		{
			ValidationUtils.ArgumentNotNull(value, "value");
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			if (!jsonSerializer.IsCheckAdditionalContentSet())
			{
				jsonSerializer.CheckAdditionalContent = true;
			}
			using JsonTextReader reader = new JsonTextReader(new StringReader(value));
			return jsonSerializer.Deserialize(reader, type);
		}

		[DebuggerStepThrough]
		public static void PopulateObject(string value, object target)
		{
			PopulateObject(value, target, null);
		}

		public static void PopulateObject(string value, object target, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			using JsonReader jsonReader = new JsonTextReader(new StringReader(value));
			jsonSerializer.Populate(jsonReader, target);
			if (settings == null || !settings.CheckAdditionalContent)
			{
				return;
			}
			while (jsonReader.Read())
			{
				if (jsonReader.TokenType != JsonToken.Comment)
				{
					throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object.");
				}
			}
		}

		public static string SerializeXmlNode(XmlNode? node)
		{
			return SerializeXmlNode(node, Formatting.None);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XmlDocument? DeserializeXmlNode(string value)
		{
			return DeserializeXmlNode(value, null);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter);
		}

		public static string SerializeXNode(XObject? node)
		{
			return SerializeXNode(node, Formatting.None);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting)
		{
			return SerializeXNode(node, formatting, omitRootObject: false);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XDocument? DeserializeXNode(string value)
		{
			return DeserializeXNode(value, null);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter);
		}
	}
	public abstract class JsonConverter
	{
		public virtual bool CanRead => true;

		public virtual bool CanWrite => true;

		public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer);

		public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer);

		public abstract bool CanConvert(Type objectType);
	}
	public abstract class JsonConverter<T> : JsonConverter
	{
		public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T))))
			{
				throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			WriteJson(writer, (T)value, serializer);
		}

		public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer);

		public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			bool flag = existingValue == null;
			if (!flag && !(existingValue is T))
			{
				throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer);
		}

		public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer);

		public sealed override bool CanConvert(Type objectType)
		{
			return typeof(T).IsAssignableFrom(objectType);
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonConverterAttribute : Attribute
	{
		private readonly Type _converterType;

		public Type ConverterType => _converterType;

		public object[]? ConverterParameters { get; }

		public JsonConverterAttribute(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			_converterType = converterType;
		}

		public JsonConverterAttribute(Type converterType, params object[] converterParameters)
			: this(converterType)
		{
			ConverterParameters = converterParameters;
		}
	}
	public class JsonConverterCollection : Collection<JsonConverter>
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonDictionaryAttribute : JsonContainerAttribute
	{
		public JsonDictionaryAttribute()
		{
		}

		public JsonDictionaryAttribute(string id)
			: base(id)
		{
		}
	}
	[Serializable]
	public class JsonException : Exception
	{
		public JsonException()
		{
		}

		public JsonException(string message)
			: base(message)
		{
		}

		public JsonException(string message, Exception? innerException)
			: base(message, innerException)
		{
		}

		public JsonException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			return new JsonException(message);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public class JsonExtensionDataAttribute : Attribute
	{
		public bool WriteData { get; set; }

		public bool ReadData { get; set; }

		public JsonExtensionDataAttribute()
		{
			WriteData = true;
			ReadData = true;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonIgnoreAttribute : Attribute
	{
	}
	public abstract class JsonNameTable
	{
		public abstract string? Get(char[] key, int start, int length);
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonObjectAttribute : JsonContainerAttribute
	{
		private MemberSerialization _memberSerialization;

		internal MissingMemberHandling? _missingMemberHandling;

		internal Required? _itemRequired;

		internal NullValueHandling? _itemNullValueHandling;

		public MemberSerialization MemberSerialization
		{
			get
			{
				return _memberSerialization;
			}
			set
			{
				_memberSerialization = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public NullValueHandling ItemNullValueHandling
		{
			get
			{
				return _itemNullValueHandling.GetValueOrDefault();
			}
			set
			{
				_itemNullValueHandling = value;
			}
		}

		public Required ItemRequired
		{
			get
			{
				return _itemRequired.GetValueOrDefault();
			}
			set
			{
				_itemRequired = value;
			}
		}

		public JsonObjectAttribute()
		{
		}

		public JsonObjectAttribute(MemberSerialization memberSerialization)
		{
			MemberSerialization = memberSerialization;
		}

		public JsonObjectAttribute(string id)
			: base(id)
		{
		}
	}
	internal enum JsonContainerType
	{
		None,
		Object,
		Array,
		Constructor
	}
	internal struct JsonPosition
	{
		private static readonly char[] SpecialCharacters = new char[18]
		{
			'.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t',
			'\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029'
		};

		internal JsonContainerType Type;

		internal int Position;

		internal string? PropertyName;

		internal bool HasIndex;

		public JsonPosition(JsonContainerType type)
		{
			Type = type;
			HasIndex = TypeHasIndex(type);
			Position = -1;
			PropertyName = null;
		}

		internal int CalculateLength()
		{
			switch (Type)
			{
			case JsonContainerType.Object:
				return PropertyName.Length + 5;
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				return MathUtils.IntLength((ulong)Position) + 2;
			default:
				throw new ArgumentOutOfRangeException("Type");
			}
		}

		internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer)
		{
			switch (Type)
			{
			case JsonContainerType.Object:
			{
				string propertyName = PropertyName;
				if (propertyName.IndexOfAny(SpecialCharacters) != -1)
				{
					sb.Append("['");
					if (writer == null)
					{
						writer = new StringWriter(sb);
					}
					JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer);
					sb.Append("']");
				}
				else
				{
					if (sb.Length > 0)
					{
						sb.Append('.');
					}
					sb.Append(propertyName);
				}
				break;
			}
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				sb.Append('[');
				sb.Append(Position);
				sb.Append(']');
				break;
			}
		}

		internal static bool TypeHasIndex(JsonContainerType type)
		{
			if (type != JsonContainerType.Array)
			{
				return type == JsonContainerType.Constructor;
			}
			return true;
		}

		internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
		{
			int num = 0;
			if (positions != null)
			{
				for (int i = 0; i < positions.Count; i++)
				{
					num += positions[i].CalculateLength();
				}
			}
			if (currentPosition.HasValue)
			{
				num += currentPosition.GetValueOrDefault().CalculateLength();
			}
			StringBuilder stringBuilder = new StringBuilder(num);
			StringWriter writer = null;
			char[] buffer = null;
			if (positions != null)
			{
				foreach (JsonPosition position in positions)
				{
					position.WriteTo(stringBuilder, ref writer, ref buffer);
				}
			}
			currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer);
			return stringBuilder.ToString();
		}

		internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message)
		{
			if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
			{
				message = message.Trim();
				if (!StringUtils.EndsWith(message, '.'))
				{
					message += ".";
				}
				message += " ";
			}
			message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
			}
			message += ".";
			return message;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonPropertyAttribute : Attribute
	{
		internal NullValueHandling? _nullValueHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal bool? _isReference;

		internal int? _order;

		internal Required? _required;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType { get; set; }

		public object[]? NamingStrategyParameters { get; set; }

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling.GetValueOrDefault();
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public int Order
		{
			get
			{
				return _order.GetValueOrDefault();
			}
			set
			{
				_order = value;
			}
		}

		public Required Required
		{
			get
			{
				return _required.GetValueOrDefault();
			}
			set
			{
				_required = value;
			}
		}

		public string? PropertyName { get; set; }

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public JsonPropertyAttribute()
		{
		}

		public JsonPropertyAttribute(string propertyName)
		{
			PropertyName = propertyName;
		}
	}
	public abstract class JsonReader : IDisposable
	{
		protected internal enum State
		{
			Start,
			Complete,
			Property,
			ObjectStart,
			Object,
			ArrayStart,
			Array,
			Closed,
			PostValue,
			ConstructorStart,
			Constructor,
			Error,
			Finished
		}

		private JsonToken _tokenType;

		private object? _value;

		internal char _quoteChar;

		internal State _currentState;

		private JsonPosition _currentPosition;

		private CultureInfo? _culture;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private int? _maxDepth;

		private bool _hasExceededMaxDepth;

		internal DateParseHandling _dateParseHandling;

		internal FloatParseHandling _floatParseHandling;

		private string? _dateFormatString;

		private List<JsonPosition>? _stack;

		protected State CurrentState => _currentState;

		public bool CloseInput { get; set; }

		public bool SupportMultipleContent { get; set; }

		public virtual char QuoteChar
		{
			get
			{
				return _quoteChar;
			}
			protected internal set
			{
				_quoteChar = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling;
			}
			set
			{
				if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateTimeZoneHandling = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling;
			}
			set
			{
				if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateParseHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling;
			}
			set
			{
				if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_floatParseHandling = value;
			}
		}

		public string? DateFormatString
		{
			get
			{
				return _dateFormatString;
			}
			set
			{
				_dateFormatString = value;
			}
		}

		public int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
			}
		}

		public virtual JsonToken TokenType => _tokenType;

		public virtual object? Value => _value;

		public virtual Type? ValueType => _value?.GetType();

		public virtual int Depth
		{
			get
			{
				int num = _stack?.Count ?? 0;
				if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
				{
					return num;
				}
				return num + 1;
			}
		}

		public virtual string Path
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null);
				return JsonPosition.BuildPath(_stack, currentPosition);
			}
		}

		public CultureInfo Culture
		{
			get
			{
				return _culture ?? CultureInfo.InvariantCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync();
		}

		public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			if (TokenType == JsonToken.PropertyName)
			{
				await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false) && depth < Depth)
				{
				}
			}
		}

		internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken)
		{
			if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
			{
				throw CreateUnexpectedEndException();
			}
		}

		public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean());
		}

		public virtual Task<byte[]?> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes());
		}

		internal async Task<byte[]?> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
		{
			List<byte> buffer = new List<byte>();
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(buffer));
			byte[] array = buffer.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime());
		}

		public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset());
		}

		public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal());
		}

		public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return Task.FromResult(ReadAsDouble());
		}

		public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32());
		}

		public virtual Task<string?> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString());
		}

		internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken)
		{
			bool flag = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (flag)
			{
				flag = await MoveToContentAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			return flag;
		}

		internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType = TokenType;
			if (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				return MoveToContentFromNonContentAsync(cancellationToken);
			}
			return AsyncUtils.True;
		}

		private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType;
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					return false;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment);
			return true;
		}

		internal JsonPosition GetPosition(int depth)
		{
			if (_stack != null && depth < _stack.Count)
			{
				return _stack[depth];
			}
			return _currentPosition;
		}

		protected JsonReader()
		{
			_currentState = State.Start;
			_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
			_dateParseHandling = DateParseHandling.DateTime;
			_floatParseHandling = FloatParseHandling.Double;
			_maxDepth = 64;
			CloseInput = true;
		}

		private void Push(JsonContainerType value)
		{
			UpdateScopeWithFinishedValue();
			if (_currentPosition.Type == JsonContainerType.None)
			{
				_currentPosition = new JsonPosition(value);
				return;
			}
			if (_stack == null)
			{
				_stack = new List<JsonPosition>();
			}
			_stack.Add(_currentPosition);
			_currentPosition = new JsonPosition(value);
			if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth)
			{
				return;
			}
			_hasExceededMaxDepth = true;
			throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth));
		}

		private JsonContainerType Pop()
		{
			JsonPosition currentPosition;
			if (_stack != null && _stack.Count > 0)
			{
				currentPosition = _currentPosition;
				_currentPosition = _stack[_stack.Count - 1];
				_stack.RemoveAt(_stack.Count - 1);
			}
			else
			{
				currentPosition = _currentPosition;
				_currentPosition = default(JsonPosition);
			}
			if (_maxDepth.HasValue && Depth <= _maxDepth)
			{
				_hasExceededMaxDepth = false;
			}
			return currentPosition.Type;
		}

		private JsonContainerType Peek()
		{
			return _currentPosition.Type;
		}

		public abstract bool Read();

		public virtual int? ReadAsInt32()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is int)
				{
					return (int)value;
				}
				int num;
				if (value is BigInteger bigInteger)
				{
					num = (int)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToInt32(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Integer, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadInt32String(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal int? ReadInt32String(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (int.TryParse(s, NumberStyles.Integer, Culture, out var result))
			{
				SetToken(JsonToken.Integer, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual string? ReadAsString()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.String:
				return (string)Value;
			default:
				if (JsonTokenUtils.IsPrimitiveToken(contentToken))
				{
					object value = Value;
					if (value != null)
					{
						string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture));
						SetToken(JsonToken.String, text, updateIndex: false);
						return text;
					}
				}
				throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		public virtual byte[]? ReadAsBytes()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.StartObject:
			{
				ReadIntoWrappedTypeObject();
				byte[] array2 = ReadAsBytes();
				ReaderReadAndAssert();
				if (TokenType != JsonToken.EndObject)
				{
					throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
				}
				SetToken(JsonToken.Bytes, array2, updateIndex: false);
				return array2;
			}
			case JsonToken.String:
			{
				string text = (string)Value;
				Guid g;
				byte[] array3 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray()));
				SetToken(JsonToken.Bytes, array3, updateIndex: false);
				return array3;
			}
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Bytes:
				if (Value is Guid guid)
				{
					byte[] array = guid.ToByteArray();
					SetToken(JsonToken.Bytes, array, updateIndex: false);
					return array;
				}
				return (byte[])Value;
			case JsonToken.StartArray:
				return ReadArrayIntoByteArray();
			default:
				throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal byte[] ReadArrayIntoByteArray()
		{
			List<byte> list = new List<byte>();
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(list));
			byte[] array = list.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer)
		{
			switch (TokenType)
			{
			case JsonToken.None:
				throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
			case JsonToken.Integer:
				buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
				return false;
			case JsonToken.EndArray:
				return true;
			case JsonToken.Comment:
				return false;
			default:
				throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		public virtual double? ReadAsDouble()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is double)
				{
					return (double)value;
				}
				double num = ((!(value is BigInteger bigInteger)) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger));
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDoubleString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal double? ReadDoubleString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual bool? ReadAsBoolean()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				bool flag = ((!(Value is BigInteger bigInteger)) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L));
				SetToken(JsonToken.Boolean, flag, updateIndex: false);
				return flag;
			}
			case JsonToken.String:
				return ReadBooleanString((string)Value);
			case JsonToken.Boolean:
				return (bool)Value;
			default:
				throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal bool? ReadBooleanString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (bool.TryParse(s, out var result))
			{
				SetToken(JsonToken.Boolean, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual decimal? ReadAsDecimal()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is decimal)
				{
					return (decimal)value;
				}
				decimal num;
				if (value is BigInteger bigInteger)
				{
					num = (decimal)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToDecimal(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDecimalString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal decimal? ReadDecimalString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success)
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTime? ReadAsDateTime()
		{
			switch (GetContentToken())
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTimeOffset dateTimeOffset)
				{
					SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false);
				}
				return (DateTime)Value;
			case JsonToken.String:
				return ReadDateTimeString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		internal DateTime? ReadDateTimeString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTimeOffset? ReadAsDateTimeOffset()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTime dateTime)
				{
					SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false);
				}
				return (DateTimeOffset)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadDateTimeOffsetString(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal DateTimeOffset? ReadDateTimeOffsetString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		internal void ReaderReadAndAssert()
		{
			if (!Read())
			{
				throw CreateUnexpectedEndException();
			}
		}

		internal JsonReaderException CreateUnexpectedEndException()
		{
			return JsonReaderException.Create(this, "Unexpected end when reading JSON.");
		}

		internal void ReadIntoWrappedTypeObject()
		{
			ReaderReadAndAssert();
			if (Value != null && Value.ToString() == "$type")
			{
				ReaderReadAndAssert();
				if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
				{
					ReaderReadAndAssert();
					if (Value.ToString() == "$value")
					{
						return;
					}
				}
			}
			throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
		}

		public void Skip()
		{
			if (TokenType == JsonToken.PropertyName)
			{
				Read();
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (Read() && depth < Depth)
				{
				}
			}
		}

		protected void SetToken(JsonToken newToken)
		{
			SetToken(newToken, null, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value)
		{
			SetToken(newToken, value, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value, bool updateIndex)
		{
			_tokenType = newToken;
			_value = value;
			switch (newToken)
			{
			case JsonToken.StartObject:
				_currentState = State.ObjectStart;
				Push(JsonContainerType.Object);
				break;
			case JsonToken.StartArray:
				_currentState = State.ArrayStart;
				Push(JsonContainerType.Array);
				break;
			case JsonToken.StartConstructor:
				_currentState = State.ConstructorStart;
				Push(JsonContainerType.Constructor);
				break;
			case JsonToken.EndObject:
				ValidateEnd(JsonToken.EndObject);
				break;
			case JsonToken.EndArray:
				ValidateEnd(JsonToken.EndArray);
				break;
			case JsonToken.EndConstructor:
				ValidateEnd(JsonToken.EndConstructor);
				break;
			case JsonToken.PropertyName:
				_currentState = State.Property;
				_currentPosition.PropertyName = (string)value;
				break;
			case JsonToken.Raw:
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				SetPostValueState(updateIndex);
				break;
			case JsonToken.Comment:
				break;
			}
		}

		internal void SetPostValueState(bool updateIndex)
		{
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
			if (updateIndex)
			{
				UpdateScopeWithFinishedValue();
			}
		}

		private void UpdateScopeWithFinishedValue()
		{
			if (_currentPosition.HasIndex)
			{
				_currentPosition.Position++;
			}
		}

		private void ValidateEnd(JsonToken endToken)
		{
			JsonContainerType jsonContainerType = Pop();
			if (GetTypeForCloseToken(endToken) != jsonContainerType)
			{
				throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType));
			}
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
		}

		protected void SetStateBasedOnCurrent()
		{
			JsonContainerType jsonContainerType = Peek();
			switch (jsonContainerType)
			{
			case JsonContainerType.Object:
				_currentState = State.Object;
				break;
			case JsonContainerType.Array:
				_currentState = State.Array;
				break;
			case JsonContainerType.Constructor:
				_currentState = State.Constructor;
				break;
			case JsonContainerType.None:
				SetFinished();
				break;
			default:
				throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType));
			}
		}

		private void SetFinished()
		{
			_currentState = ((!SupportMultipleContent) ? State.Finished : State.Start);
		}

		private JsonContainerType GetTypeForCloseToken(JsonToken token)
		{
			return token switch
			{
				JsonToken.EndObject => JsonContainerType.Object, 
				JsonToken.EndArray => JsonContainerType.Array, 
				JsonToken.EndConstructor => JsonContainerType.Constructor, 
				_ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), 
			};
		}

		void IDisposable.Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_currentState != State.Closed && disposing)
			{
				Close();
			}
		}

		public virtual void Close()
		{
			_currentState = State.Closed;
			_tokenType = JsonToken.None;
			_value = null;
		}

		internal void ReadAndAssert()
		{
			if (!Read())
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter)
		{
			if (!ReadForType(contract, hasConverter))
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal bool ReadForType(JsonContract? contract, bool hasConverter)
		{
			if (hasConverter)
			{
				return Read();
			}
			switch (contract?.InternalReadType ?? ReadType.Read)
			{
			case ReadType.Read:
				return ReadAndMoveToContent();
			case ReadType.ReadAsInt32:
				ReadAsInt32();
				break;
			case ReadType.ReadAsInt64:
			{
				bool result = ReadAndMoveToContent();
				if (TokenType == JsonToken.Undefined)
				{
					throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long)));
				}
				return result;
			}
			case ReadType.ReadAsDecimal:
				ReadAsDecimal();
				break;
			case ReadType.ReadAsDouble:
				ReadAsDouble();
				break;
			case ReadType.ReadAsBytes:
				ReadAsBytes();
				break;
			case ReadType.ReadAsBoolean:
				ReadAsBoolean();
				break;
			case ReadType.ReadAsString:
				ReadAsString();
				break;
			case ReadType.ReadAsDateTime:
				ReadAsDateTime();
				break;
			case ReadType.ReadAsDateTimeOffset:
				ReadAsDateTimeOffset();
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
			return TokenType != JsonToken.None;
		}

		internal bool ReadAndMoveToContent()
		{
			if (Read())
			{
				return MoveToContent();
			}
			return false;
		}

		internal bool MoveToContent()
		{
			JsonToken tokenType = TokenType;
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				if (!Read())
				{
					return false;
				}
				tokenType = TokenType;
			}
			return true;
		}

		private JsonToken GetContentToken()
		{
			JsonToken tokenType;
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
					return JsonToken.None;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.Comment);
			return tokenType;
		}
	}
	[Serializable]
	public class JsonReaderException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonReaderException()
		{
		}

		public JsonReaderException(string message)
			: base(message)
		{
		}

		public JsonReaderException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonReaderException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonReaderException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonReaderException(message, path, lineNumber, linePosition, ex);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonRequiredAttribute : Attribute
	{
	}
	[Serializable]
	public class JsonSerializationException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonSerializationException()
		{
		}

		public JsonSerializationException(string message)
			: base(message)
		{
		}

		public JsonSerializationException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonSerializationException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonSerializationException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonSerializationException(message, path, lineNumber, linePosition, ex);
		}
	}
	public class JsonSerializer
	{
		internal TypeNameHandling _typeNameHandling;

		internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling;

		internal PreserveReferencesHandling _preserveReferencesHandling;

		internal ReferenceLoopHandling _referenceLoopHandling;

		internal MissingMemberHandling _missingMemberHandling;

		internal ObjectCreationHandling _objectCreationHandling;

		internal NullValueHandling _nullValueHandling;

		internal DefaultValueHandling _defaultValueHandling;

		internal ConstructorHandling _constructorHandling;

		internal MetadataPropertyHandling _metadataPropertyHandling;

		internal JsonConverterCollection? _converters;

		internal IContractResolver _contractResolver;

		internal ITraceWriter? _traceWriter;

		internal IEqualityComparer? _equalityComparer;

		internal ISerializationBinder _serializationBinder;

		internal StreamingContext _context;

		private IReferenceResolver? _referenceResolver;

		private Formatting? _formatting;

		private DateFormatHandling? _dateFormatHandling;

		private DateTimeZoneHandling? _dateTimeZoneHandling;

		private DateParseHandling? _dateParseHandling;

		private FloatFormatHandling? _floatFormatHandling;

		private FloatParseHandling? _floatParseHandling;

		private StringEscapeHandling? _stringEscapeHandling;

		private CultureInfo _culture;

		private int? _maxDepth;

		private bool _maxDepthSet;

		private bool? _checkAdditionalContent;

		private string? _dateFormatString;

		private bool _dateFormatStringSet;

		public virtual IReferenceResolver? ReferenceResolver
		{
			get
			{
				return GetReferenceResolver();
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Reference resolver cannot be null.");
				}
				_referenceResolver = value;
			}
		}

		[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
		public virtual SerializationBinder Binder
		{
			get
			{
				if (_serializationBinder is SerializationBinder result)
				{
					return result;
				}
				if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter)
				{
					return serializationBinderAdapter.SerializationBinder;
				}
				throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value);
			}
		}

		public virtual ISerializationBinder SerializationBinder
		{
			get
			{
				return _serializationBinder;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = value;
			}
		}

		public virtual ITraceWriter? TraceWriter
		{
			get
			{
				return _traceWriter;
			}
			set
			{
				_traceWriter = value;
			}
		}

		public virtual IEqualityComparer? EqualityComparer
		{
			get
			{
				return _equalityComparer;
			}
			set
			{
				_equalityComparer = value;
			}
		}

		public virtual TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling;
			}
			set
			{
				if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameHandling = value;
			}
		}

		[Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")]
		public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value;
			}
		}

		public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling
		{
			get
			{
				return _typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = value;
			}
		}

		public virtual PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling;
			}
			set
			{
				if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_preserveReferencesHandling = value;
			}
		}

		public virtual ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling;
			}
			set
			{
				if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_referenceLoopHandling = value;
			}
		}

		public virtual MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling;
			}
			set
			{
				if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_missingMemberHandling = value;
			}
		}

		public virtual NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling;
			}
			set
			{
				if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_nullValueHandling = value;
			}
		}

		public virtual DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling;
			}
			set
			{
				if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_defaultValueHandling = value;
			}
		}

		public virtual ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling;
			}
			set
			{
				if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_objectCreationHandling = value;
			}
		}

		public virtual ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling;
			}
			set
			{
				if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_constructorHandling = value;
			}
		}

		public virtual MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling;
			}
			set
			{
				if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_metadataPropertyHandling = value;
			}
		}

		public virtual JsonConverterCollection Converters
		{
			get
			{
				if (_converters == null)
				{
					_converters = new JsonConverterCollection();
				}
				return _converters;
			}
		}

		public virtual IContractResolver ContractResolver
		{
			get
			{
				return _contractResolver;
			}
			set
			{
				_contractResolver = value ?? DefaultContractResolver.Instance;
			}
		}

		public virtual StreamingContext Context
		{
			get
			{
				return _context;
			}
			set
			{
				_context = value;
			}
		}

		public virtual Formatting Formatting
		{
			get
			{
				return _formatting.GetValueOrDefault();
			}
			set
			{
				_formatting = value;
			}
		}

		public virtual DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling.GetValueOrDefault();
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

		public virtual DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind;
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public virtual DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling ?? DateParseHandling.DateTime;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public virtual FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling.GetValueOrDefault();
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public virtual FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling.GetValueOrDefault();
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public virtual StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling.GetValueOrDefault();
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

		public virtual string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

		public virtual CultureInfo Culture
		{
			get
			{
				return _culture ?? JsonSerializerSettings.DefaultCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
				_maxDepthSet = true;
			}
		}

		public virtual bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent.GetValueOrDefault();
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>? Error;

		internal bool IsCheckAdditionalContentSet()
		{
			return _checkAdditionalContent.HasValue;
		}

		public JsonSerializer()
		{
			_referenceLoopHandling = ReferenceLoopHandling.Error;
			_missingMemberHandling = MissingMemberHandling.Ignore;
			_nullValueHandling = NullValueHandling.Include;
			_defaultValueHandling = DefaultValueHandling.Include;
			_objectCreationHandling = ObjectCreationHandling.Auto;
			_preserveReferencesHandling = PreserveReferencesHandling.None;
			_constructorHandling = ConstructorHandling.Default;
			_typeNameHandling = TypeNameHandling.None;
			_metadataPropertyHandling = MetadataPropertyHandling.Default;
			_context = JsonSerializerSettings.DefaultContext;
			_serializationBinder = DefaultSerializationBinder.Instance;
			_culture = JsonSerializerSettings.DefaultCulture;
			_contractResolver = DefaultContractResolver.Instance;
		}

		public static JsonSerializer Create()
		{
			return new JsonSerializer();
		}

		public static JsonSerializer Create(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = Create();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		public static JsonSerializer CreateDefault()
		{
			return Create(JsonConvert.DefaultSettings?.Invoke());
		}

		public static JsonSerializer CreateDefault(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = CreateDefault();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings)
		{
			if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
			{
				for (int i = 0; i < settings.Converters.Count; i++)
				{
					serializer.Converters.Insert(i, settings.Converters[i]);
				}
			}
			if (settings._typeNameHandling.HasValue)
			{
				serializer.TypeNameHandling = settings.TypeNameHandling;
			}
			if (settings._metadataPropertyHandling.HasValue)
			{
				serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling;
			}
			if (settings._typeNameAssemblyFormatHandling.HasValue)
			{
				serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling;
			}
			if (settings._preserveReferencesHandling.HasValue)
			{
				serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
			}
			if (settings._referenceLoopHandling.HasValue)
			{
				serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
			}
			if (settings._missingMemberHandling.HasValue)
			{
				serializer.MissingMemberHandling = settings.MissingMemberHandling;
			}
			if (settings._objectCreationHandling.HasValue)
			{
				serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
			}
			if (settings._nullValueHandling.HasValue)
			{
				serializer.NullValueHandling = settings.NullValueHandling;
			}
			if (settings._defaultValueHandling.HasValue)
			{
				serializer.DefaultValueHandling = settings.DefaultValueHandling;
			}
			if (settings._constructorHandling.HasValue)
			{
				serializer.ConstructorHandling = settings.ConstructorHandling;
			}
			if (settings._context.HasValue)
			{
				serializer.Context = settings.Context;
			}
			if (settings._checkAdditionalContent.HasValue)
			{
				serializer._checkAdditionalContent = settings._checkAdditionalContent;
			}
			if (settings.Error != null)
			{
				serializer.Error += settings.Error;
			}
			if (settings.ContractResolver != null)
			{
				serializer.ContractResolver = settings.ContractResolver;
			}
			if (settings.ReferenceResolverProvider != null)
			{
				serializer.ReferenceResolver = settings.ReferenceResolverProvider();
			}
			if (settings.TraceWriter != null)
			{
				serializer.TraceWriter = settings.TraceWriter;
			}
			if (settings.EqualityComparer != null)
			{
				serializer.EqualityComparer = settings.EqualityComparer;
			}
			if (settings.SerializationBinder != null)
			{
				serializer.SerializationBinder = settings.SerializationBinder;
			}
			if (settings._formatting.HasValue)
			{
				serializer._formatting = settings._formatting;
			}
			if (settings._dateFormatHandling.HasValue)
			{
				serializer._dateFormatHandling = settings._dateFormatHandling;
			}
			if (settings._dateTimeZoneHandling.HasValue)
			{
				serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
			}
			if (settings._dateParseHandling.HasValue)
			{
				serializer._dateParseHandling = settings._dateParseHandling;
			}
			if (settings._dateFormatStringSet)
			{
				serializer._dateFormatString = settings._dateFormatString;
				serializer._dateFormatStringSet = settings._dateFormatStringSet;
			}
			if (settings._floatFormatHandling.HasValue)
			{
				serializer._floatFormatHandling = settings._floatFormatHandling;
			}
			if (settings._floatParseHandling.HasValue)
			{
				serializer._floatParseHandling = settings._floatParseHandling;
			}
			if (settings._stringEscapeHandling.HasValue)
			{
				serializer._stringEscapeHandling = settings._stringEscapeHandling;
			}
			if (settings._culture != null)
			{
				serializer._culture = settings._culture;
			}
			if (settings._maxDepthSet)
			{
				serializer._maxDepth = settings._maxDepth;
				serializer._maxDepthSet = settings._maxDepthSet;
			}
		}

		[DebuggerStepThrough]
		public void Populate(TextReader reader, object target)
		{
			Populate(new JsonTextReader(reader), target);
		}

		[DebuggerStepThrough]
		public void Populate(JsonReader reader, object target)
		{
			PopulateInternal(reader, target);
		}

		internal virtual void PopulateInternal(JsonReader reader, object target)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			ValidationUtils.ArgumentNotNull(target, "target");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader)
		{
			return Deserialize(reader, null);
		}

		[DebuggerStepThrough]
		public object? Deserialize(TextReader reader, Type objectType)
		{
			return Deserialize(new JsonTextReader(reader), objectType);
		}

		[DebuggerStepThrough]
		public T? Deserialize<T>(JsonReader reader)
		{
			return (T)Deserialize(reader, typeof(T));
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader, Type? objectType)
		{
			return DeserializeInternal(reader, objectType);
		}

		internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			object? result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
			return result;
		}

		internal void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString)
		{
			if (_culture != null && !_culture.Equals(reader.Culture))
			{
				previousCulture = reader.Culture;
				reader.Culture = _culture;
			}
			else
			{
				previousCulture = null;
			}
			if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
				reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			else
			{
				previousDateTimeZoneHandling = null;
			}
			if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling)
			{
				previousDateParseHandling = reader.DateParseHandling;
				reader.DateParseHandling = _dateParseHandling.GetValueOrDefault();
			}
			else
			{
				previousDateParseHandling = null;
			}
			if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling)
			{
				previousFloatParseHandling = reader.FloatParseHandling;
				reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault();
			}
			else
			{
				previousFloatParseHandling = null;
			}
			if (_maxDepthSet && reader.MaxDepth != _maxDepth)
			{
				previousMaxDepth = reader.MaxDepth;
				reader.MaxDepth = _maxDepth;
			}
			else
			{
				previousMaxDepth = null;
			}
			if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString)
			{
				previousDateFormatString = reader.DateFormatString;
				reader.DateFormatString = _dateFormatString;
			}
			else
			{
				previousDateFormatString = null;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable == null && _contractResolver is DefaultContractResolver defaultContractResolver)
			{
				jsonTextReader.PropertyNameTable = defaultContractResolver.GetNameTable();
			}
		}

		private void ResetReader(JsonReader reader, CultureInfo? previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string? previousDateFormatString)
		{
			if (previousCulture != null)
			{
				reader.Culture = previousCulture;
			}
			if (previousDateTimeZoneHandling.HasValue)
			{
				reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault();
			}
			if (previousDateParseHandling.HasValue)
			{
				reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault();
			}
			if (previousFloatParseHandling.HasValue)
			{
				reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault();
			}
			if (_maxDepthSet)
			{
				reader.MaxDepth = previousMaxDepth;
			}
			if (_dateFormatStringSet)
			{
				reader.DateFormatString = previousDateFormatString;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable != null && _contractResolver is DefaultContractResolver defaultContractResolver && jsonTextReader.PropertyNameTable == defaultContractResolver.GetNameTable())
			{
				jsonTextReader.PropertyNameTable = null;
			}
		}

		public void Serialize(TextWriter textWriter, object? value)
		{
			Serialize(new JsonTextWriter(textWriter), value);
		}

		public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			SerializeInternal(jsonWriter, value, objectType);
		}

		public void Serialize(TextWriter textWriter, object? value, Type objectType)
		{
			Serialize(new JsonTextWriter(textWriter), value, objectType);
		}

		public void Serialize(JsonWriter jsonWriter, object? value)
		{
			SerializeInternal(jsonWriter, value, null);
		}

		private TraceJsonReader CreateTraceJsonReader(JsonReader reader)
		{
			TraceJsonReader traceJsonReader = new TraceJsonReader(reader);
			if (reader.TokenType != 0)
			{
				traceJsonReader.WriteCurrentToken();
			}
			return traceJsonReader;
		}

		internal virtual void SerializeInternal(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
			Formatting? formatting = null;
			if (_formatting.HasValue && jsonWriter.Formatting != _formatting)
			{
				formatting = jsonWriter.Formatting;
				jsonWriter.Formatting = _formatting.GetValueOrDefault();
			}
			DateFormatHandling? dateFormatHandling = null;
			if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling)
			{
				dateFormatHandling = jsonWriter.DateFormatHandling;
				jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault();
			}
			DateTimeZoneHandling? dateTimeZoneHandling = null;
			if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling;
				jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			FloatFormatHandling? floatFormatHandling = null;
			if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling)
			{
				floatFormatHandling = jsonWriter.FloatFormatHandling;
				jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault();
			}
			StringEscapeHandling? stringEscapeHandling = null;
			if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling)
			{
				stringEscapeHandling = jsonWriter.StringEscapeHandling;
				jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault();
			}
			CultureInfo cultureInfo = null;
			if (_culture != null && !_culture.Equals(jsonWriter.Culture))
			{
				cultureInfo = jsonWriter.Culture;
				jsonWriter.Culture = _culture;
			}
			string dateFormatString = null;
			if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString)
			{
				dateFormatString = jsonWriter.DateFormatString;
				jsonWriter.DateFormatString = _dateFormatString;
			}
			TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null);
			new JsonSerializerInternalWriter(this).Serialize(traceJsonWriter ?? jsonWriter, value, objectType);
			if (traceJsonWriter != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null);
			}
			if (formatting.HasValue)
			{
				jsonWriter.Formatting = formatting.GetValueOrDefault();
			}
			if (dateFormatHandling.HasValue)
			{
				jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault();
			}
			if (dateTimeZoneHandling.HasValue)
			{
				jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault();
			}
			if (floatFormatHandling.HasValue)
			{
				jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault();
			}
			if (stringEscapeHandling.HasValue)
			{
				jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault();
			}
			if (_dateFormatStringSet)
			{
				jsonWriter.DateFormatString = dateFormatString;
			}
			if (cultureInfo != null)
			{
				jsonWriter.Culture = cultureInfo;
			}
		}

		internal IReferenceResolver GetReferenceResolver()
		{
			if (_referenceResolver == null)
			{
				_referenceResolver = new DefaultReferenceResolver();
			}
			return _referenceResolver;
		}

		internal JsonConverter? GetMatchingConverter(Type type)
		{
			return GetMatchingConverter(_converters, type);
		}

		internal static JsonConverter? GetMatchingConverter(IList<JsonConverter>? converters, Type objectType)
		{
			if (converters != null)
			{
				for (int i = 0; i < converters.Count; i++)
				{
					JsonConverter jsonConverter = converters[i];
					if (jsonConverter.CanConvert(objectType))
					{
						return jsonConverter;
					}
				}
			}
			return null;
		}

		internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e)
		{
			this.Error?.Invoke(this, e);
		}
	}
	public class JsonSerializerSettings
	{
		internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;

		internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;

		internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;

		internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;

		internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;

		internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;

		internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;

		internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;

		internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default;

		internal static readonly StreamingContext DefaultContext;

		internal const Formatting DefaultFormatting = Formatting.None;

		internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat;

		internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;

		internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime;

		internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double;

		internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String;

		internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default;

		internal const TypeNameAssemblyFormatHandling DefaultTypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple;

		internal static readonly CultureInfo DefaultCulture;

		internal const bool DefaultCheckAdditionalContent = false;

		internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

		internal const int DefaultMaxDepth = 64;

		internal Formatting? _formatting;

		internal DateFormatHandling? _dateFormatHandling;

		internal DateTimeZoneHandling? _dateTimeZoneHandling;

		internal DateParseHandling? _dateParseHandling;

		internal FloatFormatHandling? _floatFormatHandling;

		internal FloatParseHandling? _floatParseHandling;

		internal StringEscapeHandling? _stringEscapeHandling;

		internal CultureInfo? _culture;

		internal bool? _checkAdditionalContent;

		internal int? _maxDepth;

		internal bool _maxDepthSet;

		internal string? _dateFormatString;

		internal bool _dateFormatStringSet;

		internal TypeNameAssemblyFormatHandling? _typeNameAssemblyFormatHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal PreserveReferencesHandling? _preserveReferencesHandling;

		internal NullValueHandling? _nullValueHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal MissingMemberHandling? _missingMemberHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal StreamingContext? _context;

		internal ConstructorHandling? _constructorHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal MetadataPropertyHandling? _metadataPropertyHandling;

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public IList<JsonConverter> Converters { get; set; }

		public PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling.GetValueOrDef

RiptideNetworking.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using Microsoft.CodeAnalysis;
using Riptide.Transports;
using Riptide.Transports.Udp;
using Riptide.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Tom Weiland")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © Tom Weiland 2022")]
[assembly: AssemblyDescription("Riptide Networking is a lightweight C# networking library primarily designed for use in multiplayer games.")]
[assembly: AssemblyFileVersion("2.2.0.0")]
[assembly: AssemblyInformationalVersion("2.2.0")]
[assembly: AssemblyProduct("Riptide Networking")]
[assembly: AssemblyTitle("RiptideNetworking")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/RiptideNetworking/Riptide")]
[assembly: AssemblyVersion("2.2.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}
namespace Riptide
{
	public class Client : Peer
	{
		public delegate void MessageHandler(Message message);

		private Connection connection;

		private int connectionAttempts;

		private int maxConnectionAttempts;

		private Dictionary<ushort, MessageHandler> messageHandlers;

		private IClient transport;

		private Message connectMessage;

		public ushort Id => connection.Id;

		public short RTT => connection.RTT;

		public short SmoothRTT => connection.SmoothRTT;

		public override int TimeoutTime
		{
			set
			{
				defaultTimeout = value;
				connection.TimeoutTime = defaultTimeout;
			}
		}

		public bool IsNotConnected
		{
			get
			{
				if (connection != null)
				{
					return connection.IsNotConnected;
				}
				return true;
			}
		}

		public bool IsConnecting
		{
			get
			{
				if (connection != null)
				{
					return connection.IsConnecting;
				}
				return false;
			}
		}

		public bool IsPending
		{
			get
			{
				if (connection != null)
				{
					return connection.IsPending;
				}
				return false;
			}
		}

		public bool IsConnected
		{
			get
			{
				if (connection != null)
				{
					return connection.IsConnected;
				}
				return false;
			}
		}

		public Connection Connection => connection;

		public event EventHandler Connected;

		public event EventHandler<ConnectionFailedEventArgs> ConnectionFailed;

		public event EventHandler<MessageReceivedEventArgs> MessageReceived;

		public event EventHandler<DisconnectedEventArgs> Disconnected;

		public event EventHandler<ClientConnectedEventArgs> ClientConnected;

		public event EventHandler<ClientDisconnectedEventArgs> ClientDisconnected;

		public Client(IClient transport, string logName = "CLIENT")
			: base(logName)
		{
			this.transport = transport;
		}

		public Client(string logName = "CLIENT")
			: this(new Riptide.Transports.Udp.UdpClient(), logName)
		{
		}

		public void ChangeTransport(IClient newTransport)
		{
			Disconnect();
			transport = newTransport;
		}

		public bool Connect(string hostAddress, int maxConnectionAttempts = 5, byte messageHandlerGroupId = 0, Message message = null, bool useMessageHandlers = true)
		{
			Disconnect();
			SubToTransportEvents();
			if (!transport.Connect(hostAddress, out connection, out var connectError))
			{
				RiptideLogger.Log(LogType.Error, LogName, connectError);
				UnsubFromTransportEvents();
				return false;
			}
			this.maxConnectionAttempts = maxConnectionAttempts;
			connectionAttempts = 0;
			connection.Initialize(this, defaultTimeout);
			Peer.IncreaseActiveCount();
			base.useMessageHandlers = useMessageHandlers;
			if (useMessageHandlers)
			{
				CreateMessageHandlersDictionary(messageHandlerGroupId);
			}
			connectMessage = Message.Create(MessageHeader.Connect);
			if (message != null)
			{
				if (message.ReadBits != 0)
				{
					RiptideLogger.Log(LogType.Error, LogName, "Use the parameterless 'Message.Create()' overload when setting connection attempt data!");
				}
				connectMessage.AddMessage(message);
				message.Release();
			}
			StartTime();
			Heartbeat();
			RiptideLogger.Log(LogType.Info, LogName, $"Connecting to {connection}...");
			return true;
		}

		private void SubToTransportEvents()
		{
			transport.Connected += TransportConnected;
			transport.ConnectionFailed += TransportConnectionFailed;
			transport.DataReceived += base.HandleData;
			transport.Disconnected += TransportDisconnected;
		}

		private void UnsubFromTransportEvents()
		{
			transport.Connected -= TransportConnected;
			transport.ConnectionFailed -= TransportConnectionFailed;
			transport.DataReceived -= base.HandleData;
			transport.Disconnected -= TransportDisconnected;
		}

		protected override void CreateMessageHandlersDictionary(byte messageHandlerGroupId)
		{
			MethodInfo[] array = FindMessageHandlers();
			messageHandlers = new Dictionary<ushort, MessageHandler>(array.Length);
			MethodInfo[] array2 = array;
			foreach (MethodInfo methodInfo in array2)
			{
				MessageHandlerAttribute customAttribute = methodInfo.GetCustomAttribute<MessageHandlerAttribute>();
				if (customAttribute.GroupId != messageHandlerGroupId)
				{
					continue;
				}
				if (!methodInfo.IsStatic)
				{
					throw new NonStaticHandlerException(methodInfo.DeclaringType, methodInfo.Name);
				}
				Delegate @delegate = Delegate.CreateDelegate(typeof(MessageHandler), methodInfo, throwOnBindFailure: false);
				if ((object)@delegate != null)
				{
					if (messageHandlers.ContainsKey(customAttribute.MessageId))
					{
						MethodInfo methodInfo2 = messageHandlers[customAttribute.MessageId].GetMethodInfo();
						throw new DuplicateHandlerException(customAttribute.MessageId, methodInfo, methodInfo2);
					}
					messageHandlers.Add(customAttribute.MessageId, (MessageHandler)@delegate);
				}
				else if ((object)Delegate.CreateDelegate(typeof(Server.MessageHandler), methodInfo, throwOnBindFailure: false) == null)
				{
					throw new InvalidHandlerSignatureException(methodInfo.DeclaringType, methodInfo.Name);
				}
			}
		}

		internal override void Heartbeat()
		{
			if (IsConnecting)
			{
				if (connectionAttempts < maxConnectionAttempts)
				{
					Send(connectMessage, shouldRelease: false);
					connectionAttempts++;
				}
				else
				{
					LocalDisconnect(DisconnectReason.NeverConnected);
				}
			}
			else if (IsPending)
			{
				if (connection.HasConnectAttemptTimedOut)
				{
					LocalDisconnect(DisconnectReason.TimedOut);
					return;
				}
			}
			else if (IsConnected)
			{
				if (connection.HasTimedOut)
				{
					LocalDisconnect(DisconnectReason.TimedOut);
					return;
				}
				connection.SendHeartbeat();
			}
			ExecuteLater(base.HeartbeatInterval, new HeartbeatEvent(this));
		}

		public override void Update()
		{
			base.Update();
			transport.Poll();
			HandleMessages();
		}

		protected override void Handle(Message message, MessageHeader header, Connection connection)
		{
			switch (header)
			{
			case MessageHeader.Unreliable:
			case MessageHeader.Reliable:
				OnMessageReceived(message);
				break;
			case MessageHeader.Ack:
				connection.HandleAck(message);
				break;
			case MessageHeader.Connect:
				connection.SetPending();
				break;
			case MessageHeader.Reject:
				if (!IsConnected)
				{
					LocalDisconnect(DisconnectReason.ConnectionRejected, message, (RejectReason)message.GetByte());
				}
				break;
			case MessageHeader.Heartbeat:
				connection.HandleHeartbeatResponse(message);
				break;
			case MessageHeader.Disconnect:
				LocalDisconnect((DisconnectReason)message.GetByte(), message);
				break;
			case MessageHeader.Welcome:
				if (IsConnecting || IsPending)
				{
					connection.HandleWelcome(message);
					OnConnected();
				}
				break;
			case MessageHeader.ClientConnected:
				OnClientConnected(message.GetUShort());
				break;
			case MessageHeader.ClientDisconnected:
				OnClientDisconnected(message.GetUShort());
				break;
			default:
				RiptideLogger.Log(LogType.Warning, LogName, $"Unexpected message header '{header}'! Discarding {message.BytesInUse} bytes.");
				break;
			}
			message.Release();
		}

		public ushort Send(Message message, bool shouldRelease = true)
		{
			return connection.Send(message, shouldRelease);
		}

		public void Disconnect()
		{
			if (connection != null && !IsNotConnected)
			{
				Send(Message.Create(MessageHeader.Disconnect));
				LocalDisconnect(DisconnectReason.Disconnected);
			}
		}

		internal override void Disconnect(Connection connection, DisconnectReason reason)
		{
			if (connection.IsConnected && connection.CanQualityDisconnect)
			{
				LocalDisconnect(reason);
			}
		}

		private void LocalDisconnect(DisconnectReason reason, Message message = null, RejectReason rejectReason = RejectReason.NoConnection)
		{
			if (!IsNotConnected)
			{
				UnsubFromTransportEvents();
				Peer.DecreaseActiveCount();
				StopTime();
				transport.Disconnect();
				connection.LocalDisconnect();
				switch (reason)
				{
				case DisconnectReason.NeverConnected:
					OnConnectionFailed(RejectReason.NoConnection);
					break;
				case DisconnectReason.ConnectionRejected:
					OnConnectionFailed(rejectReason, message);
					break;
				default:
					OnDisconnected(reason, message);
					break;
				}
			}
		}

		private void TransportConnected(object sender, EventArgs e)
		{
		}

		private void TransportConnectionFailed(object sender, EventArgs e)
		{
			LocalDisconnect(DisconnectReason.NeverConnected);
		}

		private void TransportDisconnected(object sender, Riptide.Transports.DisconnectedEventArgs e)
		{
			if (connection == e.Connection)
			{
				LocalDisconnect(e.Reason);
			}
		}

		protected virtual void OnConnected()
		{
			connectMessage.Release();
			connectMessage = null;
			RiptideLogger.Log(LogType.Info, LogName, "Connected successfully!");
			this.Connected?.Invoke(this, EventArgs.Empty);
		}

		protected virtual void OnConnectionFailed(RejectReason reason, Message message = null)
		{
			connectMessage.Release();
			connectMessage = null;
			RiptideLogger.Log(LogType.Info, LogName, "Connection to server failed: " + Helper.GetReasonString(reason) + ".");
			this.ConnectionFailed?.Invoke(this, new ConnectionFailedEventArgs(reason, message));
		}

		protected virtual void OnMessageReceived(Message message)
		{
			ushort num = (ushort)message.GetVarULong();
			this.MessageReceived?.Invoke(this, new MessageReceivedEventArgs(connection, num, message));
			if (useMessageHandlers)
			{
				if (messageHandlers.TryGetValue(num, out var value))
				{
					value(message);
				}
				else
				{
					RiptideLogger.Log(LogType.Warning, LogName, $"No message handler method found for message ID {num}!");
				}
			}
		}

		protected virtual void OnDisconnected(DisconnectReason reason, Message message)
		{
			RiptideLogger.Log(LogType.Info, LogName, "Disconnected from server: " + Helper.GetReasonString(reason) + ".");
			this.Disconnected?.Invoke(this, new DisconnectedEventArgs(reason, message));
		}

		protected virtual void OnClientConnected(ushort clientId)
		{
			RiptideLogger.Log(LogType.Info, LogName, $"Client {clientId} connected.");
			this.ClientConnected?.Invoke(this, new ClientConnectedEventArgs(clientId));
		}

		protected virtual void OnClientDisconnected(ushort clientId)
		{
			RiptideLogger.Log(LogType.Info, LogName, $"Client {clientId} disconnected.");
			this.ClientDisconnected?.Invoke(this, new ClientDisconnectedEventArgs(clientId));
		}
	}
	internal enum ConnectionState : byte
	{
		NotConnected,
		Connecting,
		Pending,
		Connected
	}
	public abstract class Connection
	{
		private abstract class Sequencer
		{
			private ushort _nextSequenceId = 1;

			protected readonly Connection connection;

			protected ushort lastReceivedSeqId;

			protected readonly Bitfield receivedSeqIds = new Bitfield();

			protected ushort lastAckedSeqId;

			protected readonly Bitfield ackedSeqIds = new Bitfield(isDynamicCapacity: false);

			internal ushort NextSequenceId => _nextSequenceId++;

			protected Sequencer(Connection connection)
			{
				this.connection = connection;
			}

			internal abstract bool ShouldHandle(ushort sequenceId);

			internal abstract void UpdateReceivedAcks(ushort remoteLastReceivedSeqId, ushort remoteReceivedSeqIds);
		}

		private class NotifySequencer : Sequencer
		{
			internal NotifySequencer(Connection connection)
				: base(connection)
			{
			}

			internal ushort InsertHeader(Message message)
			{
				ushort nextSequenceId = base.NextSequenceId;
				ulong bitfield = lastReceivedSeqId | ((ulong)receivedSeqIds.First8 << 16) | ((ulong)nextSequenceId << 24);
				message.SetBits(bitfield, 40, 4);
				return nextSequenceId;
			}

			internal override bool ShouldHandle(ushort sequenceId)
			{
				int sequenceGap = Helper.GetSequenceGap(sequenceId, lastReceivedSeqId);
				if (sequenceGap > 0)
				{
					receivedSeqIds.ShiftBy(sequenceGap);
					lastReceivedSeqId = sequenceId;
					if (receivedSeqIds.IsSet(sequenceGap))
					{
						return false;
					}
					receivedSeqIds.Set(sequenceGap);
					return true;
				}
				return false;
			}

			internal override void UpdateReceivedAcks(ushort remoteLastReceivedSeqId, ushort remoteReceivedSeqIds)
			{
				int num = Helper.GetSequenceGap(remoteLastReceivedSeqId, lastAckedSeqId);
				if (num <= 0)
				{
					return;
				}
				if (num > 1)
				{
					while (num > 9)
					{
						lastAckedSeqId++;
						num--;
						connection.NotifyLost?.Invoke(lastAckedSeqId);
					}
					int num2 = num - 1;
					int num3 = 1 << num2;
					for (int i = 0; i < num2; i++)
					{
						lastAckedSeqId++;
						num3 >>= 1;
						if ((remoteReceivedSeqIds & num3) == 0)
						{
							connection.OnNotifyLost(lastAckedSeqId);
						}
						else
						{
							connection.OnNotifyDelivered(lastAckedSeqId);
						}
					}
				}
				lastAckedSeqId = remoteLastReceivedSeqId;
				connection.OnNotifyDelivered(lastAckedSeqId);
			}
		}

		private class ReliableSequencer : Sequencer
		{
			internal ReliableSequencer(Connection connection)
				: base(connection)
			{
			}

			internal override bool ShouldHandle(ushort sequenceId)
			{
				bool result = false;
				int num = Helper.GetSequenceGap(sequenceId, lastReceivedSeqId);
				if (num != 0)
				{
					if (num > 0)
					{
						if (num > 64)
						{
							RiptideLogger.Log(LogType.Warning, connection.Peer.LogName, $"The gap between received sequence IDs was very large ({num})!");
						}
						receivedSeqIds.ShiftBy(num);
						lastReceivedSeqId = sequenceId;
					}
					else
					{
						num = -num;
					}
					result = !receivedSeqIds.IsSet(num);
					receivedSeqIds.Set(num);
				}
				connection.SendAck(sequenceId, lastReceivedSeqId, receivedSeqIds);
				return result;
			}

			internal override void UpdateReceivedAcks(ushort remoteLastReceivedSeqId, ushort remoteReceivedSeqIds)
			{
				int sequenceGap = Helper.GetSequenceGap(remoteLastReceivedSeqId, lastAckedSeqId);
				if (sequenceGap > 0)
				{
					if (!ackedSeqIds.HasCapacityFor(sequenceGap, out var overflow))
					{
						for (int i = 0; i < overflow; i++)
						{
							if (!ackedSeqIds.CheckAndTrimLast(out var checkedPosition))
							{
								connection.ResendMessage((ushort)(lastAckedSeqId - checkedPosition));
							}
							else
							{
								connection.ClearMessage((ushort)(lastAckedSeqId - checkedPosition));
							}
						}
					}
					ackedSeqIds.ShiftBy(sequenceGap);
					lastAckedSeqId = remoteLastReceivedSeqId;
					for (int j = 0; j < 16; j++)
					{
						if (!ackedSeqIds.IsSet(j + 1) && (remoteReceivedSeqIds & (1 << j)) != 0)
						{
							connection.ClearMessage((ushort)(lastAckedSeqId - (j + 1)));
						}
					}
					ackedSeqIds.Combine(remoteReceivedSeqIds);
					ackedSeqIds.Set(sequenceGap);
					connection.ClearMessage(remoteLastReceivedSeqId);
				}
				else if (sequenceGap < 0)
				{
					ackedSeqIds.Set(-sequenceGap);
				}
				else
				{
					ackedSeqIds.Combine(remoteReceivedSeqIds);
				}
			}
		}

		public Action<ushort> NotifyDelivered;

		public Action<ushort> NotifyLost;

		public Action<Message> NotifyReceived;

		public Action<ushort> ReliableDelivered;

		private short _rtt;

		private bool _canTimeout;

		public bool CanQualityDisconnect;

		public readonly ConnectionMetrics Metrics;

		public int MaxAvgSendAttempts;

		public int AvgSendAttemptsResilience;

		public int MaxSendAttempts;

		public float MaxNotifyLoss;

		public int NotifyLossResilience;

		private readonly NotifySequencer notify;

		private readonly ReliableSequencer reliable;

		private readonly Dictionary<ushort, PendingMessage> pendingMessages;

		private ConnectionState state;

		private int sendAttemptsViolations;

		private int lossRateViolations;

		private long lastHeartbeat;

		private byte lastPingId;

		private byte pendingPingId;

		private long pendingPingSendTime;

		public ushort Id { get; internal set; }

		public bool IsNotConnected => state == ConnectionState.NotConnected;

		public bool IsConnecting => state == ConnectionState.Connecting;

		public bool IsPending => state == ConnectionState.Pending;

		public bool IsConnected => state == ConnectionState.Connected;

		public short RTT
		{
			get
			{
				return _rtt;
			}
			private set
			{
				SmoothRTT = ((_rtt == -1) ? value : ((short)Math.Max(1f, (float)SmoothRTT * 0.7f + (float)value * 0.3f)));
				_rtt = value;
			}
		}

		public short SmoothRTT { get; private set; }

		public int TimeoutTime { get; set; }

		public bool CanTimeout
		{
			get
			{
				return _canTimeout;
			}
			set
			{
				if (value)
				{
					ResetTimeout();
				}
				_canTimeout = value;
			}
		}

		internal Peer Peer { get; private set; }

		internal bool HasTimedOut
		{
			get
			{
				if (_canTimeout)
				{
					return Peer.CurrentTime - lastHeartbeat > TimeoutTime;
				}
				return false;
			}
		}

		internal bool HasConnectAttemptTimedOut
		{
			get
			{
				if (_canTimeout)
				{
					return Peer.CurrentTime - lastHeartbeat > Peer.ConnectTimeoutTime;
				}
				return false;
			}
		}

		protected Connection()
		{
			Metrics = new ConnectionMetrics();
			notify = new NotifySequencer(this);
			reliable = new ReliableSequencer(this);
			state = ConnectionState.Connecting;
			_rtt = -1;
			SmoothRTT = -1;
			_canTimeout = true;
			CanQualityDisconnect = true;
			MaxAvgSendAttempts = 5;
			AvgSendAttemptsResilience = 64;
			MaxSendAttempts = 15;
			MaxNotifyLoss = 0.05f;
			NotifyLossResilience = 64;
			pendingMessages = new Dictionary<ushort, PendingMessage>();
		}

		internal void Initialize(Peer peer, int timeoutTime)
		{
			Peer = peer;
			TimeoutTime = timeoutTime;
		}

		public void ResetTimeout()
		{
			lastHeartbeat = Peer.CurrentTime;
		}

		public ushort Send(Message message, bool shouldRelease = true)
		{
			ushort num = 0;
			if (message.SendMode == MessageSendMode.Notify)
			{
				num = notify.InsertHeader(message);
				int bytesInUse = message.BytesInUse;
				Buffer.BlockCopy(message.Data, 0, Message.ByteBuffer, 0, bytesInUse);
				Send(Message.ByteBuffer, bytesInUse);
				Metrics.SentNotify(bytesInUse);
			}
			else if (message.SendMode == MessageSendMode.Unreliable)
			{
				int bytesInUse2 = message.BytesInUse;
				Buffer.BlockCopy(message.Data, 0, Message.ByteBuffer, 0, bytesInUse2);
				Send(Message.ByteBuffer, bytesInUse2);
				Metrics.SentUnreliable(bytesInUse2);
			}
			else
			{
				num = reliable.NextSequenceId;
				PendingMessage pendingMessage = PendingMessage.Create(num, message, this);
				pendingMessages.Add(num, pendingMessage);
				pendingMessage.TrySend();
				Metrics.ReliableUniques++;
			}
			if (shouldRelease)
			{
				message.Release();
			}
			return num;
		}

		protected internal abstract void Send(byte[] dataBuffer, int amount);

		internal void ProcessNotify(byte[] dataBuffer, int amount, Message message)
		{
			notify.UpdateReceivedAcks(Converter.UShortFromBits(dataBuffer, 4), Converter.ByteFromBits(dataBuffer, 20));
			Metrics.ReceivedNotify(amount);
			if (notify.ShouldHandle(Converter.UShortFromBits(dataBuffer, 28)))
			{
				Buffer.BlockCopy(dataBuffer, 1, message.Data, 1, amount - 1);
				NotifyReceived?.Invoke(message);
			}
			else
			{
				Metrics.NotifyDiscarded++;
			}
		}

		internal bool ShouldHandle(ushort sequenceId)
		{
			return reliable.ShouldHandle(sequenceId);
		}

		internal void LocalDisconnect()
		{
			state = ConnectionState.NotConnected;
			foreach (PendingMessage value in pendingMessages.Values)
			{
				value.Clear();
			}
			pendingMessages.Clear();
		}

		private void ResendMessage(ushort sequenceId)
		{
			if (pendingMessages.TryGetValue(sequenceId, out var value))
			{
				value.RetrySend();
			}
		}

		internal void ClearMessage(ushort sequenceId)
		{
			if (pendingMessages.TryGetValue(sequenceId, out var value))
			{
				ReliableDelivered?.Invoke(sequenceId);
				value.Clear();
				pendingMessages.Remove(sequenceId);
				UpdateSendAttemptsViolations();
			}
		}

		internal void SetPending()
		{
			if (IsConnecting)
			{
				state = ConnectionState.Pending;
				ResetTimeout();
			}
		}

		private void UpdateSendAttemptsViolations()
		{
			if (Metrics.RollingReliableSends.Mean > (double)MaxAvgSendAttempts)
			{
				sendAttemptsViolations++;
				if (sendAttemptsViolations >= AvgSendAttemptsResilience)
				{
					Peer.Disconnect(this, DisconnectReason.PoorConnection);
				}
			}
			else
			{
				sendAttemptsViolations = 0;
			}
		}

		private void UpdateLossViolations()
		{
			if (Metrics.RollingNotifyLossRate > MaxNotifyLoss)
			{
				lossRateViolations++;
				if (lossRateViolations >= NotifyLossResilience)
				{
					Peer.Disconnect(this, DisconnectReason.PoorConnection);
				}
			}
			else
			{
				lossRateViolations = 0;
			}
		}

		private void SendAck(ushort forSeqId, ushort lastReceivedSeqId, Bitfield receivedSeqIds)
		{
			Message message = Message.Create(MessageHeader.Ack);
			message.AddUShort(lastReceivedSeqId);
			message.AddUShort(receivedSeqIds.First16);
			if (forSeqId == lastReceivedSeqId)
			{
				message.AddBool(value: false);
			}
			else
			{
				message.AddBool(value: true);
				message.AddUShort(forSeqId);
			}
			Send(message);
		}

		internal void HandleAck(Message message)
		{
			ushort uShort = message.GetUShort();
			ushort uShort2 = message.GetUShort();
			ushort sequenceId = (message.GetBool() ? message.GetUShort() : uShort);
			ClearMessage(sequenceId);
			reliable.UpdateReceivedAcks(uShort, uShort2);
		}

		internal void SendWelcome()
		{
			Message message = Message.Create(MessageHeader.Welcome);
			message.AddUShort(Id);
			Send(message);
		}

		internal bool HandleWelcomeResponse(Message message)
		{
			if (!IsPending)
			{
				return false;
			}
			ushort uShort = message.GetUShort();
			if (Id != uShort)
			{
				RiptideLogger.Log(LogType.Error, Peer.LogName, $"Client has assumed ID {uShort} instead of {Id}!");
			}
			state = ConnectionState.Connected;
			ResetTimeout();
			return true;
		}

		internal void HandleHeartbeat(Message message)
		{
			if (IsConnected)
			{
				RespondHeartbeat(message.GetByte());
				RTT = message.GetShort();
				ResetTimeout();
			}
		}

		private void RespondHeartbeat(byte pingId)
		{
			Message message = Message.Create(MessageHeader.Heartbeat);
			message.AddByte(pingId);
			Send(message);
		}

		internal void HandleWelcome(Message message)
		{
			Id = message.GetUShort();
			state = ConnectionState.Connected;
			ResetTimeout();
			RespondWelcome();
		}

		private void RespondWelcome()
		{
			Message message = Message.Create(MessageHeader.Welcome);
			message.AddUShort(Id);
			Send(message);
		}

		internal void SendHeartbeat()
		{
			pendingPingId = lastPingId++;
			pendingPingSendTime = Peer.CurrentTime;
			Message message = Message.Create(MessageHeader.Heartbeat);
			message.AddByte(pendingPingId);
			message.AddShort(RTT);
			Send(message);
		}

		internal void HandleHeartbeatResponse(Message message)
		{
			byte @byte = message.GetByte();
			if (pendingPingId == @byte)
			{
				RTT = (short)Math.Max(1L, Peer.CurrentTime - pendingPingSendTime);
			}
			ResetTimeout();
		}

		protected virtual void OnNotifyDelivered(ushort sequenceId)
		{
			Metrics.DeliveredNotify();
			NotifyDelivered?.Invoke(sequenceId);
			UpdateLossViolations();
		}

		protected virtual void OnNotifyLost(ushort sequenceId)
		{
			Metrics.LostNotify();
			NotifyLost?.Invoke(sequenceId);
			UpdateLossViolations();
		}
	}
	public class ServerConnectedEventArgs : EventArgs
	{
		public readonly Connection Client;

		public ServerConnectedEventArgs(Connection client)
		{
			Client = client;
		}
	}
	public class ServerConnectionFailedEventArgs : EventArgs
	{
		public readonly Connection Client;

		public ServerConnectionFailedEventArgs(Connection client)
		{
			Client = client;
		}
	}
	public class ServerDisconnectedEventArgs : EventArgs
	{
		public readonly Connection Client;

		public readonly DisconnectReason Reason;

		public ServerDisconnectedEventArgs(Connection client, DisconnectReason reason)
		{
			Client = client;
			Reason = reason;
		}
	}
	public class MessageReceivedEventArgs : EventArgs
	{
		public readonly Connection FromConnection;

		public readonly ushort MessageId;

		public readonly Message Message;

		public MessageReceivedEventArgs(Connection fromConnection, ushort messageId, Message message)
		{
			FromConnection = fromConnection;
			MessageId = messageId;
			Message = message;
		}
	}
	public class ConnectionFailedEventArgs : EventArgs
	{
		public readonly RejectReason Reason;

		public readonly Message Message;

		public ConnectionFailedEventArgs(RejectReason reason, Message message)
		{
			Reason = reason;
			Message = message;
		}
	}
	public class DisconnectedEventArgs : EventArgs
	{
		public readonly DisconnectReason Reason;

		public readonly Message Message;

		public DisconnectedEventArgs(DisconnectReason reason, Message message)
		{
			Reason = reason;
			Message = message;
		}
	}
	public class ClientConnectedEventArgs : EventArgs
	{
		public readonly ushort Id;

		public ClientConnectedEventArgs(ushort id)
		{
			Id = id;
		}
	}
	public class ClientDisconnectedEventArgs : EventArgs
	{
		public readonly ushort Id;

		public ClientDisconnectedEventArgs(ushort id)
		{
			Id = id;
		}
	}
	public class InsufficientCapacityException : Exception
	{
		public readonly Message RiptideMessage;

		public readonly string TypeName;

		public readonly int RequiredBits;

		public InsufficientCapacityException()
		{
		}

		public InsufficientCapacityException(string message)
			: base(message)
		{
		}

		public InsufficientCapacityException(string message, Exception inner)
			: base(message, inner)
		{
		}

		public InsufficientCapacityException(Message message, int reserveBits)
			: base(GetErrorMessage(message, reserveBits))
		{
			RiptideMessage = message;
			TypeName = "reservation";
			RequiredBits = reserveBits;
		}

		public InsufficientCapacityException(Message message, string typeName, int requiredBits)
			: base(GetErrorMessage(message, typeName, requiredBits))
		{
			RiptideMessage = message;
			TypeName = typeName;
			RequiredBits = requiredBits;
		}

		public InsufficientCapacityException(Message message, int arrayLength, string typeName, int requiredBits)
			: base(GetErrorMessage(message, arrayLength, typeName, requiredBits))
		{
			RiptideMessage = message;
			TypeName = typeName + "[]";
			RequiredBits = requiredBits * arrayLength;
		}

		private static string GetErrorMessage(Message message, int reserveBits)
		{
			return string.Format("Cannot reserve {0} {1} in a message with {2} ", reserveBits, Helper.CorrectForm(reserveBits, "bit"), message.UnwrittenBits) + Helper.CorrectForm(message.UnwrittenBits, "bit") + " of remaining capacity!";
		}

		private static string GetErrorMessage(Message message, string typeName, int requiredBits)
		{
			return string.Format("Cannot add a value of type '{0}' (requires {1} {2}) to ", typeName, requiredBits, Helper.CorrectForm(requiredBits, "bit")) + string.Format("a message with {0} {1} of remaining capacity!", message.UnwrittenBits, Helper.CorrectForm(message.UnwrittenBits, "bit"));
		}

		private static string GetErrorMessage(Message message, int arrayLength, string typeName, int requiredBits)
		{
			requiredBits *= arrayLength;
			return string.Format("Cannot add an array of type '{0}[]' with {1} {2} (requires {3} {4}) ", typeName, arrayLength, Helper.CorrectForm(arrayLength, "element"), requiredBits, Helper.CorrectForm(requiredBits, "bit")) + string.Format("to a message with {0} {1} of remaining capacity!", message.UnwrittenBits, Helper.CorrectForm(message.UnwrittenBits, "bit"));
		}
	}
	public class NonStaticHandlerException : Exception
	{
		public readonly Type DeclaringType;

		public readonly string HandlerMethodName;

		public NonStaticHandlerException()
		{
		}

		public NonStaticHandlerException(string message)
			: base(message)
		{
		}

		public NonStaticHandlerException(string message, Exception inner)
			: base(message, inner)
		{
		}

		public NonStaticHandlerException(Type declaringType, string handlerMethodName)
			: base(GetErrorMessage(declaringType, handlerMethodName))
		{
			DeclaringType = declaringType;
			HandlerMethodName = handlerMethodName;
		}

		private static string GetErrorMessage(Type declaringType, string handlerMethodName)
		{
			return "'" + declaringType.Name + "." + handlerMethodName + "' is an instance method, but message handler methods must be static!";
		}
	}
	public class InvalidHandlerSignatureException : Exception
	{
		public readonly Type DeclaringType;

		public readonly string HandlerMethodName;

		public InvalidHandlerSignatureException()
		{
		}

		public InvalidHandlerSignatureException(string message)
			: base(message)
		{
		}

		public InvalidHandlerSignatureException(string message, Exception inner)
			: base(message, inner)
		{
		}

		public InvalidHandlerSignatureException(Type declaringType, string handlerMethodName)
			: base(GetErrorMessage(declaringType, handlerMethodName))
		{
			DeclaringType = declaringType;
			HandlerMethodName = handlerMethodName;
		}

		private static string GetErrorMessage(Type declaringType, string handlerMethodName)
		{
			return "'" + declaringType.Name + "." + handlerMethodName + "' doesn't match any acceptable message handler method signatures! Server message handler methods should have a 'ushort' and a 'Message' parameter, while client message handler methods should only have a 'Message' parameter.";
		}
	}
	public class DuplicateHandlerException : Exception
	{
		public readonly ushort Id;

		public readonly Type DeclaringType1;

		public readonly string HandlerMethodName1;

		public readonly Type DeclaringType2;

		public readonly string HandlerMethodName2;

		public DuplicateHandlerException()
		{
		}

		public DuplicateHandlerException(string message)
			: base(message)
		{
		}

		public DuplicateHandlerException(string message, Exception inner)
			: base(message, inner)
		{
		}

		public DuplicateHandlerException(ushort id, MethodInfo method1, MethodInfo method2)
			: base(GetErrorMessage(id, method1, method2))
		{
			Id = id;
			DeclaringType1 = method1.DeclaringType;
			HandlerMethodName1 = method1.Name;
			DeclaringType2 = method2.DeclaringType;
			HandlerMethodName2 = method2.Name;
		}

		private static string GetErrorMessage(ushort id, MethodInfo method1, MethodInfo method2)
		{
			return $"Message handler methods '{method1.DeclaringType.Name}.{method1.Name}' and '{method2.DeclaringType.Name}.{method2.Name}' are both set to handle messages with ID {id}! Only one handler method is allowed per message ID!";
		}
	}
	public interface IMessageSerializable
	{
		void Serialize(Message message);

		void Deserialize(Message message);
	}
	public enum MessageSendMode : byte
	{
		Notify = 6,
		Unreliable = 0,
		Reliable = 7
	}
	public class Message
	{
		public const int MaxHeaderSize = 44;

		internal const int HeaderBits = 4;

		internal const byte HeaderBitmask = 15;

		internal const int UnreliableHeaderBits = 4;

		internal const int ReliableHeaderBits = 20;

		internal const int NotifyHeaderBits = 44;

		internal const int MinUnreliableBytes = 1;

		internal const int MinReliableBytes = 3;

		internal const int MinNotifyBytes = 6;

		private const int BitsPerByte = 8;

		private const int BitsPerSegment = 64;

		internal static byte[] ByteBuffer;

		private static int maxBitCount;

		private static int maxArraySize;

		private static readonly List<Message> pool;

		private readonly ulong[] data;

		private int readBit;

		private int writeBit;

		private const string ByteName = "byte";

		private const string SByteName = "sbyte";

		private const string BoolName = "bool";

		private const string ShortName = "short";

		private const string UShortName = "ushort";

		private const string IntName = "int";

		private const string UIntName = "uint";

		private const string LongName = "long";

		private const string ULongName = "ulong";

		private const string FloatName = "float";

		private const string DoubleName = "double";

		private const string StringName = "string";

		private const string ArrayLengthName = "array length";

		public static int MaxSize { get; private set; }

		public static int MaxPayloadSize
		{
			get
			{
				return MaxSize - 6;
			}
			set
			{
				if (Peer.ActiveCount > 0)
				{
					throw new InvalidOperationException("Changing the 'MaxPayloadSize' is not allowed while a Server or Client is running!");
				}
				if (value < 0)
				{
					throw new ArgumentOutOfRangeException("value", "'MaxPayloadSize' cannot be negative!");
				}
				MaxSize = 6 + value;
				maxBitCount = MaxSize * 8;
				maxArraySize = MaxSize / 8 + ((MaxSize % 8 != 0) ? 1 : 0);
				ByteBuffer = new byte[MaxSize];
				TrimPool();
				PendingMessage.ClearPool();
			}
		}

		public static byte InstancesPerPeer { get; set; }

		public MessageSendMode SendMode { get; private set; }

		public int ReadBits => readBit;

		public int UnreadBits => writeBit - readBit;

		public int WrittenBits => writeBit;

		public int UnwrittenBits => maxBitCount - writeBit;

		public int BytesInUse => writeBit / 8 + ((writeBit % 8 != 0) ? 1 : 0);

		[Obsolete("Use ReadBits instead.")]
		public int ReadLength => ReadBits / 8 + ((ReadBits % 8 != 0) ? 1 : 0);

		[Obsolete("Use UnreadBits instead.")]
		public int UnreadLength => UnreadBits / 8 + ((UnreadBits % 8 != 0) ? 1 : 0);

		[Obsolete("Use WrittenBits instead.")]
		public int WrittenLength => WrittenBits / 8 + ((WrittenBits % 8 != 0) ? 1 : 0);

		internal ulong[] Data => data;

		static Message()
		{
			InstancesPerPeer = 4;
			pool = new List<Message>(InstancesPerPeer * 2);
			MaxSize = 1231;
			maxBitCount = MaxSize * 8;
			maxArraySize = MaxSize / 8 + ((MaxSize % 8 != 0) ? 1 : 0);
			ByteBuffer = new byte[MaxSize];
		}

		private Message()
		{
			data = new ulong[maxArraySize];
		}

		public static Message Create()
		{
			Message message = RetrieveFromPool();
			message.readBit = 0;
			message.writeBit = 0;
			return message;
		}

		public static Message Create(MessageSendMode sendMode)
		{
			return RetrieveFromPool().Init((MessageHeader)sendMode);
		}

		public static Message Create(MessageSendMode sendMode, ushort id)
		{
			return RetrieveFromPool().Init((MessageHeader)sendMode).AddVarULong(id);
		}

		public static Message Create(MessageSendMode sendMode, Enum id)
		{
			return Create(sendMode, (ushort)(object)id);
		}

		internal static Message Create(MessageHeader header)
		{
			return RetrieveFromPool().Init(header);
		}

		public static void TrimPool()
		{
			if (Peer.ActiveCount == 0)
			{
				pool.Clear();
				pool.Capacity = InstancesPerPeer * 2;
				return;
			}
			int num = Peer.ActiveCount * InstancesPerPeer;
			if (pool.Count > num)
			{
				pool.RemoveRange(Peer.ActiveCount * InstancesPerPeer, pool.Count - num);
				pool.Capacity = num * 2;
			}
		}

		private static Message RetrieveFromPool()
		{
			Message result;
			if (pool.Count > 0)
			{
				result = pool[0];
				pool.RemoveAt(0);
			}
			else
			{
				result = new Message();
			}
			return result;
		}

		public void Release()
		{
			if (pool.Count < pool.Capacity && !pool.Contains(this))
			{
				pool.Add(this);
			}
		}

		private Message Init(MessageHeader header)
		{
			data[0] = (ulong)header;
			SetHeader(header);
			return this;
		}

		internal Message Init(byte firstByte, int contentLength, out MessageHeader header)
		{
			data[contentLength / 8] = 0uL;
			data[0] = firstByte;
			header = (MessageHeader)(firstByte & 0xFu);
			SetHeader(header);
			writeBit = contentLength * 8;
			return this;
		}

		private void SetHeader(MessageHeader header)
		{
			if (header == MessageHeader.Notify)
			{
				readBit = 44;
				writeBit = 44;
				SendMode = MessageSendMode.Notify;
			}
			else if ((int)header >= 7)
			{
				readBit = 20;
				writeBit = 20;
				SendMode = MessageSendMode.Reliable;
			}
			else
			{
				readBit = 4;
				writeBit = 4;
				SendMode = MessageSendMode.Unreliable;
			}
		}

		public Message AddMessage(Message message)
		{
			return AddMessage(message, message.UnreadBits, message.readBit);
		}

		public Message AddMessage(Message message, int amount, int startBit)
		{
			if (UnwrittenBits < amount)
			{
				throw new InsufficientCapacityException(this, "Message", amount);
			}
			int num = startBit / 64;
			int num2 = startBit % 64;
			int num3 = writeBit / 64;
			int num4 = writeBit % 64;
			int num5 = num4 - num2;
			int num6 = (writeBit + amount) / 64 - num3 + 1;
			if (num5 == 0)
			{
				ulong num7 = message.data[num];
				if (num4 == 0)
				{
					data[num3] = num7;
				}
				else
				{
					data[num3] |= num7 & (ulong)(~((1L << num2) - 1));
				}
				for (int i = 1; i < num6; i++)
				{
					data[num3 + i] = message.data[num + i];
				}
			}
			else if (num5 > 0)
			{
				ulong num8 = message.data[num] & (ulong)(~((1L << num2) - 1));
				num8 <<= num5;
				if (num4 == 0)
				{
					data[num3] = num8;
				}
				else
				{
					data[num3] |= num8;
				}
				for (int j = 1; j < num6; j++)
				{
					data[num3 + j] = (message.data[num + j - 1] >> 64 - num5) | (message.data[num + j] << num5);
				}
			}
			else
			{
				num5 = -num5;
				ulong num9 = message.data[num] & (ulong)(~((1L << num2) - 1));
				num9 >>= num5;
				if (num4 == 0)
				{
					data[num3] = num9;
				}
				else
				{
					data[num3] |= num9;
				}
				int num10 = (startBit + amount) / 64 - num + 1;
				for (int k = 1; k < num10; k++)
				{
					data[num3 + k - 1] |= message.data[num + k] << 64 - num5;
					data[num3 + k] = message.data[num + k] >> num5;
				}
			}
			writeBit += amount;
			data[num3 + num6 - 1] &= (ulong)((1L << writeBit % 64) - 1);
			return this;
		}

		public Message ReserveBits(int amount)
		{
			if (UnwrittenBits < amount)
			{
				throw new InsufficientCapacityException(this, amount);
			}
			int num = writeBit % 64;
			writeBit += amount;
			if (num + amount >= 64)
			{
				data[writeBit / 64] = 0uL;
			}
			return this;
		}

		public Message SkipBits(int amount)
		{
			if (UnreadBits < amount)
			{
				RiptideLogger.Log(LogType.Error, string.Format("Message only contains {0} unread {1}, which is not enough to skip {2}!", UnreadBits, Helper.CorrectForm(UnreadBits, "bit"), amount));
			}
			readBit += amount;
			return this;
		}

		public Message SetBits(ulong bitfield, int amount, int startBit)
		{
			if (amount > 64)
			{
				throw new ArgumentOutOfRangeException("amount", $"Cannot set more than {64} bits at a time!");
			}
			Converter.SetBits(bitfield, amount, data, startBit);
			return this;
		}

		public Message PeekBits(int amount, int startBit, out byte bitfield)
		{
			if (amount > 8)
			{
				throw new ArgumentOutOfRangeException("amount", string.Format("This '{0}' overload cannot be used to peek more than {1} bits at a time!", "PeekBits", 8));
			}
			Converter.GetBits(amount, data, startBit, out bitfield);
			return this;
		}

		public Message PeekBits(int amount, int startBit, out ushort bitfield)
		{
			if (amount > 16)
			{
				throw new ArgumentOutOfRangeException("amount", string.Format("This '{0}' overload cannot be used to peek more than {1} bits at a time!", "PeekBits", 16));
			}
			Converter.GetBits(amount, data, startBit, out bitfield);
			return this;
		}

		public Message PeekBits(int amount, int startBit, out uint bitfield)
		{
			if (amount > 32)
			{
				throw new ArgumentOutOfRangeException("amount", string.Format("This '{0}' overload cannot be used to peek more than {1} bits at a time!", "PeekBits", 32));
			}
			Converter.GetBits(amount, data, startBit, out bitfield);
			return this;
		}

		public Message PeekBits(int amount, int startBit, out ulong bitfield)
		{
			if (amount > 64)
			{
				throw new ArgumentOutOfRangeException("amount", string.Format("This '{0}' overload cannot be used to peek more than {1} bits at a time!", "PeekBits", 64));
			}
			Converter.GetBits(amount, data, startBit, out bitfield);
			return this;
		}

		public Message AddBits(byte bitfield, int amount)
		{
			if (amount > 8)
			{
				throw new ArgumentOutOfRangeException("amount", string.Format("This '{0}' overload cannot be used to add more than {1} bits at a time!", "AddBits", 8));
			}
			bitfield &= (byte)((1 << amount) - 1);
			Converter.ByteToBits(bitfield, data, writeBit);
			writeBit += amount;
			return this;
		}

		public Message AddBits(ushort bitfield, int amount)
		{
			if (amount > 16)
			{
				throw new ArgumentOutOfRangeException("amount", string.Format("This '{0}' overload cannot be used to add more than {1} bits at a time!", "AddBits", 16));
			}
			bitfield &= (ushort)((1 << amount) - 1);
			Converter.UShortToBits(bitfield, data, writeBit);
			writeBit += amount;
			return this;
		}

		public Message AddBits(uint bitfield, int amount)
		{
			if (amount > 32)
			{
				throw new ArgumentOutOfRangeException("amount", string.Format("This '{0}' overload cannot be used to add more than {1} bits at a time!", "AddBits", 32));
			}
			bitfield &= (uint)((1 << amount - 1 << 1) - 1);
			Converter.UIntToBits(bitfield, data, writeBit);
			writeBit += amount;
			return this;
		}

		public Message AddBits(ulong bitfield, int amount)
		{
			if (amount > 64)
			{
				throw new ArgumentOutOfRangeException("amount", string.Format("This '{0}' overload cannot be used to add more than {1} bits at a time!", "AddBits", 64));
			}
			bitfield &= (ulong)((1L << amount - 1 << 1) - 1);
			Converter.ULongToBits(bitfield, data, writeBit);
			writeBit += amount;
			return this;
		}

		public Message GetBits(int amount, out byte bitfield)
		{
			PeekBits(amount, readBit, out bitfield);
			readBit += amount;
			return this;
		}

		public Message GetBits(int amount, out ushort bitfield)
		{
			PeekBits(amount, readBit, out bitfield);
			readBit += amount;
			return this;
		}

		public Message GetBits(int amount, out uint bitfield)
		{
			PeekBits(amount, readBit, out bitfield);
			readBit += amount;
			return this;
		}

		public Message GetBits(int amount, out ulong bitfield)
		{
			PeekBits(amount, readBit, out bitfield);
			readBit += amount;
			return this;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message AddVarLong(long value)
		{
			return AddVarULong((ulong)Converter.ZigZagEncode(value));
		}

		public Message AddVarULong(ulong value)
		{
			do
			{
				byte b = (byte)(value & 0x7F);
				value >>= 7;
				if (value != 0L)
				{
					b = (byte)(b | 0x80u);
				}
				AddByte(b);
			}
			while (value != 0L);
			return this;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public long GetVarLong()
		{
			return Converter.ZigZagDecode((long)GetVarULong());
		}

		public ulong GetVarULong()
		{
			ulong num = 0uL;
			int num2 = 0;
			ulong num3;
			do
			{
				num3 = GetByte();
				num |= (num3 & 0x7F) << num2;
				num2 += 7;
			}
			while ((num3 & 0x80) != 0L);
			return num;
		}

		public Message AddByte(byte value)
		{
			if (UnwrittenBits < 8)
			{
				throw new InsufficientCapacityException(this, "byte", 8);
			}
			Converter.ByteToBits(value, data, writeBit);
			writeBit += 8;
			return this;
		}

		public Message AddSByte(sbyte value)
		{
			if (UnwrittenBits < 8)
			{
				throw new InsufficientCapacityException(this, "sbyte", 8);
			}
			Converter.SByteToBits(value, data, writeBit);
			writeBit += 8;
			return this;
		}

		public byte GetByte()
		{
			if (UnreadBits < 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("byte", $"{(byte)0}"));
				return 0;
			}
			byte result = Converter.ByteFromBits(data, readBit);
			readBit += 8;
			return result;
		}

		public sbyte GetSByte()
		{
			if (UnreadBits < 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("sbyte", $"{(sbyte)0}"));
				return 0;
			}
			sbyte result = Converter.SByteFromBits(data, readBit);
			readBit += 8;
			return result;
		}

		public Message AddBytes(byte[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			int num = array.Length * 8;
			if (UnwrittenBits < num)
			{
				throw new InsufficientCapacityException(this, array.Length, "byte", 8);
			}
			if (writeBit % 8 == 0)
			{
				int num2 = writeBit % 64;
				if (num2 + num > 64)
				{
					data[(writeBit + num) / 64] = 0uL;
				}
				else if (num2 == 0)
				{
					data[writeBit / 64] = 0uL;
				}
				Buffer.BlockCopy(array, 0, data, writeBit / 8, array.Length);
				writeBit += num;
			}
			else
			{
				for (int i = 0; i < array.Length; i++)
				{
					Converter.ByteToBits(array[i], data, writeBit);
					writeBit += 8;
				}
			}
			return this;
		}

		public Message AddBytes(byte[] array, int startIndex, int amount, bool includeLength = true)
		{
			if (startIndex < 0 || startIndex >= array.Length)
			{
				throw new ArgumentOutOfRangeException("startIndex");
			}
			if (startIndex + amount > array.Length)
			{
				throw new ArgumentException("amount", string.Format("The source array is not long enough to read {0} {1} starting at {2}!", amount, Helper.CorrectForm(amount, "byte"), startIndex));
			}
			if (includeLength)
			{
				AddVarULong((uint)amount);
			}
			int num = amount * 8;
			if (UnwrittenBits < num)
			{
				throw new InsufficientCapacityException(this, amount, "byte", 8);
			}
			if (writeBit % 8 == 0)
			{
				int num2 = writeBit % 64;
				if (num2 + num > 64)
				{
					data[(writeBit + num) / 64] = 0uL;
				}
				else if (num2 == 0)
				{
					data[writeBit / 64] = 0uL;
				}
				Buffer.BlockCopy(array, startIndex, data, writeBit / 8, amount);
				writeBit += num;
			}
			else
			{
				for (int i = startIndex; i < startIndex + amount; i++)
				{
					Converter.ByteToBits(array[i], data, writeBit);
					writeBit += 8;
				}
			}
			return this;
		}

		public Message AddSBytes(sbyte[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length * 8)
			{
				throw new InsufficientCapacityException(this, array.Length, "sbyte", 8);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.SByteToBits(array[i], data, writeBit);
				writeBit += 8;
			}
			return this;
		}

		public byte[] GetBytes()
		{
			return GetBytes((int)GetVarULong());
		}

		public byte[] GetBytes(int amount)
		{
			byte[] array = new byte[amount];
			ReadBytes(amount, array);
			return array;
		}

		public void GetBytes(byte[] intoArray, int startIndex = 0)
		{
			GetBytes((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetBytes(int amount, byte[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "byte"));
			}
			ReadBytes(amount, intoArray, startIndex);
		}

		public sbyte[] GetSBytes()
		{
			return GetSBytes((int)GetVarULong());
		}

		public sbyte[] GetSBytes(int amount)
		{
			sbyte[] array = new sbyte[amount];
			ReadSBytes(amount, array);
			return array;
		}

		public void GetSBytes(sbyte[] intoArray, int startIndex = 0)
		{
			GetSBytes((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetSBytes(int amount, sbyte[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "sbyte"));
			}
			ReadSBytes(amount, intoArray, startIndex);
		}

		private void ReadBytes(int amount, byte[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "byte"));
				amount = UnreadBits / 8;
			}
			if (readBit % 8 == 0)
			{
				Buffer.BlockCopy(data, readBit / 8, intoArray, startIndex, amount);
				readBit += amount * 8;
				return;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.ByteFromBits(data, readBit);
				readBit += 8;
			}
		}

		private void ReadSBytes(int amount, sbyte[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "sbyte"));
				amount = UnreadBits / 8;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.SByteFromBits(data, readBit);
				readBit += 8;
			}
		}

		public Message AddBool(bool value)
		{
			if (UnwrittenBits < 1)
			{
				throw new InsufficientCapacityException(this, "bool", 1);
			}
			Converter.BoolToBit(value, data, writeBit++);
			return this;
		}

		public bool GetBool()
		{
			if (UnreadBits < 1)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("bool", $"{false}"));
				return false;
			}
			return Converter.BoolFromBit(data, readBit++);
		}

		public Message AddBools(bool[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length)
			{
				throw new InsufficientCapacityException(this, array.Length, "bool", 1);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.BoolToBit(array[i], data, writeBit++);
			}
			return this;
		}

		public bool[] GetBools()
		{
			return GetBools((int)GetVarULong());
		}

		public bool[] GetBools(int amount)
		{
			bool[] array = new bool[amount];
			ReadBools(amount, array);
			return array;
		}

		public void GetBools(bool[] intoArray, int startIndex = 0)
		{
			GetBools((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetBools(int amount, bool[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "bool"));
			}
			ReadBools(amount, intoArray, startIndex);
		}

		private void ReadBools(int amount, bool[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "bool"));
				amount = UnreadBits;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.BoolFromBit(data, readBit++);
			}
		}

		public Message AddShort(short value)
		{
			if (UnwrittenBits < 16)
			{
				throw new InsufficientCapacityException(this, "short", 16);
			}
			Converter.ShortToBits(value, data, writeBit);
			writeBit += 16;
			return this;
		}

		public Message AddUShort(ushort value)
		{
			if (UnwrittenBits < 16)
			{
				throw new InsufficientCapacityException(this, "ushort", 16);
			}
			Converter.UShortToBits(value, data, writeBit);
			writeBit += 16;
			return this;
		}

		public short GetShort()
		{
			if (UnreadBits < 16)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("short", $"{(short)0}"));
				return 0;
			}
			short result = Converter.ShortFromBits(data, readBit);
			readBit += 16;
			return result;
		}

		public ushort GetUShort()
		{
			if (UnreadBits < 16)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("ushort", $"{(ushort)0}"));
				return 0;
			}
			ushort result = Converter.UShortFromBits(data, readBit);
			readBit += 16;
			return result;
		}

		public Message AddShorts(short[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length * 2 * 8)
			{
				throw new InsufficientCapacityException(this, array.Length, "short", 16);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.ShortToBits(array[i], data, writeBit);
				writeBit += 16;
			}
			return this;
		}

		public Message AddUShorts(ushort[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length * 2 * 8)
			{
				throw new InsufficientCapacityException(this, array.Length, "ushort", 16);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.UShortToBits(array[i], data, writeBit);
				writeBit += 16;
			}
			return this;
		}

		public short[] GetShorts()
		{
			return GetShorts((int)GetVarULong());
		}

		public short[] GetShorts(int amount)
		{
			short[] array = new short[amount];
			ReadShorts(amount, array);
			return array;
		}

		public void GetShorts(short[] intoArray, int startIndex = 0)
		{
			GetShorts((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetShorts(int amount, short[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "short"));
			}
			ReadShorts(amount, intoArray, startIndex);
		}

		public ushort[] GetUShorts()
		{
			return GetUShorts((int)GetVarULong());
		}

		public ushort[] GetUShorts(int amount)
		{
			ushort[] array = new ushort[amount];
			ReadUShorts(amount, array);
			return array;
		}

		public void GetUShorts(ushort[] intoArray, int startIndex = 0)
		{
			GetUShorts((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetUShorts(int amount, ushort[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "ushort"));
			}
			ReadUShorts(amount, intoArray, startIndex);
		}

		private void ReadShorts(int amount, short[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 2 * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "short"));
				amount = UnreadBits / 16;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.ShortFromBits(data, readBit);
				readBit += 16;
			}
		}

		private void ReadUShorts(int amount, ushort[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 2 * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "ushort"));
				amount = UnreadBits / 16;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.UShortFromBits(data, readBit);
				readBit += 16;
			}
		}

		public Message AddInt(int value)
		{
			if (UnwrittenBits < 32)
			{
				throw new InsufficientCapacityException(this, "int", 32);
			}
			Converter.IntToBits(value, data, writeBit);
			writeBit += 32;
			return this;
		}

		public Message AddUInt(uint value)
		{
			if (UnwrittenBits < 32)
			{
				throw new InsufficientCapacityException(this, "uint", 32);
			}
			Converter.UIntToBits(value, data, writeBit);
			writeBit += 32;
			return this;
		}

		public int GetInt()
		{
			if (UnreadBits < 32)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("int", $"{0}"));
				return 0;
			}
			int result = Converter.IntFromBits(data, readBit);
			readBit += 32;
			return result;
		}

		public uint GetUInt()
		{
			if (UnreadBits < 32)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("uint", $"{0u}"));
				return 0u;
			}
			uint result = Converter.UIntFromBits(data, readBit);
			readBit += 32;
			return result;
		}

		public Message AddInts(int[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length * 4 * 8)
			{
				throw new InsufficientCapacityException(this, array.Length, "int", 32);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.IntToBits(array[i], data, writeBit);
				writeBit += 32;
			}
			return this;
		}

		public Message AddUInts(uint[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length * 4 * 8)
			{
				throw new InsufficientCapacityException(this, array.Length, "uint", 32);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.UIntToBits(array[i], data, writeBit);
				writeBit += 32;
			}
			return this;
		}

		public int[] GetInts()
		{
			return GetInts((int)GetVarULong());
		}

		public int[] GetInts(int amount)
		{
			int[] array = new int[amount];
			ReadInts(amount, array);
			return array;
		}

		public void GetInts(int[] intoArray, int startIndex = 0)
		{
			GetInts((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetInts(int amount, int[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "int"));
			}
			ReadInts(amount, intoArray, startIndex);
		}

		public uint[] GetUInts()
		{
			return GetUInts((int)GetVarULong());
		}

		public uint[] GetUInts(int amount)
		{
			uint[] array = new uint[amount];
			ReadUInts(amount, array);
			return array;
		}

		public void GetUInts(uint[] intoArray, int startIndex = 0)
		{
			GetUInts((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetUInts(int amount, uint[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "uint"));
			}
			ReadUInts(amount, intoArray, startIndex);
		}

		private void ReadInts(int amount, int[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 4 * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "int"));
				amount = UnreadBits / 32;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.IntFromBits(data, readBit);
				readBit += 32;
			}
		}

		private void ReadUInts(int amount, uint[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 4 * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "uint"));
				amount = UnreadBits / 32;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.UIntFromBits(data, readBit);
				readBit += 32;
			}
		}

		public Message AddLong(long value)
		{
			if (UnwrittenBits < 64)
			{
				throw new InsufficientCapacityException(this, "long", 64);
			}
			Converter.LongToBits(value, data, writeBit);
			writeBit += 64;
			return this;
		}

		public Message AddULong(ulong value)
		{
			if (UnwrittenBits < 64)
			{
				throw new InsufficientCapacityException(this, "ulong", 64);
			}
			Converter.ULongToBits(value, data, writeBit);
			writeBit += 64;
			return this;
		}

		public long GetLong()
		{
			if (UnreadBits < 64)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("long", $"{0L}"));
				return 0L;
			}
			long result = Converter.LongFromBits(data, readBit);
			readBit += 64;
			return result;
		}

		public ulong GetULong()
		{
			if (UnreadBits < 64)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("ulong", $"{0uL}"));
				return 0uL;
			}
			ulong result = Converter.ULongFromBits(data, readBit);
			readBit += 64;
			return result;
		}

		public Message AddLongs(long[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length * 8 * 8)
			{
				throw new InsufficientCapacityException(this, array.Length, "long", 64);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.LongToBits(array[i], data, writeBit);
				writeBit += 64;
			}
			return this;
		}

		public Message AddULongs(ulong[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length * 8 * 8)
			{
				throw new InsufficientCapacityException(this, array.Length, "ulong", 64);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.ULongToBits(array[i], data, writeBit);
				writeBit += 64;
			}
			return this;
		}

		public long[] GetLongs()
		{
			return GetLongs((int)GetVarULong());
		}

		public long[] GetLongs(int amount)
		{
			long[] array = new long[amount];
			ReadLongs(amount, array);
			return array;
		}

		public void GetLongs(long[] intoArray, int startIndex = 0)
		{
			GetLongs((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetLongs(int amount, long[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "long"));
			}
			ReadLongs(amount, intoArray, startIndex);
		}

		public ulong[] GetULongs()
		{
			return GetULongs((int)GetVarULong());
		}

		public ulong[] GetULongs(int amount)
		{
			ulong[] array = new ulong[amount];
			ReadULongs(amount, array);
			return array;
		}

		public void GetULongs(ulong[] intoArray, int startIndex = 0)
		{
			GetULongs((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetULongs(int amount, ulong[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "ulong"));
			}
			ReadULongs(amount, intoArray, startIndex);
		}

		private void ReadLongs(int amount, long[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 8 * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "long"));
				amount = UnreadBits / 64;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.LongFromBits(data, readBit);
				readBit += 64;
			}
		}

		private void ReadULongs(int amount, ulong[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 8 * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "ulong"));
				amount = UnreadBits / 64;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.ULongFromBits(data, readBit);
				readBit += 64;
			}
		}

		public Message AddFloat(float value)
		{
			if (UnwrittenBits < 32)
			{
				throw new InsufficientCapacityException(this, "float", 32);
			}
			Converter.FloatToBits(value, data, writeBit);
			writeBit += 32;
			return this;
		}

		public float GetFloat()
		{
			if (UnreadBits < 32)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("float", $"{0f}"));
				return 0f;
			}
			float result = Converter.FloatFromBits(data, readBit);
			readBit += 32;
			return result;
		}

		public Message AddFloats(float[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length * 4 * 8)
			{
				throw new InsufficientCapacityException(this, array.Length, "float", 32);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.FloatToBits(array[i], data, writeBit);
				writeBit += 32;
			}
			return this;
		}

		public float[] GetFloats()
		{
			return GetFloats((int)GetVarULong());
		}

		public float[] GetFloats(int amount)
		{
			float[] array = new float[amount];
			ReadFloats(amount, array);
			return array;
		}

		public void GetFloats(float[] intoArray, int startIndex = 0)
		{
			GetFloats((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetFloats(int amount, float[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "float"));
			}
			ReadFloats(amount, intoArray, startIndex);
		}

		private void ReadFloats(int amount, float[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 4 * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "float"));
				amount = UnreadBits / 32;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.FloatFromBits(data, readBit);
				readBit += 32;
			}
		}

		public Message AddDouble(double value)
		{
			if (UnwrittenBits < 64)
			{
				throw new InsufficientCapacityException(this, "double", 64);
			}
			Converter.DoubleToBits(value, data, writeBit);
			writeBit += 64;
			return this;
		}

		public double GetDouble()
		{
			if (UnreadBits < 64)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("double", $"{0.0}"));
				return 0.0;
			}
			double result = Converter.DoubleFromBits(data, readBit);
			readBit += 64;
			return result;
		}

		public Message AddDoubles(double[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			if (UnwrittenBits < array.Length * 8 * 8)
			{
				throw new InsufficientCapacityException(this, array.Length, "double", 64);
			}
			for (int i = 0; i < array.Length; i++)
			{
				Converter.DoubleToBits(array[i], data, writeBit);
				writeBit += 64;
			}
			return this;
		}

		public double[] GetDoubles()
		{
			return GetDoubles((int)GetVarULong());
		}

		public double[] GetDoubles(int amount)
		{
			double[] array = new double[amount];
			ReadDoubles(amount, array);
			return array;
		}

		public void GetDoubles(double[] intoArray, int startIndex = 0)
		{
			GetDoubles((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetDoubles(int amount, double[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "double"));
			}
			ReadDoubles(amount, intoArray, startIndex);
		}

		private void ReadDoubles(int amount, double[] intoArray, int startIndex = 0)
		{
			if (UnreadBits < amount * 8 * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError(amount, "double"));
				amount = UnreadBits / 64;
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = Converter.DoubleFromBits(data, readBit);
				readBit += 64;
			}
		}

		public Message AddString(string value)
		{
			AddBytes(Encoding.UTF8.GetBytes(value));
			return this;
		}

		public string GetString()
		{
			int num = (int)GetVarULong();
			if (UnreadBits < num * 8)
			{
				RiptideLogger.Log(LogType.Error, NotEnoughBitsError("string", "shortened string"));
				num = UnreadBits / 8;
			}
			return Encoding.UTF8.GetString(GetBytes(num), 0, num);
		}

		public Message AddStrings(string[] array, bool includeLength = true)
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			for (int i = 0; i < array.Length; i++)
			{
				AddString(array[i]);
			}
			return this;
		}

		public string[] GetStrings()
		{
			return GetStrings((int)GetVarULong());
		}

		public string[] GetStrings(int amount)
		{
			string[] array = new string[amount];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = GetString();
			}
			return array;
		}

		public void GetStrings(string[] intoArray, int startIndex = 0)
		{
			GetStrings((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetStrings(int amount, string[] intoArray, int startIndex = 0)
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, "string"));
			}
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = GetString();
			}
		}

		public Message AddSerializable<T>(T value) where T : IMessageSerializable
		{
			value.Serialize(this);
			return this;
		}

		public T GetSerializable<T>() where T : IMessageSerializable, new()
		{
			T result = new T();
			result.Deserialize(this);
			return result;
		}

		public Message AddSerializables<T>(T[] array, bool includeLength = true) where T : IMessageSerializable
		{
			if (includeLength)
			{
				AddVarULong((uint)array.Length);
			}
			for (int i = 0; i < array.Length; i++)
			{
				AddSerializable(array[i]);
			}
			return this;
		}

		public T[] GetSerializables<T>() where T : IMessageSerializable, new()
		{
			return GetSerializables<T>((int)GetVarULong());
		}

		public T[] GetSerializables<T>(int amount) where T : IMessageSerializable, new()
		{
			T[] array = new T[amount];
			ReadSerializables(amount, array);
			return array;
		}

		public void GetSerializables<T>(T[] intoArray, int startIndex = 0) where T : IMessageSerializable, new()
		{
			GetSerializables((int)GetVarULong(), intoArray, startIndex);
		}

		public void GetSerializables<T>(int amount, T[] intoArray, int startIndex = 0) where T : IMessageSerializable, new()
		{
			if (startIndex + amount > intoArray.Length)
			{
				throw new ArgumentException("amount", ArrayNotLongEnoughError(amount, intoArray.Length, startIndex, typeof(T).Name));
			}
			ReadSerializables(amount, intoArray, startIndex);
		}

		private void ReadSerializables<T>(int amount, T[] intoArray, int startIndex = 0) where T : IMessageSerializable, new()
		{
			for (int i = 0; i < amount; i++)
			{
				intoArray[startIndex + i] = GetSerializable<T>();
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(byte value)
		{
			return AddByte(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(sbyte value)
		{
			return AddSByte(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(bool value)
		{
			return AddBool(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(short value)
		{
			return AddShort(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(ushort value)
		{
			return AddUShort(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(int value)
		{
			return AddInt(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(uint value)
		{
			return AddUInt(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(long value)
		{
			return AddLong(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(ulong value)
		{
			return AddULong(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(float value)
		{
			return AddFloat(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(double value)
		{
			return AddDouble(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(string value)
		{
			return AddString(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add<T>(T value) where T : IMessageSerializable
		{
			return AddSerializable(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(byte[] array, bool includeLength = true)
		{
			return AddBytes(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(sbyte[] array, bool includeLength = true)
		{
			return AddSBytes(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(bool[] array, bool includeLength = true)
		{
			return AddBools(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(short[] array, bool includeLength = true)
		{
			return AddShorts(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(ushort[] array, bool includeLength = true)
		{
			return AddUShorts(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(int[] array, bool includeLength = true)
		{
			return AddInts(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(uint[] array, bool includeLength = true)
		{
			return AddUInts(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(long[] array, bool includeLength = true)
		{
			return AddLongs(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(ulong[] array, bool includeLength = true)
		{
			return AddULongs(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(float[] array, bool includeLength = true)
		{
			return AddFloats(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(double[] array, bool includeLength = true)
		{
			return AddDoubles(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add(string[] array, bool includeLength = true)
		{
			return AddStrings(array, includeLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Message Add<T>(T[] array, bool includeLength = true) where T : IMessageSerializable, new()
		{
			return AddSerializables(array, includeLength);
		}

		private string NotEnoughBitsError(string valueName, string defaultReturn)
		{
			return string.Format("Message only contains {0} unread {1}, which is not enough to retrieve a value of type '{2}'! Returning {3}.", UnreadBits, Helper.CorrectForm(UnreadBits, "bit"), valueName, defaultReturn);
		}

		private string NotEnoughBitsError(int arrayLength, string valueName)
		{
			return string.Format("Message only contains {0} unread {1}, which is not enough to retrieve {2} {3}! Returned array will contain default elements.", UnreadBits, Helper.CorrectForm(UnreadBits, "bit"), arrayLength, Helper.CorrectForm(arrayLength, valueName));
		}

		private string ArrayNotLongEnoughError(int amount, int arrayLength, int startIndex, string valueName, string pluralValueName = "")
		{
			if (string.IsNullOrEmpty(pluralValueName))
			{
				pluralValueName = valueName + "s";
			}
			return $"The amount of {pluralValueName} to retrieve ({amount}) is greater than the number of elements from the start index ({startIndex}) to the end of the given array (length: {arrayLength})!";
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
	public sealed class MessageHandlerAttribute : Attribute
	{
		public readonly ushort MessageId;

		public readonly byte GroupId;

		public MessageHandlerAttribute(ushort messageId, byte groupId = 0)
		{
			MessageId = messageId;
			GroupId = groupId;
		}
	}
	public class MessageRelayFilter
	{
		private const int BitsPerInt = 32;

		private int[] filter;

		public MessageRelayFilter(int size)
		{
			Set(size);
		}

		public MessageRelayFilter(Type idEnum)
		{
			Set(GetSizeFromEnum(idEnum));
		}

		public MessageRelayFilter(int size, params ushort[] idsToEnable)
		{
			Set(size);
			EnableIds(idsToEnable);
		}

		public MessageRelayFilter(Type idEnum, params Enum[] idsToEnable)
		{
			Set(GetSizeFromEnum(idEnum));
			EnableIds(idsToEnable.Cast<ushort>().ToArray());
		}

		private void EnableIds(ushort[] idsToEnable)
		{
			for (int i = 0; i < idsToEnable.Length; i++)
			{
				EnableRelay(idsToEnable[i]);
			}
		}

		private int GetSizeFromEnum(Type idEnum)
		{
			if (!idEnum.IsEnum)
			{
				throw new ArgumentException("Parameter 'idEnum' must be an enum type!", "idEnum");
			}
			return Enum.GetValues(idEnum).Cast<ushort>().Max() + 1;
		}

		private void Set(int size)
		{
			filter = new int[size / 32 + ((size % 32 > 0) ? 1 : 0)];
		}

		public void EnableRelay(ushort forMessageId)
		{
			filter[forMessageId / 32] |= 1 << forMessageId % 32;
		}

		public void EnableRelay(Enum forMessageId)
		{
			EnableRelay((ushort)(object)forMessageId);
		}

		public void DisableRelay(ushort forMessageId)
		{
			filter[forMessageId / 32] &= ~(1 << forMessageId % 32);
		}

		public void DisableRelay(Enum forMessageId)
		{
			DisableRelay((ushort)(object)forMessageId);
		}

		internal bool ShouldRelay(ushort forMessageId)
		{
			return (filter[forMessageId / 32] & (1 << forMessageId % 32)) != 0;
		}
	}
	public enum RejectReason : byte
	{
		NoConnection,
		AlreadyConnected,
		ServerFull,
		Rejected,
		Custom
	}
	public enum DisconnectReason : byte
	{
		NeverConnected,
		ConnectionRejected,
		TransportError,
		TimedOut,
		Kicked,
		ServerStopped,
		Disconnected,
		PoorConnection
	}
	public abstract class Peer
	{
		public readonly string LogName;

		protected bool useMessageHandlers;

		protected int defaultTimeout = 5000;

		private readonly Stopwatch time = new Stopwatch();

		private readonly Queue<MessageToHandle> messagesToHandle = new Queue<MessageToHandle>();

		private readonly Riptide.Utils.PriorityQueue<DelayedEvent, long> eventQueue = new Riptide.Utils.PriorityQueue<DelayedEvent, long>();

		public abstract int TimeoutTime { set; }

		public int HeartbeatInterval { get; set; } = 1000;


		internal static int ActiveCount { get; private set; }

		internal int ConnectTimeoutTime { get; set; } = 10000;


		internal long CurrentTime { get; private set; }

		public Peer(string logName)
		{
			LogName = logName;
		}

		protected MethodInfo[] FindMessageHandlers()
		{
			string thisAssemblyName = Assembly.GetExecutingAssembly().GetName().FullName;
			return (from m in (from a in AppDomain.CurrentDomain.GetAssemblies()
					where a.GetReferencedAssemblies().Any((AssemblyName n) => n.FullName == thisAssemblyName)
					select a).SelectMany((Assembly a) => a.GetTypes()).SelectMany((Type t) => t.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
				where m.GetCustomAttributes(typeof(MessageHandlerAttribute), inherit: false).Length != 0
				select m).ToArray();
		}

		protected abstract void CreateMessageHandlersDictionary(byte messageHandlerGroupId);

		protected void StartTime()
		{
			CurrentTime = 0L;
			time.Restart();
		}

		protected void StopTime()
		{
			CurrentTime = 0L;
			time.Reset();
			eventQueue.Clear();
		}

		internal abstract void Heartbeat();

		public virtual void Update()
		{
			CurrentTime = time.ElapsedMilliseconds;
			while (eventQueue.Count > 0 && eventQueue.PeekPriority() <= CurrentTime)
			{
				eventQueue.Dequeue().Invoke();
			}
		}

		internal void ExecuteLater(long inMS, DelayedEvent delayedEvent)
		{
			eventQueue.Enqueue(delayedEvent, CurrentTime + inMS);
		}

		protected void HandleMessages()
		{
			while (messagesToHandle.Count > 0)
			{
				MessageToHandle messageToHandle = messagesToHandle.Dequeue();
				Handle(messageToHandle.Message, messageToHandle.Header, messageToHandle.FromConnection);
			}
		}

		protected void HandleData(object _, Riptide.Transports.DataReceivedEventArgs e)
		{
			MessageHeader header;
			Message message = Message.Create().Init(e.DataBuffer[0], e.Amount, out header);
			if (message.SendMode == MessageSendMode.Notify)
			{
				if (e.Amount >= 6)
				{
					e.FromConnection.ProcessNotify(e.DataBuffer, e.Amount, message);
				}
			}
			else if (message.SendMode == MessageSendMode.Unreliable)
			{
				if (e.Amount > 1)
				{
					Buffer.BlockCopy(e.DataBuffer, 1, message.Data, 1, e.Amount - 1);
				}
				messagesToHandle.Enqueue(new MessageToHandle(message, header, e.FromConnection));
				e.FromConnection.Metrics.ReceivedUnreliable(e.Amount);
			}
			else if (e.Amount >= 3)
			{
				e.FromConnection.Metrics.ReceivedReliable(e.Amount);
				if (e.FromConnection.ShouldHandle(Converter.UShortFromBits(e.DataBuffer, 4)))
				{
					Buffer.BlockCopy(e.DataBuffer, 1, message.Data, 1, e.Amount - 1);
					messagesToHandle.Enqueue(new MessageToHandle(message, header, e.FromConnection));
				}
				else
				{
					e.FromConnection.Metrics.ReliableDiscarded++;
				}
			}
		}

		protected abstract void Handle(Message message, MessageHeader header, Connection connection);

		internal abstract void Disconnect(Connection connection, DisconnectReason reason);

		protected static void IncreaseActiveCount()
		{
			ActiveCount++;
		}

		protected static void DecreaseActiveCount()
		{
			ActiveCount--;
			if (ActiveCount < 0)
			{
				ActiveCount = 0;
			}
		}
	}
	internal readonly struct MessageToHandle
	{
		internal readonly Message Message;

		internal readonly MessageHeader Header;

		internal readonly Connection FromConnection;

		public MessageToHandle(Message message, MessageHeader header, Connection fromConnection)
		{
			Message = message;
			Header = header;
			FromConnection = fromConnection;
		}
	}
	internal class PendingMessage
	{
		private const float RetryTimeMultiplier = 1.2f;

		private static readonly List<PendingMessage> pool = new List<PendingMessage>();

		private Connection connection;

		private readonly byte[] data;

		private int size;

		private byte sendAttempts;

		private bool wasCleared;

		internal long LastSendTime { get; private set; }

		internal PendingMessage()
		{
			data = new byte[Message.MaxSize];
		}

		internal static PendingMessage Create(ushort sequenceId, Message message, Connection connection)
		{
			PendingMessage pendingMessage = RetrieveFromPool();
			pendingMessage.connection = connection;
			message.SetBits(sequenceId, 16, 4);
			pendingMessage.size = message.BytesInUse;
			Buffer.BlockCopy(message.Data, 0, pendingMessage.data, 0, pendingMessage.size);
			pendingMessage.sendAttempts = 0;
			pendingMessage.wasCleared = false;
			return pendingMessage;
		}

		private static PendingMessage RetrieveFromPool()
		{
			PendingMessage result;
			if (pool.Count > 0)
			{
				result = pool[0];
				pool.RemoveAt(0);
			}
			else
			{
				result = new PendingMessage();
			}
			return result;
		}

		public static void ClearPool()
		{
			pool.Clear();
		}

		private void Release()
		{
			if (!pool.Contains(this))
			{
				pool.Add(this);
			}
		}

		internal void RetrySend()
		{
			if (!wasCleared)
			{
				long currentTime = connection.Peer.CurrentTime;
				if (LastSendTime + ((connection.SmoothRTT < 0) ? 25 : (connection.SmoothRTT / 2)) <= currentTime)
				{
					TrySend();
				}
				else
				{
					connection.Peer.ExecuteLater((connection.SmoothRTT < 0) ? 50 : ((long)Math.Max(10f, (float)connection.SmoothRTT * 1.2f)), new ResendEvent(this, currentTime));
				}
			}
		}

		internal void TrySend()
		{
			if (sendAttempts >= connection.MaxSendAttempts && connection.CanQualityDisconnect)
			{
				RiptideLogger.Log(LogType.Info, connection.Peer.LogName, $"Could not guarantee delivery of a {(MessageHeader)(data[0] & 0xFu)} message after {sendAttempts} attempts! Disconnecting...");
				connection.Peer.Disconnect(connection, DisconnectReason.PoorConnection);
				return;
			}
			connection.Send(data, size);
			connection.Metrics.SentReliable(size);
			LastSendTime = connection.Peer.CurrentTime;
			sendAttempts++;
			connection.Peer.ExecuteLater((connection.SmoothRTT < 0) ? 50 : ((long)Math.Max(10f, (float)connection.SmoothRTT * 1.2f)), new ResendEvent(this, connection.Peer.CurrentTime));
		}

		internal void Clear()
		{
			connection.Metrics.RollingReliableSends.Add((int)sendAttempts);
			wasCleared = true;
			Release();
		}
	}
	public class Server : Peer
	{
		public delegate void MessageHandler(ushort fromClientId, Message message);

		public delegate void ConnectionAttemptHandler(Connection pendingConnection, Message connectMessage);

		public ConnectionAttemptHandler HandleConnection;

		public MessageRelayFilter RelayFilter;

		private readonly List<Connection> pendingConnections;

		private Dictionary<ushort, Connection> clients;

		private readonly List<Connection> timedOutClients;

		private Dictionary<ushort, MessageHandler> messageHandlers;

		private IServer transport;

		private Queue<ushort> availableClientIds;

		public bool IsRunning { get; private set; }

		public ushort Port => transport.Port;

		public override int TimeoutTime
		{
			set
			{
				defaultTimeout = value;
				foreach (Connection value2 in clients.Values)
				{
					value2.TimeoutTime = defaultTimeout;
				}
			}
		}

		public ushort MaxClientCount { get; private set; }

		public int ClientCount => clients.Count;

		public Connection[] Clients => clients.Values.ToArray();

		public event EventHandler<ServerConnectedEventArgs> ClientConnected;

		public event EventHandler<ServerConnectionFailedEventArgs> ConnectionFailed;

		public event EventHandler<MessageReceivedEventArgs> MessageReceived;

		public event EventHandler<ServerDisconnectedEventArgs> ClientDisconnected;

		public Server(IServer transport, string logName = "SERVER")
			: base(logName)
		{
			this.transport = transport;
			pendingConnections = new List<Connection>();
			clients = new Dictionary<ushort, Connection>();
			timedOutClients = new List<Connection>();
		}

		public Server(string logName = "SERVER")
			: this(new UdpServer(), logName)
		{
		}

		public void ChangeTransport(IServer newTransport)
		{
			Stop();
			transport = newTransport;
		}

		public void Start(ushort port, ushort maxClientCount, byte messageHandlerGroupId = 0, bool useMessageHandlers = true)
		{
			Stop();
			Peer.IncreaseActiveCount();
			base.useMessageHandlers = useMessageHandlers;
			if (useMessageHandlers)
			{
				CreateMessageHandlersDictionary(messageHandlerGroupId);
			}
			MaxClientCount = maxClientCount;
			clients = new Dictionary<ushort, Connection>(maxClientCount);
			InitializeClientIds();
			SubToTransportEvents();
			transport.Start(port);
			StartTime();
			Heartbeat();
			IsRunning = true;
			RiptideLogger.Log(LogType.Info, LogName, $"Started on port {port}.");
		}

		private void SubToTransportEvents()
		{
			transport.Connected += HandleConnectionAttempt;
			transport.DataReceived += base.HandleData;
			transport.Disconnected += TransportDisconnected;
		}

		private void UnsubFromTransportEvents()
		{
			transport.Connected -= HandleConnectionAttempt;
			transport.DataReceived -= base.HandleData;
			transport.Disconnected -= TransportDisconnected;
		}

		protected override void CreateMessageHandlersDictionary(byte messageHandlerGroupId)
		{
			MethodInfo[] array = FindMessageHandlers();
			messageHandlers = new Dictionary<ushort, MessageHandler>(array.Length);
			MethodInfo[] array2 = array;
			foreach (MethodInfo methodInfo in array2)
			{
				MessageHandlerAttribute customAttribute = methodInfo.GetCustomAttribute<MessageHandlerAttribute>();
				if (customAttribute.GroupId != messageHandlerGroupId)
				{
					continue;
				}
				if (!methodInfo.IsStatic)
				{
					throw new NonStaticHandlerException(methodInfo.DeclaringType, methodInfo.Name);
				}
				Delegate @delegate = Delegate.CreateDelegate(typeof(MessageHandler), methodInfo, throwOnBindFailure: false);
				if ((object)@delegate != null)
				{
					if (messageHandlers.ContainsKey(customAttribute.MessageId))
					{
						MethodInfo methodInfo2 = messageHandlers[customAttribute.MessageId].GetMethodInfo();
						throw new DuplicateHandlerException(customAttribute.MessageId, methodInfo, methodInfo2);
					}
					messageHandlers.Add(customAttribute.MessageId, (MessageHandler)@delegate);
				}
				else if ((object)Delegate.CreateDelegate(typeof(Client.MessageHandler), methodInfo, throwOnBindFailure: false) == null)
				{
					throw new InvalidHandlerSignatureException(methodInfo.DeclaringType, methodInfo.Name);
				}
			}
		}

		private void HandleConnectionAttempt(object _, ConnectedEventArgs e)
		{
			e.Connection.Initialize(this, defaultTimeout);
		}

		private void HandleConnect(Connection connection, Message connectMessage)
		{
			connection.SetPending();
			if (HandleConnection == null)
			{
				AcceptConnection(connection);
			}
			else if (ClientCount < MaxClientCount)
			{
				if (!clients.ContainsValue(connection) && !pendingConnections.Contains(connection))
				{
					pendingConnections.Add(connection);
					Send(Message.Create(MessageHeader.Connect), connection);
					HandleConnection(connection, connectMessage);
				}
				else
				{
					Reject(connection, RejectReason.AlreadyConnected);
				}
			}
			else
			{
				Reject(connection, RejectReason.ServerFull);
			}
		}

		public void Accept(Connection connection)
		{
			if (pendingConnections.Remove(connection))
			{
				AcceptConnection(connection);
			}
			else
			{
				RiptideLogger.Log(LogType.Warning, LogName, $"Couldn't accept connection from {connection} because no such connection was pending!");
			}
		}

		public void Reject(Connection connection, Message message = null)
		{
			if (message != null && message.ReadBits != 0)
			{
				RiptideLogger.Log(LogType.Error, LogName, "Use the parameterless 'Message.Create()' overload when setting rejection data!");
			}
			if (pendingConnections.Remove(connection))
			{
				Reject(connection, (message == null) ? RejectReason.Rejected : RejectReason.Custom, message);
			}
			else
			{
				RiptideLogger.Log(LogType.Warning, LogName, $"Couldn't reject connection from {connection} because no such connection was pending!");
			}
		}

		private void AcceptConnection(Connection connection)
		{
			if (ClientCount < MaxClientCount)
			{
				if (!clients.ContainsValue(connection))
				{
					ushort key = (connection.Id = GetAvailableClientId());
					clients.Add(key, connection);
					connection.ResetTimeout();
					connection.SendWelcome();
				}
				else
				{
					Reject(connection, RejectReason.AlreadyConnected);
				}
			}
			else
			{
				Reject(connection, RejectReason.ServerFull);
			}
		}

		private void Reject(Connection connection, RejectReason reason, Message rejectMessage = null)
		{
			if (reason != RejectReason.AlreadyConnected)
			{
				Message message = Message.Create(MessageHeader.Reject);
				message.AddByte((byte)reason);
				if (reason == RejectReason.Custom)
				{
					message.AddMessage(rejectMessage);
				}
				for (int i = 0; i < 3; i++)
				{
					connection.Send(message, shouldRelease: false);
				}
				message.Release();
			}
			connection.ResetTimeout();
			connection.LocalDisconnect();
			RiptideLogger.Log(LogType.Info, LogName, $"Rejected connection from {connection}: {Helper.GetReasonString(reason)}.");
		}

		internal override void Heartbeat()
		{
			foreach (Connection value in clients.Values)
			{
				if (value.HasTimedOut)
				{
					timedOutClients.Add(value);
				}
			}
			foreach (Connection pendingConnection in pendingConnections)
			{
				if (pendingConnection.HasConnectAttemptTimedOut)
				{
					timedOutClients.Add(pendingConnection);
				}
			}
			foreach (Connection timedOutClient in timedOutClients)
			{
				LocalDisconnect(timedOutClient, DisconnectReason.TimedOut);
			}
			timedOutClients.Clear();
			ExecuteLater(base.HeartbeatInterval, new HeartbeatEvent(this));
		}

		public override void Update()
		{
			base.Update();
			transport.Poll();
			HandleMessages();
		}

		protected override void Handle(Message message, MessageHeader header, Connection connection)
		{
			switch (header)
			{
			case MessageHeader.Unreliable:
			case MessageHeader.Reliable:
				OnMessageReceived(message, connection);
				break;
			case MessageHeader.Ack:
				connection.HandleAck(message);
				break;
			case MessageHeader.Connect:
				HandleConnect(connection, message);
				break;
			case MessageHeader.Heartbeat:
				connection.HandleHeartbeat(message);
				break;
			case MessageHeader.Disconnect:
				LocalDisconnect(connection, DisconnectReason.Disconnected);
				break;
			case MessageHeader.Welcome:
				if (connection.HandleWelcomeResponse(message))
				{
					OnClientConnected(connection);
				}
				break;
			default:
				RiptideLogger.Log(LogType.Warning, LogName, $"Unexpected message header '{header}'! Discarding {message.BytesInUse} bytes received from {connection}.");
				break;
			}
			message.Release();
		}

		public void Send(Message message, ushort toClient, bool shouldRelease = true)
		{
			if (clients.TryGetValue(toClient, out var value))
			{
				Send(message, value, shouldRelease);
			}
		}

		public ushort Send(Message message, Connection toClient, bool shouldRelease = true)
		{
			return toClient.Send(message, shouldRelease);
		}

		public void SendToAll(Message message, bool shouldRelease = true)
		{
			foreach (Connection value in clients.Values)
			{
				value.Send(message, shouldRelease: false);
			}
			if (shouldRelease)
			{
				message.Release();
			}
		}

		public void SendToAll(Message message, ushort exceptToClientId, bool shouldRelease = true)
		{
			foreach (Connection value in clients.Values)
			{
				if (value.Id != exceptToClientId)
				{
					value.Send(message, shouldRelease: false);
				}
			}
			if (shouldRelease)
			{
				message.Release();
			}
		}

		public bool TryGetClient(ushort id, out Connection client)
		{
			return clients.TryGetValue(id, out client);
		}

		public void DisconnectClient(ushort id, Message message = null)
		{
			if (message != null && message.ReadBits != 0)
			{
				RiptideLogger.Log(LogType.Error, LogName, "Use the parameterless 'Message.Create()' overload when setting disconnection data!");
			}
			if (clients.TryGetValue(id, out var value))
			{
				SendDisconnect(value, DisconnectReason.Kicked, message);
				LocalDisconnect(value, DisconnectReason.Kicked);
			}
			else
			{
				RiptideLogger.Log(LogType.Warning, LogName, $"Couldn't disconnect client {id} because it wasn't connected!");
			}
		}

		public void DisconnectClient(Connection client, Message message = null)
		{
			if (message != null && message.ReadBits != 0)
			{
				RiptideLogger.Log(LogType.Error, LogName, "Use the parameterless 'Message.Create()' overload when setting disconnection data!");
			}
			if (clients.ContainsKey(client.Id))
			{
				SendDisconnect(client, DisconnectReason.Kicked, message);
				LocalDisconnect(client, DisconnectReason.Kicked);
			}
			else
			{
				RiptideLogger.Log(LogType.Warning, LogName, $"Couldn't disconnect client {client.Id} because it wasn't connected!");
			}
		}

		internal override void Disconnect(Connection connection, DisconnectReason reason)
		{
			if (connection.IsConnected && connection.CanQualityDisconnect)
			{
				LocalDisconnect(connection, reason);
			}
		}

		private void LocalDisconnect(Connection client, DisconnectReason reason)
		{
			if (client.Peer == this)
			{
				transport.Close(client);
				if (clients.Remove(client.Id))
				{
					availableClientIds.Enqueue(client.Id);
				}
				if (client.IsConnected)
				{
					OnClientDisconnected(client, reason);
				}
				else if (client.IsPending)
				{
					OnConnectionFailed(client);
				}
				client.LocalDisconnect();
			}
		}

		private void TransportDisconnected(object sender, Riptide.Transports.DisconnectedEventArgs e)
		{
			LocalDisconnect(e.Connection, e.Reason);
		}

		public void Stop()
		{
			if (!IsRunning)
			{
				return;
			}
			pendingConnections.Clear();
			byte[] array = new byte[2] { 5, 5 };
			foreach (Connection value in clients.Values)
			{
				value.Send(array, array.Length);
			}
			clients.Clear();
			transport.Shutdown();
			UnsubFromTransportEvents();
			Peer.DecreaseActiveCount();
			StopTime();
			IsRunning = false;
			RiptideLogger.Log(LogType.Info, LogName, "Server stopped.");
		}

		private void InitializeClientIds()
		{
			if (MaxClientCount > 65534)
			{
				throw new Exception($"A server's max client count may not exceed {65534}!");
			}
			availableClientIds = new Queue<ushort>(MaxClientCount);
			for (ushort num = 1; num <= MaxClientCount; num++)
			{
				availableClientIds.Enqueue(num);
			}
		}

		private ushort GetAvailableClientId()
		{
			if (availableClientIds.Count > 0)
			{
				return availableClientIds.Dequeue();
			}
			RiptideLogger.Log(LogType.Error, LogName, "No available client IDs, assigned 0!");
			return 0;
		}

		private void SendDisconnect(Connection client, DisconnectReason reason, Message disconnectMessage)
		{
			Message message = Message.Create(MessageHeader.Disconnect);
			message.AddByte((byte)reason);
			if (reason == DisconnectReason.Kicked && disconnectMessage != null)
			{
				message.AddMessage(disconnectMessage);
			}
			Send(message, client);
		}

		private void SendClientConnected(Connection newClient)
		{
			Message message = Message.Create(MessageHeader.ClientConnected);
			message.AddUShort(newClient.Id);
			SendToAll(message, newClient.Id);
		}

		private void SendClientDisconnected(ushort id)
		{
			Message message = Message.Create(MessageHeader.ClientDisconnected);
			message.AddUShort(id);
			SendToAll(message);
		}

		protected virtual void OnClientConnected(Connection client)
		{
			RiptideLogger.Log(LogType.Info, LogName, $"Client {client.Id} ({client}) connected successfully!");
			SendClientConnected(client);
			this.ClientConnected?.Invoke(this, new ServerConnectedEventArgs(client));
		}

		protected virtual void OnConnectionFailed(Connection connection)
		{
			RiptideLogger.Log(LogType.Info, LogName, $"Client {connection} stopped responding before the connection was fully established!");
			this.ConnectionFailed?.Invoke(this, new ServerConnectionFailedEventArgs(connection));
		}

		protected virtual void OnMessageReceived(Message message, Connection fromConnection)
		{
			ushort num = (ushort)message.GetVarULong();
			if (RelayFilter != null && RelayFilter.ShouldRelay(num))
			{
				SendToAll(message, fromConnection.Id);
				return;
			}
			this.MessageReceived?.Invoke(this, new MessageReceivedEventArgs(fromConnection, num, message));
			if (useMessageHandlers)
			{
				if (messageHandlers.TryGetValue(num, out var value))
				{
					value(fromConnection.Id, message);
				}
				else
				{
					RiptideLogger.Log(LogType.Warning, LogName, $"No message handler method found for message ID {num}!");
				}
			}
		}

		protected virtual void OnClientDisconnected(Connection connection, DisconnectReason reason)
		{
			RiptideLogger.Log(LogType.Info, LogName, $"Client {connection.Id} ({connection}) disconnected: {Helper.GetReasonString(reason)}.");
			SendClientDisconnected(connection.Id);
			this.ClientDisconnected?.Invoke(this, new ServerDisconnectedEventArgs(connection, reason));
		}
	}
}
namespace Riptide.Utils
{
	internal class Bitfield
	{
		private const int SegmentSize = 32;

		private readonly List<uint> segments;

		private readonly bool isDynamicCapacity;

		private int count;

		private int capacity;

		internal byte First8 => (byte)segments[0];

		internal ushort First16 => (ushort)segments[0];

		internal Bitfield(bool isDynamicCapacity = true)
		{
			segments = new List<uint>(4) { 0u };
			capacity = segments.Count * 32;
			this.isDynamicCapacity = isDynamicCapacity;
		}

		internal bool HasCapacityFor(int amount, out int overflow)
		{
			overflow = count + amount - capacity;
			return overflow < 0;
		}

		internal void ShiftBy(int amount)
		{
			int num = amount / 32;
			int num2 = amount % 32;
			int overflow;
			if (!isDynamicCapacity)
			{
				count = Math.Min(count + amount, 32);
			}
			else if (!HasCapacityFor(amount, out overflow))
			{
				Trim();
				count += amount;
				if (count > capacity)
				{
					int num3 = num + 1;
					for (int i = 0; i < num3; i++)
					{
						segments.Add(0u);
					}
					capacity = segments.Count * 32;
				}
			}
			else
			{
				count += amount;
			}
			int num4 = segments.Count - 1;
			segments[num4] <<= num2;
			for (num4 -= 1 + num; num4 > -1; num4--)
			{
				ulong num5 = (ulong)segments[num4] << num2;
				segments[num4] = (uint)num5;
				segments[num4 + 1 + num] |= (uint)(int)(num5 >> 32);
			}
		}

		internal bool CheckAndTrimLast(out int checkedPosition)
		{
			checkedPosition = count;
			uint num = (uint)(1 << (count - 1) % 32);
			bool result = (segments[segments.Count - 1] & num) != 0;
			count--;
			return result;
		}

		private void Trim()
		{
			while (count > 0 && IsSet(count))
			{
				count--;
			}
		}

		internal void Set(int bit)
		{
			if (bit < 1)
			{
				throw new ArgumentOutOfRangeException("bit", "'bit' must be greater than zero!");
			}
			bit--;
			int num = bit / 32;
			uint num2 = (uint)(1 << bit % 32);
			if (num < segments.Count)
			{
				segments[num] |= num2;
			}
		}

		internal bool IsSet(int bit)
		{
			if (bit > count)
			{
				return true;
			}
			if (bit < 1)
			{
				throw new ArgumentOutOfRangeException("bit", "'bit' must be greater than zero!");
			}
			bit--;
			int num = bit / 32;
			uint num2 = (uint)(1 << bit % 32);
			if (num < segments.Count)
			{
				return (segments[num] & num2) != 0;
			}
			return true;
		}

		internal void Combine(ushort other)
		{
			segments[0] |= other;
		}
	}
	public class ConnectionMetrics
	{
		public readonly RollingStat RollingReliableSends;

		private const ulong ULongLeftBit = 9223372036854775808uL;

		private ulong notifyLossTracker;

		private int notifyBufferCount;

		public int BytesIn => UnreliableBytesIn + NotifyBytesIn + ReliableBytesIn;

		public int BytesOut => UnreliableBytesOut + NotifyBytesOut + ReliableBytesOut;

		public int MessagesIn => UnreliableIn + NotifyIn + ReliableIn;

		public int MessagesOut => UnreliableOut + NotifyOut + ReliableOut;

		public int UnreliableBytesIn { get; private set; }

		public int UnreliableBytesOut { get; internal set; }

		public int UnreliableIn { get; private set; }

		public int UnreliableOut { get; internal set; }

		public int NotifyBytesIn { get; private set; }

		public int NotifyBytesOut { get; internal set; }

		public int NotifyIn { get; private set; }

		public int NotifyOut { get; internal set; }

		public int NotifyDiscarded { get; internal set; }

		public int NotifyLost { get; private set; }

		public int NotifyDelivered { get; private set; }

		public int RollingNotifyLost { get; private set; }

		public int RollingNotifyDelivered { get; private set; }

		public float RollingNotifyLossRate => (float)RollingNotifyLost / 64f;

		public int ReliableBytesIn { get; private set; }

		publi