Decompiled source of DiscordRichPresence v1.2.1

Cuno-DiscordRichPresence-1.2.1/DiscordRichPresence.dll

Decompiled 2 months 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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DiscordRPC;
using DiscordRPC.Events;
using DiscordRPC.IO;
using DiscordRPC.Logging;
using DiscordRPC.Message;
using DiscordRPC.Unity;
using DiscordRichPresence.Hooks;
using DiscordRichPresence.Utils;
using Epic.OnlineServices;
using Epic.OnlineServices.Lobby;
using Facepunch.Steamworks;
using Lachee.IO;
using Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.UI.MainMenu;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.Options;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("DiscordRichPresence")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a2e8600d5beff9c3044c98e2f0d9d1d6a8693463")]
[assembly: AssemblyProduct("DiscordRichPresence")]
[assembly: AssemblyTitle("DiscordRichPresence")]
[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;
		}
	}
}
namespace DiscordRPC.Unity
{
	public class UnityNamedPipe : INamedPipeClient, IDisposable
	{
		private const string PIPE_NAME = "discord-ipc-{0}";

		private NamedPipeClientStream _stream;

		private readonly byte[] _buffer = new byte[PipeFrame.MAX_SIZE];

		private volatile bool _isDisposed;

		public ILogger Logger { get; set; }

		public bool IsConnected => _stream != null && _stream.IsConnected;

		public int ConnectedPipe { get; private set; }

		public bool Connect(int pipe)
		{
			if (_isDisposed)
			{
				throw new ObjectDisposedException("NamedPipe");
			}
			if (pipe > 9)
			{
				throw new ArgumentOutOfRangeException("pipe", "Argument cannot be greater than 9");
			}
			if (pipe < 0)
			{
				for (int i = 0; i < 10; i++)
				{
					if (AttemptConnection(i) || AttemptConnection(i, doSandbox: true))
					{
						return true;
					}
				}
				return false;
			}
			return AttemptConnection(pipe) || AttemptConnection(pipe, doSandbox: true);
		}

		private bool AttemptConnection(int pipe, bool doSandbox = false)
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			if (_stream != null)
			{
				Logger.Error("Attempted to create a new stream while one already exists!", Array.Empty<object>());
				return false;
			}
			if (IsConnected)
			{
				Logger.Error("Attempted to create a new connection while one already exists!", Array.Empty<object>());
				return false;
			}
			try
			{
				string text = (doSandbox ? GetPipeSandbox() : "");
				if (doSandbox && text == null)
				{
					Logger.Trace("Skipping sandbox because this platform does not support it", Array.Empty<object>());
					return false;
				}
				string pipeName = GetPipeName(pipe);
				Logger.Info("Connecting to " + pipeName + " (" + text + ")", Array.Empty<object>());
				ConnectedPipe = pipe;
				_stream = new NamedPipeClientStream(".", pipeName);
				_stream.Connect();
				Logger.Info("Connected", Array.Empty<object>());
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed: " + ex.GetType().FullName + ", " + ex.Message, Array.Empty<object>());
				ConnectedPipe = -1;
				Close();
				return false;
			}
		}

		public void Close()
		{
			if (_stream != null)
			{
				Logger.Trace("Closing stream", Array.Empty<object>());
				((Stream)(object)_stream).Dispose();
				_stream = null;
			}
		}

		public void Dispose()
		{
			if (!_isDisposed)
			{
				Logger.Trace("Disposing stream", Array.Empty<object>());
				_isDisposed = true;
				Close();
			}
		}

		public bool ReadFrame(out PipeFrame frame)
		{
			//IL_0028: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (_isDisposed)
			{
				throw new ObjectDisposedException("_stream");
			}
			if (!IsConnected)
			{
				frame = default(PipeFrame);
				return false;
			}
			int num = ((Stream)(object)_stream).Read(_buffer, 0, _buffer.Length);
			Logger.Trace("Read {0} bytes", new object[1] { num });
			if (num == 0)
			{
				frame = default(PipeFrame);
				return false;
			}
			using MemoryStream memoryStream = new MemoryStream(_buffer, 0, num);
			frame = default(PipeFrame);
			if (!((PipeFrame)(ref frame)).ReadStream((Stream)memoryStream))
			{
				Logger.Error("Failed to read a frame! {0}", new object[1] { ((PipeFrame)(ref frame)).Opcode });
				return false;
			}
			Logger.Trace("Read pipe frame!", Array.Empty<object>());
			return true;
		}

		public bool WriteFrame(PipeFrame frame)
		{
			if (_isDisposed)
			{
				throw new ObjectDisposedException("_stream");
			}
			if (!IsConnected)
			{
				Logger.Error("Failed to write frame because the stream is closed", Array.Empty<object>());
				return false;
			}
			try
			{
				Logger.Trace("Writing frame", Array.Empty<object>());
				((PipeFrame)(ref frame)).WriteStream((Stream)(object)_stream);
				return true;
			}
			catch (IOException ex)
			{
				Logger.Error("Failed to write frame due to IOException: {0}", new object[1] { ex.Message });
			}
			catch (ObjectDisposedException)
			{
				Logger.Warning("Failed to write frame as the stream was already disposed", Array.Empty<object>());
			}
			catch (InvalidOperationException)
			{
				Logger.Warning("Failed to write frame because of an invalid operation", Array.Empty<object>());
			}
			return false;
		}

		private string GetPipeName(int pipe, string sandbox = "")
		{
			switch (Environment.OSVersion.Platform)
			{
			default:
				Logger.Trace("PIPE WIN", Array.Empty<object>());
				return sandbox + $"discord-ipc-{pipe}";
			case PlatformID.Unix:
			case PlatformID.MacOSX:
				Logger.Trace("PIPE UNIX / MACOSX", Array.Empty<object>());
				return Path.Combine(GetEnviromentTemp(), sandbox + $"discord-ipc-{pipe}");
			}
		}

		private string GetPipeSandbox()
		{
			PlatformID platform = Environment.OSVersion.Platform;
			PlatformID platformID = platform;
			if (platformID != PlatformID.Unix)
			{
				return null;
			}
			return "snap.discord/";
		}

		private string GetEnviromentTemp()
		{
			string text = null;
			text = text ?? Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR");
			text = text ?? Environment.GetEnvironmentVariable("TMPDIR");
			text = text ?? Environment.GetEnvironmentVariable("TMP");
			text = text ?? Environment.GetEnvironmentVariable("TEMP");
			return text ?? "/tmp";
		}
	}
}
namespace DiscordRichPresence
{
	[BepInPlugin("com.cuno.discord", "Discord Rich Presence", "1.2.1")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DiscordRichPresencePlugin : BaseUnityPlugin
	{
		internal static ManualLogSource LoggerEXT { get; private set; }

		public static DiscordRpcClient Client { get; set; }

		public static RichPresence RichPresence { get; set; }

		public static DiscordRichPresencePlugin Instance { get; private set; }

		public static SceneDef CurrentScene => SceneCatalog.GetSceneDefForCurrentScene();

		public static float CurrentChargeLevel { get; set; }

		public static float MoonCountdownTimer { get; set; }

		public static string CurrentBoss { get; set; }

		public static bool IsInEOSLobby => EOSLobbyManager.GetFromPlatformSystems() != null && ((LobbyManager)EOSLobbyManager.GetFromPlatformSystems()).isInLobby;

		public void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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)
			//IL_006c: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_008a: Expected O, but got Unknown
			Instance = this;
			LoggerEXT = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Starting Discord Rich Presence...");
			UnityNamedPipe unityNamedPipe = new UnityNamedPipe();
			Client = new DiscordRpcClient("992086428240580720", -1, (ILogger)null, true, (INamedPipeClient)(object)unityNamedPipe);
			Client.RegisterUriScheme("632360", (string)null);
			RichPresence = new RichPresence
			{
				State = "Starting game...",
				Assets = new Assets(),
				Secrets = new Secrets(),
				Timestamps = new Timestamps()
			};
			Client.SetPresence(RichPresence);
			Client.Initialize();
			PluginConfig.AllowJoiningEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "Allow Joining", true, "Controls whether or not other users should be allowed to ask to join your game.");
			PluginConfig.TeleporterStatusEntry = ((BaseUnityPlugin)this).Config.Bind<PluginConfig.TeleporterStatus>("Options", "Teleporter Status", PluginConfig.TeleporterStatus.None, "Controls whether the teleporter boss, teleporter charge status, or neither, should be shown alongside the current difficulty.");
			PluginConfig.MainMenuIdleMessageEntry = ((BaseUnityPlugin)this).Config.Bind<string>("Options", "Main Menu Idle Message", "", "Allows you to choose a message to be displayed when idling in the main menu.");
			if (RiskOfOptionsUtils.IsEnabled)
			{
				RiskOfOptionsUtils.SetModDescription("Adds Discord Rich Presence functionality to Risk of Rain 2");
				RiskOfOptionsUtils.AddCheckBoxOption(PluginConfig.AllowJoiningEntry);
				RiskOfOptionsUtils.AddMultiOption<PluginConfig.TeleporterStatus>(PluginConfig.TeleporterStatusEntry);
				RiskOfOptionsUtils.AddTextInputOption(PluginConfig.MainMenuIdleMessageEntry);
			}
		}

		private static void InitializeHooks()
		{
			DiscordClientHooks.AddHooks(Client);
			PauseManagerHooks.AddHooks();
			SteamworksLobbyHooks.AddHooks();
			RoR2Hooks.AddHooks();
			SceneManager.activeSceneChanged += SceneManager_activeSceneChanged;
			Stage.onServerStageBegin += Stage_onServerStageBegin;
		}

		public static void Dispose()
		{
			DiscordClientHooks.RemoveHooks(Client);
			PauseManagerHooks.RemoveHooks();
			SteamworksLobbyHooks.RemoveHooks();
			RoR2Hooks.RemoveHooks();
			if (((object)(UserID)(ref EOSLoginManager.loggedInUserID)).ToString() != string.Empty)
			{
				EOSLobbyHooks.RemoveHooks();
			}
			SceneManager.activeSceneChanged -= SceneManager_activeSceneChanged;
			Stage.onServerStageBegin -= Stage_onServerStageBegin;
			Client.Dispose();
		}

		public void OnEnable()
		{
			InitializeHooks();
		}

		public void OnDisable()
		{
			Dispose();
		}

		private static void SceneManager_activeSceneChanged(Scene arg0, Scene arg1)
		{
			if (Client != null && Client.IsInitialized)
			{
				CurrentBoss = "";
				CurrentChargeLevel = 0f;
				MoonCountdownTimer = 0f;
				EOSLobbyManager fromPlatformSystems = EOSLobbyManager.GetFromPlatformSystems();
				if (((Scene)(ref arg1)).name == "title" && Client.Instance.Lobby.IsValid)
				{
					PresenceUtils.SetLobbyPresence(Client, RichPresence, Client.Instance);
				}
				else if (((Scene)(ref arg1)).name == "title" && IsInEOSLobby)
				{
					PresenceUtils.SetLobbyPresence(Client, RichPresence, fromPlatformSystems);
				}
				if (((Scene)(ref arg1)).name == "lobby" && !Client.Instance.Lobby.IsValid && !IsInEOSLobby)
				{
					PresenceUtils.SetMainMenuPresence(Client, RichPresence, "Choosing Character");
				}
				else if (((Scene)(ref arg1)).name == "lobby" && Client.Instance.Lobby.IsValid)
				{
					PresenceUtils.SetLobbyPresence(Client, RichPresence, Client.Instance, justParty: false, "Choosing Character");
				}
				else if (((Scene)(ref arg1)).name == "lobby" && IsInEOSLobby)
				{
					PresenceUtils.SetLobbyPresence(Client, RichPresence, fromPlatformSystems, justParty: false, "Choosing Character");
				}
				if (((Scene)(ref arg1)).name == "logbook")
				{
					PresenceUtils.SetMainMenuPresence(Client, RichPresence, "Reading Logbook");
				}
				else if ((Object)(object)Run.instance != (Object)null && (Object)(object)CurrentScene != (Object)null && (Client.Instance.Lobby.IsValid || IsInEOSLobby))
				{
					LoggerEXT.LogInfo((object)("Scene Manager Active Scene Changed Called With Value: " + (Run.instance.stageClearCount + 1)));
					PresenceUtils.SetStagePresence(Client, RichPresence, CurrentScene, Run.instance);
				}
			}
		}

		private static void Stage_onServerStageBegin(Stage obj)
		{
			CurrentChargeLevel = 0f;
			if ((Object)(object)CurrentScene != (Object)null && (Object)(object)Run.instance != (Object)null)
			{
				PresenceUtils.SetStagePresence(Client, RichPresence, CurrentScene, Run.instance);
			}
		}
	}
	public static class PluginConfig
	{
		public enum TeleporterStatus : byte
		{
			None,
			Boss,
			Charge
		}

		public static ConfigEntry<bool> AllowJoiningEntry { get; set; }

		public static ConfigEntry<TeleporterStatus> TeleporterStatusEntry { get; set; }

		public static ConfigEntry<string> MainMenuIdleMessageEntry { get; set; }
	}
}
namespace DiscordRichPresence.Utils
{
	public static class InfoTextUtils
	{
		public enum StyleTag : byte
		{
			Damage = 1,
			Healing,
			Utility,
			Health,
			Stack,
			Mono,
			Death,
			UserSetting,
			Artifact,
			Sub,
			Event,
			WorldEvent,
			KeywordName,
			Shrine
		}

		public static List<string> CharactersWithAssets = new List<string>
		{
			"Acrid", "Artificer", "Bandit", "Captain", "Commando", "Engineer", "Heretic", "Huntress", "Loader", "MUL-T",
			"Mercenary", "REX", "Railgunner", "Enforcer", "CHEF", "Miner", "Paladin", "HAN-D", "Sniper", "Bomber",
			"Nemesis Enforcer", "Nemesis Commando", "Chirr", "Executioner", "An Arbiter", "Red Mist"
		};

		public static string GetCharacterInternalName(string name)
		{
			if (name == "「V??oid Fiend』")
			{
				return "voidfiend";
			}
			if (CharactersWithAssets.Contains(name))
			{
				return CharactersWithAssets.Find((string c) => c == name).ToLower().Replace(" ", "");
			}
			return "unknown";
		}

		public static string FormatTextStyleTag(string content, StyleTag styleTag)
		{
			string text = (((int)styleTag < 1 || (int)styleTag > 4) ? ("c" + styleTag) : ("cIs" + styleTag));
			return "<style=" + text + ">" + content + "</style>";
		}
	}
	public static class PresenceUtils
	{
		public static void SetStagePresence(DiscordRpcClient client, RichPresence richPresence, SceneDef scene, Run run, bool isPaused = false)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Invalid comparison between Unknown and I4
			if ((Object)(object)Run.instance == (Object)null)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogError((object)"Run instance is null. Check for its null status before passing it as a parameter. Stack trace follows:");
			}
			if ((Object)(object)scene == (Object)null)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogError((object)"Scene is null. Check for its null status before passing it as a parameter. Stack trace follows:");
			}
			((BaseRichPresence)richPresence).Assets.LargeImageKey = scene.baseSceneName;
			((BaseRichPresence)richPresence).Assets.LargeImageText = "DiscordRichPresence v" + ((BaseUnityPlugin)DiscordRichPresencePlugin.Instance).Info.Metadata.Version;
			((BaseRichPresence)richPresence).State = $"Stage {run.stageClearCount + 1} - {Language.GetString(scene.nameToken)}";
			InfiniteTowerRun val = (InfiniteTowerRun)(object)((run is InfiniteTowerRun) ? run : null);
			if (val != null && val.waveIndex > 0)
			{
				((BaseRichPresence)richPresence).State = $"Wave {val.waveIndex} - {Language.GetString(scene.nameToken)}";
			}
			string @string = Language.GetString(DifficultyCatalog.GetDifficultyDef(run.selectedDifficulty).nameToken);
			((BaseRichPresence)richPresence).Timestamps = new Timestamps();
			((BaseRichPresence)richPresence).Secrets = new Secrets();
			if (scene.baseSceneName == "outro")
			{
				DiscordRichPresencePlugin.MoonCountdownTimer = 0f;
				((BaseRichPresence)richPresence).Assets.LargeImageKey = "moon2";
				((BaseRichPresence)richPresence).Details = "Credits";
				((BaseRichPresence)richPresence).State = $"Stage {run.stageClearCount + 1} - {Language.GetString(scene.nameToken)}";
			}
			else if (DiscordRichPresencePlugin.MoonCountdownTimer > 0f)
			{
				((BaseRichPresence)richPresence).Details = "Escaping! | " + @string;
				if (!isPaused)
				{
					((BaseRichPresence)richPresence).Timestamps.EndUnixMilliseconds = (ulong)DateTimeOffset.Now.ToUnixTimeSeconds() + (ulong)DiscordRichPresencePlugin.MoonCountdownTimer;
				}
			}
			else
			{
				((BaseRichPresence)richPresence).Details = @string;
				if (PluginConfig.TeleporterStatusEntry.Value == PluginConfig.TeleporterStatus.Boss && DiscordRichPresencePlugin.CurrentBoss != "")
				{
					((BaseRichPresence)richPresence).Details = "Fighting " + DiscordRichPresencePlugin.CurrentBoss + " | " + @string;
				}
				else if (PluginConfig.TeleporterStatusEntry.Value == PluginConfig.TeleporterStatus.Charge && DiscordRichPresencePlugin.CurrentChargeLevel > 0f)
				{
					((BaseRichPresence)richPresence).Details = "Charging teleporter (" + DiscordRichPresencePlugin.CurrentChargeLevel * 100f + "%) | " + @string;
				}
				if ((int)scene.sceneType == 1 && !isPaused)
				{
					((BaseRichPresence)richPresence).Timestamps.StartUnixMilliseconds = (ulong)DateTimeOffset.Now.ToUnixTimeSeconds() - (ulong)run.GetRunStopwatch();
				}
			}
			DiscordRichPresencePlugin.RichPresence = richPresence;
			client.SetPresence(richPresence);
		}

		public static void SetMainMenuPresence(DiscordRpcClient client, RichPresence richPresence, string details = "")
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			((BaseRichPresence)richPresence).Assets = new Assets
			{
				LargeImageKey = "riskofrain2",
				LargeImageText = "DiscordRichPresence v" + ((BaseUnityPlugin)DiscordRichPresencePlugin.Instance).Info.Metadata.Version
			};
			((BaseRichPresence)richPresence).Details = PluginConfig.MainMenuIdleMessageEntry.Value;
			if (details != "")
			{
				((BaseRichPresence)richPresence).Details = details;
			}
			((BaseRichPresence)richPresence).Timestamps = new Timestamps();
			((BaseRichPresence)richPresence).State = "In Menu";
			((BaseRichPresence)richPresence).Secrets = new Secrets();
			((BaseRichPresence)richPresence).Party = new Party();
			DiscordRichPresencePlugin.RichPresence = richPresence;
			client.SetPresence(richPresence);
		}

		public static void SetLobbyPresence(DiscordRpcClient client, RichPresence richPresence, Client faceClient, bool justParty = false, string details = "")
		{
			//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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			if (!justParty)
			{
				((BaseRichPresence)richPresence).State = "In Lobby";
				((BaseRichPresence)richPresence).Details = "Preparing";
				if (details != "")
				{
					((BaseRichPresence)richPresence).Details = details;
				}
				((BaseRichPresence)richPresence).Assets = new Assets
				{
					LargeImageKey = "riskofrain2",
					LargeImageText = "DiscordRichPresence v" + ((BaseUnityPlugin)DiscordRichPresencePlugin.Instance).Info.Metadata.Version
				};
				((BaseRichPresence)richPresence).Timestamps = new Timestamps();
			}
			richPresence = UpdateParty(richPresence, faceClient);
			DiscordRichPresencePlugin.RichPresence = richPresence;
			client.SetPresence(richPresence);
		}

		public static void SetLobbyPresence(DiscordRpcClient client, RichPresence richPresence, EOSLobbyManager lobbyManager, bool justParty = false, string details = "")
		{
			//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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			if (!justParty)
			{
				((BaseRichPresence)richPresence).State = "In Lobby";
				((BaseRichPresence)richPresence).Details = "Preparing";
				if (details != "")
				{
					((BaseRichPresence)richPresence).Details = details;
				}
				((BaseRichPresence)richPresence).Assets = new Assets
				{
					LargeImageKey = "riskofrain2",
					LargeImageText = "DiscordRichPresence v" + ((BaseUnityPlugin)DiscordRichPresencePlugin.Instance).Info.Metadata.Version
				};
				((BaseRichPresence)richPresence).Timestamps = new Timestamps();
			}
			richPresence = UpdateParty(richPresence, lobbyManager);
			DiscordRichPresencePlugin.RichPresence = richPresence;
			client.SetPresence(richPresence);
		}

		public static RichPresence UpdateParty(RichPresence richPresence, Client faceClient, bool includeJoinButton = true)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			((BaseRichPresence)richPresence).Party.ID = faceClient.Username;
			((BaseRichPresence)richPresence).Party.Max = faceClient.Lobby.MaxMembers;
			((BaseRichPresence)richPresence).Party.Size = faceClient.Lobby.NumMembers;
			((BaseRichPresence)richPresence).Secrets = new Secrets();
			if (PluginConfig.AllowJoiningEntry.Value && includeJoinButton)
			{
				((BaseRichPresence)richPresence).Secrets.JoinSecret = faceClient.Lobby.CurrentLobby.ToString();
			}
			return richPresence;
		}

		public static RichPresence UpdateParty(RichPresence richPresence, EOSLobbyManager lobbyManager, bool includeJoinButton = true)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			((BaseRichPresence)richPresence).Party.ID = lobbyManager.CurrentLobbyId;
			((BaseRichPresence)richPresence).Party.Max = ((LobbyManager)lobbyManager).newestLobbyData.totalMaxPlayers;
			((BaseRichPresence)richPresence).Party.Size = ((LobbyManager)lobbyManager).newestLobbyData.totalPlayerCount;
			((BaseRichPresence)richPresence).Secrets = new Secrets();
			if (PluginConfig.AllowJoiningEntry.Value && includeJoinButton)
			{
				((BaseRichPresence)richPresence).Secrets.JoinSecret = ((object)(UserID)(ref ((LobbyManager)lobbyManager).GetLobbyMembers()[0])).ToString();
			}
			return richPresence;
		}
	}
	public static class RiskOfOptionsUtils
	{
		public static bool IsEnabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		public static void AddCheckBoxOption(ConfigEntry<bool> entry)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(entry));
		}

		public static void AddMultiOption<T>(ConfigEntry<T> entry) where T : Enum
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)entry));
		}

		public static void AddTextInputOption(ConfigEntry<string> entry)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(entry));
		}

		public static void SetModDescription(string description)
		{
			ModSettingsManager.SetModDescription(description);
		}
	}
}
namespace DiscordRichPresence.Hooks
{
	public static class DiscordClientHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static OnReadyEvent <0>__Client_OnReady;

			public static OnErrorEvent <1>__Client_OnError;

			public static OnJoinRequestedEvent <2>__Client_OnJoinRequested;

			public static OnJoinEvent <3>__Client_OnJoin;
		}

		public static void AddHooks(DiscordRpcClient client)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			client.Subscribe((EventType)2);
			client.Subscribe((EventType)4);
			object obj = <>O.<0>__Client_OnReady;
			if (obj == null)
			{
				OnReadyEvent val = Client_OnReady;
				<>O.<0>__Client_OnReady = val;
				obj = (object)val;
			}
			client.OnReady += (OnReadyEvent)obj;
			object obj2 = <>O.<1>__Client_OnError;
			if (obj2 == null)
			{
				OnErrorEvent val2 = Client_OnError;
				<>O.<1>__Client_OnError = val2;
				obj2 = (object)val2;
			}
			client.OnError += (OnErrorEvent)obj2;
			object obj3 = <>O.<2>__Client_OnJoinRequested;
			if (obj3 == null)
			{
				OnJoinRequestedEvent val3 = Client_OnJoinRequested;
				<>O.<2>__Client_OnJoinRequested = val3;
				obj3 = (object)val3;
			}
			client.OnJoinRequested += (OnJoinRequestedEvent)obj3;
			object obj4 = <>O.<3>__Client_OnJoin;
			if (obj4 == null)
			{
				OnJoinEvent val4 = Client_OnJoin;
				<>O.<3>__Client_OnJoin = val4;
				obj4 = (object)val4;
			}
			client.OnJoin += (OnJoinEvent)obj4;
		}

		public static void RemoveHooks(DiscordRpcClient client)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			client.Unsubscribe((EventType)2);
			client.Unsubscribe((EventType)4);
			object obj = <>O.<0>__Client_OnReady;
			if (obj == null)
			{
				OnReadyEvent val = Client_OnReady;
				<>O.<0>__Client_OnReady = val;
				obj = (object)val;
			}
			client.OnReady -= (OnReadyEvent)obj;
			object obj2 = <>O.<1>__Client_OnError;
			if (obj2 == null)
			{
				OnErrorEvent val2 = Client_OnError;
				<>O.<1>__Client_OnError = val2;
				obj2 = (object)val2;
			}
			client.OnError -= (OnErrorEvent)obj2;
			object obj3 = <>O.<2>__Client_OnJoinRequested;
			if (obj3 == null)
			{
				OnJoinRequestedEvent val3 = Client_OnJoinRequested;
				<>O.<2>__Client_OnJoinRequested = val3;
				obj3 = (object)val3;
			}
			client.OnJoinRequested -= (OnJoinRequestedEvent)obj3;
			object obj4 = <>O.<3>__Client_OnJoin;
			if (obj4 == null)
			{
				OnJoinEvent val4 = Client_OnJoin;
				<>O.<3>__Client_OnJoin = val4;
				obj4 = (object)val4;
			}
			client.OnJoin -= (OnJoinEvent)obj4;
		}

		private static void Client_OnReady(object sender, ReadyMessage args)
		{
			//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)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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)
			//IL_008a: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00b4: Expected O, but got Unknown
			DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)("Discord Rich Presence Ready - User: " + args.User.Username));
			if (DiscordRichPresencePlugin.Client != null && DiscordRichPresencePlugin.Client.IsInitialized)
			{
				DiscordRichPresencePlugin.RichPresence = new RichPresence
				{
					Assets = new Assets
					{
						LargeImageKey = "riskofrain2",
						LargeImageText = "DiscordRichPresence v" + ((BaseUnityPlugin)DiscordRichPresencePlugin.Instance).Info.Metadata.Version
					},
					State = "Starting game...",
					Secrets = new Secrets(),
					Timestamps = new Timestamps()
				};
				DiscordRichPresencePlugin.Client.SetPresence(DiscordRichPresencePlugin.RichPresence);
			}
		}

		private static void Client_OnError(object sender, ErrorMessage args)
		{
			DiscordRichPresencePlugin.LoggerEXT.LogError((object)args.Message);
			DiscordRichPresencePlugin.Dispose();
		}

		private static void Client_OnJoinRequested(object sender, JoinRequestMessage args)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)$"User {args.User.Username} asked to join lobby");
			Chat.AddMessage($"Discord user {InfoTextUtils.FormatTextStyleTag(args.User.Username, InfoTextUtils.StyleTag.Event)} has asked to join your game!");
			DiscordRpcClient val = (DiscordRpcClient)sender;
			val.Respond(args, true);
		}

		private static void Client_OnJoin(object sender, JoinMessage args)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (Client.Instance.Lobby.IsValid)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)("Joining Game via Discord - Steam Lobby ID: " + args.Secret));
				ConCommandArgs val = default(ConCommandArgs);
				val.userArgs = new List<string> { args.Secret };
				ConCommandArgs val2 = val;
				((PCLobbyManager)SteamworksLobbyManager.GetFromPlatformSystems()).JoinLobby(val2);
			}
			else
			{
				DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)("Joining Game via Discord - EOS User ID: " + args.Secret));
				UserID val3 = default(UserID);
				UserID.TryParse(args.Secret, ref val3);
				((LobbyManager)EOSLobbyManager.GetFromPlatformSystems()).JoinLobby(val3);
			}
		}
	}
	public static class EOSLobbyHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_OnLobbyCreated <0>__EOSLobbyManager_OnLobbyCreated;

			public static hook_OnLobbyJoined <1>__EOSLobbyManager_OnLobbyJoined;

			public static hook_OnLobbyChanged <2>__EOSLobbyManager_OnLobbyChanged;

			public static hook_LeaveLobby <3>__EOSLobbyManager_LeaveLobby;
		}

		public static void AddHooks()
		{
			//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_001d: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			try
			{
				object obj = <>O.<0>__EOSLobbyManager_OnLobbyCreated;
				if (obj == null)
				{
					hook_OnLobbyCreated val = EOSLobbyManager_OnLobbyCreated;
					<>O.<0>__EOSLobbyManager_OnLobbyCreated = val;
					obj = (object)val;
				}
				EOSLobbyManager.OnLobbyCreated += (hook_OnLobbyCreated)obj;
				object obj2 = <>O.<1>__EOSLobbyManager_OnLobbyJoined;
				if (obj2 == null)
				{
					hook_OnLobbyJoined val2 = EOSLobbyManager_OnLobbyJoined;
					<>O.<1>__EOSLobbyManager_OnLobbyJoined = val2;
					obj2 = (object)val2;
				}
				EOSLobbyManager.OnLobbyJoined += (hook_OnLobbyJoined)obj2;
				object obj3 = <>O.<2>__EOSLobbyManager_OnLobbyChanged;
				if (obj3 == null)
				{
					hook_OnLobbyChanged val3 = EOSLobbyManager_OnLobbyChanged;
					<>O.<2>__EOSLobbyManager_OnLobbyChanged = val3;
					obj3 = (object)val3;
				}
				EOSLobbyManager.OnLobbyChanged += (hook_OnLobbyChanged)obj3;
				object obj4 = <>O.<3>__EOSLobbyManager_LeaveLobby;
				if (obj4 == null)
				{
					hook_LeaveLobby val4 = EOSLobbyManager_LeaveLobby;
					<>O.<3>__EOSLobbyManager_LeaveLobby = val4;
					obj4 = (object)val4;
				}
				EOSLobbyManager.LeaveLobby += (hook_LeaveLobby)obj4;
			}
			catch (BadImageFormatException)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogError((object)"Couldn't hook EOS methods");
			}
		}

		public static void RemoveHooks()
		{
			//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_001d: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			try
			{
				object obj = <>O.<0>__EOSLobbyManager_OnLobbyCreated;
				if (obj == null)
				{
					hook_OnLobbyCreated val = EOSLobbyManager_OnLobbyCreated;
					<>O.<0>__EOSLobbyManager_OnLobbyCreated = val;
					obj = (object)val;
				}
				EOSLobbyManager.OnLobbyCreated -= (hook_OnLobbyCreated)obj;
				object obj2 = <>O.<1>__EOSLobbyManager_OnLobbyJoined;
				if (obj2 == null)
				{
					hook_OnLobbyJoined val2 = EOSLobbyManager_OnLobbyJoined;
					<>O.<1>__EOSLobbyManager_OnLobbyJoined = val2;
					obj2 = (object)val2;
				}
				EOSLobbyManager.OnLobbyJoined -= (hook_OnLobbyJoined)obj2;
				object obj3 = <>O.<2>__EOSLobbyManager_OnLobbyChanged;
				if (obj3 == null)
				{
					hook_OnLobbyChanged val3 = EOSLobbyManager_OnLobbyChanged;
					<>O.<2>__EOSLobbyManager_OnLobbyChanged = val3;
					obj3 = (object)val3;
				}
				EOSLobbyManager.OnLobbyChanged -= (hook_OnLobbyChanged)obj3;
				object obj4 = <>O.<3>__EOSLobbyManager_LeaveLobby;
				if (obj4 == null)
				{
					hook_LeaveLobby val4 = EOSLobbyManager_LeaveLobby;
					<>O.<3>__EOSLobbyManager_LeaveLobby = val4;
					obj4 = (object)val4;
				}
				EOSLobbyManager.LeaveLobby -= (hook_LeaveLobby)obj4;
			}
			catch (BadImageFormatException)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogError((object)"Couldn't unhook EOS methods");
			}
		}

		private static void EOSLobbyManager_OnLobbyCreated(orig_OnLobbyCreated orig, EOSLobbyManager self, CreateLobbyCallbackInfo data)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, data);
			if ((int)data.ResultCode == 0 && self != null)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)("Discord broadcasting new EOS lobby with ID " + self.CurrentLobbyId));
				PresenceUtils.SetLobbyPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, self);
			}
		}

		private static void EOSLobbyManager_OnLobbyJoined(orig_OnLobbyJoined orig, EOSLobbyManager self, JoinLobbyCallbackInfo data)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, data);
			if ((int)data.ResultCode == 0 && self != null)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)"Successfully joined EOS lobby");
				PresenceUtils.SetLobbyPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, self);
			}
		}

		private static void EOSLobbyManager_OnLobbyChanged(orig_OnLobbyChanged orig, EOSLobbyManager self)
		{
			orig.Invoke(self);
			if (self != null && ((LobbyManager)self).isInLobby)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)"Discord re-broadcasting EOS lobby");
				if ((Object)(object)Run.instance == (Object)null)
				{
					PresenceUtils.SetLobbyPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, self, ((BaseRichPresence)DiscordRichPresencePlugin.RichPresence).Details == "Choosing Character");
					return;
				}
				DiscordRichPresencePlugin.RichPresence = PresenceUtils.UpdateParty(DiscordRichPresencePlugin.RichPresence, self, includeJoinButton: false);
				PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, Run.instance);
			}
		}

		private static void EOSLobbyManager_LeaveLobby(orig_LeaveLobby orig, EOSLobbyManager self)
		{
			orig.Invoke(self);
			if (DiscordRichPresencePlugin.Client != null && DiscordRichPresencePlugin.Client.IsInitialized)
			{
				PresenceUtils.SetMainMenuPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence);
			}
		}

		public static void EOSLoginManager_CompleteConnectLogin(orig_CompleteConnectLogin orig, EOSLoginManager self, ProductUserId localUserId)
		{
			orig.Invoke(self, localUserId);
			AddHooks();
			DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)((object)(UserID)(ref EOSLoginManager.loggedInUserID)).ToString());
		}
	}
	public static class PauseManagerHooks
	{
		public static void AddHooks()
		{
			PauseManager.onPauseStartGlobal = (Action)Delegate.Combine(PauseManager.onPauseStartGlobal, new Action(OnGamePaused));
			PauseManager.onPauseEndGlobal = (Action)Delegate.Combine(PauseManager.onPauseEndGlobal, new Action(OnGameUnPaused));
		}

		public static void RemoveHooks()
		{
			PauseManager.onPauseStartGlobal = (Action)Delegate.Remove(PauseManager.onPauseStartGlobal, new Action(OnGamePaused));
			PauseManager.onPauseEndGlobal = (Action)Delegate.Remove(PauseManager.onPauseEndGlobal, new Action(OnGameUnPaused));
		}

		private static void OnGamePaused()
		{
			if ((Object)(object)Run.instance != (Object)null && (Object)(object)DiscordRichPresencePlugin.CurrentScene != (Object)null)
			{
				PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, Run.instance, isPaused: true);
			}
		}

		private static void OnGameUnPaused()
		{
			if ((Object)(object)Run.instance != (Object)null && (Object)(object)DiscordRichPresencePlugin.CurrentScene != (Object)null)
			{
				PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, Run.instance);
			}
		}
	}
	public static class RoR2Hooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action<CharacterBody> <0>__CharacterBody_onBodyStartGlobal;

			public static Action<CharacterBody> <1>__CharacterBody_onBodyDestroyGlobal;

			public static hook_Start <2>__Stage_Start;

			public static hook_FixedUpdate <3>__TeleporterInteraction_FixedUpdate;

			public static hook_SetCountdownTime <4>__EscapeSequenceController_SetCountdownTime;

			public static hook_BeginNextWave <5>__InfiniteTowerRun_BeginNextWave;

			public static hook_OnEnter <6>__BaseMainMenuScreen_OnEnter;
		}

		public static void AddHooks()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0074: 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_007f: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			CharacterBody.onBodyStartGlobal += CharacterBody_onBodyStartGlobal;
			CharacterBody.onBodyDestroyGlobal += CharacterBody_onBodyDestroyGlobal;
			object obj = <>O.<2>__Stage_Start;
			if (obj == null)
			{
				hook_Start val = Stage_Start;
				<>O.<2>__Stage_Start = val;
				obj = (object)val;
			}
			Stage.Start += (hook_Start)obj;
			object obj2 = <>O.<3>__TeleporterInteraction_FixedUpdate;
			if (obj2 == null)
			{
				hook_FixedUpdate val2 = TeleporterInteraction_FixedUpdate;
				<>O.<3>__TeleporterInteraction_FixedUpdate = val2;
				obj2 = (object)val2;
			}
			TeleporterInteraction.FixedUpdate += (hook_FixedUpdate)obj2;
			object obj3 = <>O.<4>__EscapeSequenceController_SetCountdownTime;
			if (obj3 == null)
			{
				hook_SetCountdownTime val3 = EscapeSequenceController_SetCountdownTime;
				<>O.<4>__EscapeSequenceController_SetCountdownTime = val3;
				obj3 = (object)val3;
			}
			EscapeSequenceController.SetCountdownTime += (hook_SetCountdownTime)obj3;
			object obj4 = <>O.<5>__InfiniteTowerRun_BeginNextWave;
			if (obj4 == null)
			{
				hook_BeginNextWave val4 = InfiniteTowerRun_BeginNextWave;
				<>O.<5>__InfiniteTowerRun_BeginNextWave = val4;
				obj4 = (object)val4;
			}
			InfiniteTowerRun.BeginNextWave += (hook_BeginNextWave)obj4;
			object obj5 = <>O.<6>__BaseMainMenuScreen_OnEnter;
			if (obj5 == null)
			{
				hook_OnEnter val5 = BaseMainMenuScreen_OnEnter;
				<>O.<6>__BaseMainMenuScreen_OnEnter = val5;
				obj5 = (object)val5;
			}
			BaseMainMenuScreen.OnEnter += (hook_OnEnter)obj5;
		}

		private static void Stage_Start(orig_Start orig, Stage self)
		{
			orig.Invoke(self);
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			object obj;
			if (firstLocalUser == null)
			{
				obj = null;
			}
			else
			{
				PlayerCharacterMasterController cachedMasterController = firstLocalUser.cachedMasterController;
				if (cachedMasterController == null)
				{
					obj = null;
				}
				else
				{
					CharacterMaster master = cachedMasterController.master;
					obj = ((master != null) ? master.GetBody() : null);
				}
			}
			CharacterBody val = (CharacterBody)obj;
			if (!((Object)(object)val == (Object)null))
			{
				DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)("LocalBodyBaseName: " + val.baseNameToken));
				((BaseRichPresence)DiscordRichPresencePlugin.RichPresence).Assets.SmallImageKey = InfoTextUtils.GetCharacterInternalName(val.GetDisplayName());
				((BaseRichPresence)DiscordRichPresencePlugin.RichPresence).Assets.SmallImageText = val.GetDisplayName();
				DiscordRichPresencePlugin.Client.SetPresence(DiscordRichPresencePlugin.RichPresence);
				PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, Run.instance);
			}
		}

		public static void RemoveHooks()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0074: 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_007f: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			CharacterBody.onBodyStartGlobal -= CharacterBody_onBodyStartGlobal;
			CharacterBody.onBodyDestroyGlobal -= CharacterBody_onBodyDestroyGlobal;
			object obj = <>O.<2>__Stage_Start;
			if (obj == null)
			{
				hook_Start val = Stage_Start;
				<>O.<2>__Stage_Start = val;
				obj = (object)val;
			}
			Stage.Start -= (hook_Start)obj;
			object obj2 = <>O.<3>__TeleporterInteraction_FixedUpdate;
			if (obj2 == null)
			{
				hook_FixedUpdate val2 = TeleporterInteraction_FixedUpdate;
				<>O.<3>__TeleporterInteraction_FixedUpdate = val2;
				obj2 = (object)val2;
			}
			TeleporterInteraction.FixedUpdate -= (hook_FixedUpdate)obj2;
			object obj3 = <>O.<4>__EscapeSequenceController_SetCountdownTime;
			if (obj3 == null)
			{
				hook_SetCountdownTime val3 = EscapeSequenceController_SetCountdownTime;
				<>O.<4>__EscapeSequenceController_SetCountdownTime = val3;
				obj3 = (object)val3;
			}
			EscapeSequenceController.SetCountdownTime -= (hook_SetCountdownTime)obj3;
			object obj4 = <>O.<5>__InfiniteTowerRun_BeginNextWave;
			if (obj4 == null)
			{
				hook_BeginNextWave val4 = InfiniteTowerRun_BeginNextWave;
				<>O.<5>__InfiniteTowerRun_BeginNextWave = val4;
				obj4 = (object)val4;
			}
			InfiniteTowerRun.BeginNextWave -= (hook_BeginNextWave)obj4;
			object obj5 = <>O.<6>__BaseMainMenuScreen_OnEnter;
			if (obj5 == null)
			{
				hook_OnEnter val5 = BaseMainMenuScreen_OnEnter;
				<>O.<6>__BaseMainMenuScreen_OnEnter = val5;
				obj5 = (object)val5;
			}
			BaseMainMenuScreen.OnEnter -= (hook_OnEnter)obj5;
		}

		private static void CharacterBody_onBodyStartGlobal(CharacterBody obj)
		{
			if (obj.isChampion)
			{
				DiscordRichPresencePlugin.CurrentBoss = obj.GetDisplayName();
				PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, Run.instance);
			}
		}

		private static void CharacterBody_onBodyDestroyGlobal(CharacterBody obj)
		{
			if (obj.isChampion && (Object)(object)Run.instance != (Object)null)
			{
				DiscordRichPresencePlugin.CurrentBoss = "";
				PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, Run.instance);
			}
		}

		private static void TeleporterInteraction_FixedUpdate(orig_FixedUpdate orig, TeleporterInteraction self)
		{
			if (Math.Round(self.chargeFraction, 2) != (double)DiscordRichPresencePlugin.CurrentChargeLevel && PluginConfig.TeleporterStatusEntry.Value == PluginConfig.TeleporterStatus.Charge)
			{
				DiscordRichPresencePlugin.CurrentChargeLevel = (float)Math.Round(self.chargeFraction, 2);
				PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, Run.instance);
			}
			orig.Invoke(self);
		}

		private static void EscapeSequenceController_SetCountdownTime(orig_SetCountdownTime orig, EscapeSequenceController self, double secondsRemaining)
		{
			DiscordRichPresencePlugin.MoonCountdownTimer = (float)secondsRemaining + 1f;
			PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, Run.instance);
			orig.Invoke(self, secondsRemaining);
		}

		private static void InfiniteTowerRun_BeginNextWave(orig_BeginNextWave orig, InfiniteTowerRun self)
		{
			PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, (Run)(object)self);
			orig.Invoke(self);
		}

		private static void BaseMainMenuScreen_OnEnter(orig_OnEnter orig, BaseMainMenuScreen self, MainMenuController mainMenuController)
		{
			if (Client.Instance.Lobby.IsValid)
			{
				PresenceUtils.SetLobbyPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, Client.Instance);
			}
			else if (DiscordRichPresencePlugin.IsInEOSLobby)
			{
				PresenceUtils.SetLobbyPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, EOSLobbyManager.GetFromPlatformSystems());
			}
			else
			{
				PresenceUtils.SetMainMenuPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence);
			}
			orig.Invoke(self, mainMenuController);
		}
	}
	public static class SteamworksLobbyHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_OnLobbyCreated <0>__SteamworksLobbyManager_OnLobbyCreated;

			public static hook_OnLobbyJoined <1>__SteamworksLobbyManager_OnLobbyJoined;

			public static hook_OnLobbyChanged <2>__SteamworksLobbyManager_OnLobbyChanged;

			public static hook_LeaveLobby <3>__SteamworksLobbyManager_LeaveLobby;
		}

		public static void AddHooks()
		{
			//IL_0011: 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)
			//IL_001c: Expected O, but got Unknown
			//IL_0032: 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_003d: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0074: 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_007f: Expected O, but got Unknown
			object obj = <>O.<0>__SteamworksLobbyManager_OnLobbyCreated;
			if (obj == null)
			{
				hook_OnLobbyCreated val = SteamworksLobbyManager_OnLobbyCreated;
				<>O.<0>__SteamworksLobbyManager_OnLobbyCreated = val;
				obj = (object)val;
			}
			SteamworksLobbyManager.OnLobbyCreated += (hook_OnLobbyCreated)obj;
			object obj2 = <>O.<1>__SteamworksLobbyManager_OnLobbyJoined;
			if (obj2 == null)
			{
				hook_OnLobbyJoined val2 = SteamworksLobbyManager_OnLobbyJoined;
				<>O.<1>__SteamworksLobbyManager_OnLobbyJoined = val2;
				obj2 = (object)val2;
			}
			SteamworksLobbyManager.OnLobbyJoined += (hook_OnLobbyJoined)obj2;
			object obj3 = <>O.<2>__SteamworksLobbyManager_OnLobbyChanged;
			if (obj3 == null)
			{
				hook_OnLobbyChanged val3 = SteamworksLobbyManager_OnLobbyChanged;
				<>O.<2>__SteamworksLobbyManager_OnLobbyChanged = val3;
				obj3 = (object)val3;
			}
			SteamworksLobbyManager.OnLobbyChanged += (hook_OnLobbyChanged)obj3;
			object obj4 = <>O.<3>__SteamworksLobbyManager_LeaveLobby;
			if (obj4 == null)
			{
				hook_LeaveLobby val4 = SteamworksLobbyManager_LeaveLobby;
				<>O.<3>__SteamworksLobbyManager_LeaveLobby = val4;
				obj4 = (object)val4;
			}
			SteamworksLobbyManager.LeaveLobby += (hook_LeaveLobby)obj4;
		}

		public static void RemoveHooks()
		{
			//IL_0011: 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)
			//IL_001c: Expected O, but got Unknown
			//IL_0032: 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_003d: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0074: 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_007f: Expected O, but got Unknown
			object obj = <>O.<0>__SteamworksLobbyManager_OnLobbyCreated;
			if (obj == null)
			{
				hook_OnLobbyCreated val = SteamworksLobbyManager_OnLobbyCreated;
				<>O.<0>__SteamworksLobbyManager_OnLobbyCreated = val;
				obj = (object)val;
			}
			SteamworksLobbyManager.OnLobbyCreated -= (hook_OnLobbyCreated)obj;
			object obj2 = <>O.<1>__SteamworksLobbyManager_OnLobbyJoined;
			if (obj2 == null)
			{
				hook_OnLobbyJoined val2 = SteamworksLobbyManager_OnLobbyJoined;
				<>O.<1>__SteamworksLobbyManager_OnLobbyJoined = val2;
				obj2 = (object)val2;
			}
			SteamworksLobbyManager.OnLobbyJoined -= (hook_OnLobbyJoined)obj2;
			object obj3 = <>O.<2>__SteamworksLobbyManager_OnLobbyChanged;
			if (obj3 == null)
			{
				hook_OnLobbyChanged val3 = SteamworksLobbyManager_OnLobbyChanged;
				<>O.<2>__SteamworksLobbyManager_OnLobbyChanged = val3;
				obj3 = (object)val3;
			}
			SteamworksLobbyManager.OnLobbyChanged -= (hook_OnLobbyChanged)obj3;
			object obj4 = <>O.<3>__SteamworksLobbyManager_LeaveLobby;
			if (obj4 == null)
			{
				hook_LeaveLobby val4 = SteamworksLobbyManager_LeaveLobby;
				<>O.<3>__SteamworksLobbyManager_LeaveLobby = val4;
				obj4 = (object)val4;
			}
			SteamworksLobbyManager.LeaveLobby -= (hook_LeaveLobby)obj4;
		}

		private static void SteamworksLobbyManager_OnLobbyCreated(orig_OnLobbyCreated orig, SteamworksLobbyManager self, bool success)
		{
			orig.Invoke(self, success);
			if (success && Client.Instance != null)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)("Discord broadcasting new Steam lobby with ID " + Client.Instance.Lobby.CurrentLobby));
				PresenceUtils.SetLobbyPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, Client.Instance);
			}
		}

		private static void SteamworksLobbyManager_OnLobbyJoined(orig_OnLobbyJoined orig, SteamworksLobbyManager self, bool success)
		{
			orig.Invoke(self, success);
			if (success && Client.Instance != null)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)"Successfully joined Steam lobby");
				PresenceUtils.SetLobbyPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, Client.Instance);
			}
		}

		private static void SteamworksLobbyManager_OnLobbyChanged(orig_OnLobbyChanged orig, SteamworksLobbyManager self)
		{
			orig.Invoke(self);
			if (((LobbyManager)self).isInLobby && Client.Instance != null)
			{
				DiscordRichPresencePlugin.LoggerEXT.LogInfo((object)"Discord re-broadcasting Steam lobby");
				if ((Object)(object)Run.instance == (Object)null)
				{
					PresenceUtils.SetLobbyPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, Client.Instance, ((BaseRichPresence)DiscordRichPresencePlugin.RichPresence).Details == "Choosing Character");
					return;
				}
				DiscordRichPresencePlugin.RichPresence = PresenceUtils.UpdateParty(DiscordRichPresencePlugin.RichPresence, Client.Instance, includeJoinButton: false);
				PresenceUtils.SetStagePresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence, DiscordRichPresencePlugin.CurrentScene, Run.instance);
			}
		}

		private static void SteamworksLobbyManager_LeaveLobby(orig_LeaveLobby orig, SteamworksLobbyManager self)
		{
			orig.Invoke(self);
			if (DiscordRichPresencePlugin.Client != null && DiscordRichPresencePlugin.Client.IsInitialized)
			{
				PresenceUtils.SetMainMenuPresence(DiscordRichPresencePlugin.Client, DiscordRichPresencePlugin.RichPresence);
			}
		}
	}
}

Cuno-DiscordRichPresence-1.2.1/DiscordRPC.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using DiscordRPC.Converters;
using DiscordRPC.Events;
using DiscordRPC.Exceptions;
using DiscordRPC.Helper;
using DiscordRPC.IO;
using DiscordRPC.Logging;
using DiscordRPC.Message;
using DiscordRPC.RPC;
using DiscordRPC.RPC.Commands;
using DiscordRPC.RPC.Payload;
using DiscordRPC.Registry;
using Microsoft.Win32;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Discord RPC")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Discord RPC")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("819d20d6-8d88-45c1-a4d2-aa21f10abd19")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace DiscordRPC
{
	public class Configuration
	{
		[JsonProperty("api_endpoint")]
		public string ApiEndpoint { get; set; }

		[JsonProperty("cdn_host")]
		public string CdnHost { get; set; }

		[JsonProperty("enviroment")]
		public string Enviroment { get; set; }
	}
	public sealed class DiscordRpcClient : IDisposable
	{
		private ILogger _logger;

		private RpcConnection connection;

		private bool _shutdownOnly = true;

		private object _sync = new object();

		public bool HasRegisteredUriScheme { get; private set; }

		public string ApplicationID { get; private set; }

		public string SteamID { get; private set; }

		public int ProcessID { get; private set; }

		public int MaxQueueSize { get; private set; }

		public bool IsDisposed { get; private set; }

		public ILogger Logger
		{
			get
			{
				return _logger;
			}
			set
			{
				_logger = value;
				if (connection != null)
				{
					connection.Logger = value;
				}
			}
		}

		public bool AutoEvents { get; private set; }

		public bool SkipIdenticalPresence { get; set; }

		public int TargetPipe { get; private set; }

		public RichPresence CurrentPresence { get; private set; }

		public EventType Subscription { get; private set; }

		public User CurrentUser { get; private set; }

		public Configuration Configuration { get; private set; }

		public bool IsInitialized { get; private set; }

		public bool ShutdownOnly
		{
			get
			{
				return _shutdownOnly;
			}
			set
			{
				_shutdownOnly = value;
				if (connection != null)
				{
					connection.ShutdownOnly = value;
				}
			}
		}

		public event OnReadyEvent OnReady;

		public event OnCloseEvent OnClose;

		public event OnErrorEvent OnError;

		public event OnPresenceUpdateEvent OnPresenceUpdate;

		public event OnSubscribeEvent OnSubscribe;

		public event OnUnsubscribeEvent OnUnsubscribe;

		public event OnJoinEvent OnJoin;

		public event OnSpectateEvent OnSpectate;

		public event OnJoinRequestedEvent OnJoinRequested;

		public event OnConnectionEstablishedEvent OnConnectionEstablished;

		public event OnConnectionFailedEvent OnConnectionFailed;

		public event OnRpcMessageEvent OnRpcMessage;

		public DiscordRpcClient(string applicationID)
			: this(applicationID, -1, null, autoEvents: true, null)
		{
		}

		public DiscordRpcClient(string applicationID, int pipe = -1, ILogger logger = null, bool autoEvents = true, INamedPipeClient client = null)
		{
			if (string.IsNullOrEmpty(applicationID))
			{
				throw new ArgumentNullException("applicationID");
			}
			Type typeFromHandle = typeof(JsonConverter);
			if ((object)typeFromHandle == null)
			{
				throw new Exception("JsonConverter Type Not Found");
			}
			ApplicationID = applicationID.Trim();
			TargetPipe = pipe;
			ProcessID = Process.GetCurrentProcess().Id;
			HasRegisteredUriScheme = false;
			AutoEvents = autoEvents;
			SkipIdenticalPresence = true;
			_logger = logger ?? new NullLogger();
			connection = new RpcConnection(ApplicationID, ProcessID, TargetPipe, client ?? new ManagedNamedPipeClient(), (!autoEvents) ? 128u : 0u)
			{
				ShutdownOnly = _shutdownOnly,
				Logger = _logger
			};
			connection.OnRpcMessage += delegate(object sender, IMessage msg)
			{
				if (this.OnRpcMessage != null)
				{
					this.OnRpcMessage(this, msg);
				}
				if (AutoEvents)
				{
					ProcessMessage(msg);
				}
			};
		}

		public IMessage[] Invoke()
		{
			if (AutoEvents)
			{
				Logger.Error("Cannot Invoke client when AutomaticallyInvokeEvents has been set.");
				return new IMessage[0];
			}
			IMessage[] array = connection.DequeueMessages();
			foreach (IMessage message in array)
			{
				ProcessMessage(message);
			}
			return array;
		}

		private void ProcessMessage(IMessage message)
		{
			if (message == null)
			{
				return;
			}
			switch (message.Type)
			{
			case MessageType.PresenceUpdate:
				lock (_sync)
				{
					if (message is PresenceMessage presenceMessage)
					{
						if (CurrentPresence == null)
						{
							CurrentPresence = new RichPresence().Merge(presenceMessage.Presence);
						}
						else if (presenceMessage.Presence == null)
						{
							CurrentPresence = null;
						}
						else
						{
							CurrentPresence.Merge(presenceMessage.Presence);
						}
						presenceMessage.Presence = CurrentPresence;
					}
				}
				break;
			case MessageType.Ready:
				if (message is ReadyMessage readyMessage)
				{
					lock (_sync)
					{
						Configuration = readyMessage.Configuration;
						CurrentUser = readyMessage.User;
					}
					SynchronizeState();
				}
				break;
			case MessageType.JoinRequest:
				if (Configuration != null && message is JoinRequestMessage joinRequestMessage)
				{
					joinRequestMessage.User.SetConfiguration(Configuration);
				}
				break;
			case MessageType.Subscribe:
				lock (_sync)
				{
					SubscribeMessage subscribeMessage = message as SubscribeMessage;
					Subscription |= subscribeMessage.Event;
				}
				break;
			case MessageType.Unsubscribe:
				lock (_sync)
				{
					UnsubscribeMessage unsubscribeMessage = message as UnsubscribeMessage;
					Subscription &= ~unsubscribeMessage.Event;
				}
				break;
			}
			switch (message.Type)
			{
			case MessageType.Ready:
				if (this.OnReady != null)
				{
					this.OnReady(this, message as ReadyMessage);
				}
				break;
			case MessageType.Close:
				if (this.OnClose != null)
				{
					this.OnClose(this, message as CloseMessage);
				}
				break;
			case MessageType.Error:
				if (this.OnError != null)
				{
					this.OnError(this, message as ErrorMessage);
				}
				break;
			case MessageType.PresenceUpdate:
				if (this.OnPresenceUpdate != null)
				{
					this.OnPresenceUpdate(this, message as PresenceMessage);
				}
				break;
			case MessageType.Subscribe:
				if (this.OnSubscribe != null)
				{
					this.OnSubscribe(this, message as SubscribeMessage);
				}
				break;
			case MessageType.Unsubscribe:
				if (this.OnUnsubscribe != null)
				{
					this.OnUnsubscribe(this, message as UnsubscribeMessage);
				}
				break;
			case MessageType.Join:
				if (this.OnJoin != null)
				{
					this.OnJoin(this, message as JoinMessage);
				}
				break;
			case MessageType.Spectate:
				if (this.OnSpectate != null)
				{
					this.OnSpectate(this, message as SpectateMessage);
				}
				break;
			case MessageType.JoinRequest:
				if (this.OnJoinRequested != null)
				{
					this.OnJoinRequested(this, message as JoinRequestMessage);
				}
				break;
			case MessageType.ConnectionEstablished:
				if (this.OnConnectionEstablished != null)
				{
					this.OnConnectionEstablished(this, message as ConnectionEstablishedMessage);
				}
				break;
			case MessageType.ConnectionFailed:
				if (this.OnConnectionFailed != null)
				{
					this.OnConnectionFailed(this, message as ConnectionFailedMessage);
				}
				break;
			default:
				Logger.Error("Message was queued with no appropriate handle! {0}", message.Type);
				break;
			}
		}

		public void Respond(JoinRequestMessage request, bool acceptRequest)
		{
			if (IsDisposed)
			{
				throw new ObjectDisposedException("Discord IPC Client");
			}
			if (connection == null)
			{
				throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized");
			}
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			connection.EnqueueCommand(new RespondCommand
			{
				Accept = acceptRequest,
				UserID = request.User.ID.ToString()
			});
		}

		public void SetPresence(RichPresence presence)
		{
			if (IsDisposed)
			{
				throw new ObjectDisposedException("Discord IPC Client");
			}
			if (connection == null)
			{
				throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized");
			}
			if (!IsInitialized)
			{
				Logger.Warning("The client is not yet initialized, storing the presence as a state instead.");
			}
			if (!presence)
			{
				if (!SkipIdenticalPresence || CurrentPresence != null)
				{
					connection.EnqueueCommand(new PresenceCommand
					{
						PID = ProcessID,
						Presence = null
					});
				}
			}
			else
			{
				if (presence.HasSecrets() && !HasRegisteredUriScheme)
				{
					throw new BadPresenceException("Cannot send a presence with secrets as this object has not registered a URI scheme. Please enable the uri scheme registration in the DiscordRpcClient constructor.");
				}
				if (presence.HasParty() && presence.Party.Max < presence.Party.Size)
				{
					throw new BadPresenceException("Presence maximum party size cannot be smaller than the current size.");
				}
				if (presence.HasSecrets() && !presence.HasParty())
				{
					Logger.Warning("The presence has set the secrets but no buttons will show as there is no party available.");
				}
				if (!SkipIdenticalPresence || !presence.Matches(CurrentPresence))
				{
					connection.EnqueueCommand(new PresenceCommand
					{
						PID = ProcessID,
						Presence = presence.Clone()
					});
				}
			}
			lock (_sync)
			{
				CurrentPresence = presence?.Clone();
			}
		}

		public RichPresence UpdateDetails(string details)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			richPresence.Details = details;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdateState(string state)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			richPresence.State = state;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdateParty(Party party)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			richPresence.Party = party;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdatePartySize(int size)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			if (richPresence.Party == null)
			{
				throw new BadPresenceException("Cannot set the size of the party if the party does not exist");
			}
			richPresence.Party.Size = size;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdatePartySize(int size, int max)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			if (richPresence.Party == null)
			{
				throw new BadPresenceException("Cannot set the size of the party if the party does not exist");
			}
			richPresence.Party.Size = size;
			richPresence.Party.Max = max;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdateLargeAsset(string key = null, string tooltip = null)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			if (richPresence.Assets == null)
			{
				richPresence.Assets = new Assets();
			}
			richPresence.Assets.LargeImageKey = key ?? richPresence.Assets.LargeImageKey;
			richPresence.Assets.LargeImageText = tooltip ?? richPresence.Assets.LargeImageText;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdateSmallAsset(string key = null, string tooltip = null)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			if (richPresence.Assets == null)
			{
				richPresence.Assets = new Assets();
			}
			richPresence.Assets.SmallImageKey = key ?? richPresence.Assets.SmallImageKey;
			richPresence.Assets.SmallImageText = tooltip ?? richPresence.Assets.SmallImageText;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdateSecrets(Secrets secrets)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			richPresence.Secrets = secrets;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdateStartTime()
		{
			return UpdateStartTime(DateTime.UtcNow);
		}

		public RichPresence UpdateStartTime(DateTime time)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			if (richPresence.Timestamps == null)
			{
				richPresence.Timestamps = new Timestamps();
			}
			richPresence.Timestamps.Start = time;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdateEndTime()
		{
			return UpdateEndTime(DateTime.UtcNow);
		}

		public RichPresence UpdateEndTime(DateTime time)
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			if (richPresence.Timestamps == null)
			{
				richPresence.Timestamps = new Timestamps();
			}
			richPresence.Timestamps.End = time;
			SetPresence(richPresence);
			return richPresence;
		}

		public RichPresence UpdateClearTime()
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			RichPresence richPresence;
			lock (_sync)
			{
				richPresence = ((CurrentPresence != null) ? CurrentPresence.Clone() : new RichPresence());
			}
			richPresence.Timestamps = null;
			SetPresence(richPresence);
			return richPresence;
		}

		public void ClearPresence()
		{
			if (IsDisposed)
			{
				throw new ObjectDisposedException("Discord IPC Client");
			}
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			if (connection == null)
			{
				throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized");
			}
			SetPresence(null);
		}

		public bool RegisterUriScheme(string steamAppID = null, string executable = null)
		{
			UriSchemeRegister uriSchemeRegister = new UriSchemeRegister(_logger, ApplicationID, steamAppID, executable);
			return HasRegisteredUriScheme = uriSchemeRegister.RegisterUriScheme();
		}

		public void Subscribe(EventType type)
		{
			SetSubscription(Subscription | type);
		}

		[Obsolete("Replaced with Unsubscribe", true)]
		public void Unubscribe(EventType type)
		{
			SetSubscription(Subscription & ~type);
		}

		public void Unsubscribe(EventType type)
		{
			SetSubscription(Subscription & ~type);
		}

		public void SetSubscription(EventType type)
		{
			if (IsInitialized)
			{
				SubscribeToTypes(Subscription & ~type, isUnsubscribe: true);
				SubscribeToTypes(~Subscription & type, isUnsubscribe: false);
			}
			else
			{
				Logger.Warning("Client has not yet initialized, but events are being subscribed too. Storing them as state instead.");
			}
			lock (_sync)
			{
				Subscription = type;
			}
		}

		private void SubscribeToTypes(EventType type, bool isUnsubscribe)
		{
			if (type != 0)
			{
				if (IsDisposed)
				{
					throw new ObjectDisposedException("Discord IPC Client");
				}
				if (!IsInitialized)
				{
					throw new UninitializedException();
				}
				if (connection == null)
				{
					throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized");
				}
				if (!HasRegisteredUriScheme)
				{
					throw new InvalidConfigurationException("Cannot subscribe/unsubscribe to an event as this application has not registered a URI Scheme. Call RegisterUriScheme().");
				}
				if ((type & EventType.Spectate) == EventType.Spectate)
				{
					connection.EnqueueCommand(new SubscribeCommand
					{
						Event = ServerEvent.ActivitySpectate,
						IsUnsubscribe = isUnsubscribe
					});
				}
				if ((type & EventType.Join) == EventType.Join)
				{
					connection.EnqueueCommand(new SubscribeCommand
					{
						Event = ServerEvent.ActivityJoin,
						IsUnsubscribe = isUnsubscribe
					});
				}
				if ((type & EventType.JoinRequest) == EventType.JoinRequest)
				{
					connection.EnqueueCommand(new SubscribeCommand
					{
						Event = ServerEvent.ActivityJoinRequest,
						IsUnsubscribe = isUnsubscribe
					});
				}
			}
		}

		public void SynchronizeState()
		{
			if (!IsInitialized)
			{
				throw new UninitializedException();
			}
			SetPresence(CurrentPresence);
			if (HasRegisteredUriScheme)
			{
				SubscribeToTypes(Subscription, isUnsubscribe: false);
			}
		}

		public bool Initialize()
		{
			if (IsDisposed)
			{
				throw new ObjectDisposedException("Discord IPC Client");
			}
			if (IsInitialized)
			{
				throw new UninitializedException("Cannot initialize a client that is already initialized");
			}
			if (connection == null)
			{
				throw new ObjectDisposedException("Connection", "Cannot initialize as the connection has been deinitialized");
			}
			return IsInitialized = connection.AttemptConnection();
		}

		public void Deinitialize()
		{
			if (!IsInitialized)
			{
				throw new UninitializedException("Cannot deinitialize a client that has not been initalized.");
			}
			connection.Close();
			IsInitialized = false;
		}

		public void Dispose()
		{
			if (!IsDisposed)
			{
				if (IsInitialized)
				{
					Deinitialize();
				}
				IsDisposed = true;
			}
		}
	}
	[Flags]
	public enum EventType
	{
		None = 0,
		Spectate = 1,
		Join = 2,
		JoinRequest = 4
	}
	[Serializable]
	[JsonObject(/*Could not decode attribute arguments.*/)]
	public class BaseRichPresence
	{
		protected internal string _state;

		protected internal string _details;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string State
		{
			get
			{
				return _state;
			}
			set
			{
				if (!ValidateString(value, out _state, 128, Encoding.UTF8))
				{
					throw new StringOutOfRangeException("State", 0, 128);
				}
			}
		}

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string Details
		{
			get
			{
				return _details;
			}
			set
			{
				if (!ValidateString(value, out _details, 128, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(128);
				}
			}
		}

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public Timestamps Timestamps { get; set; }

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public Assets Assets { get; set; }

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public Party Party { get; set; }

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public Secrets Secrets { get; set; }

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		[Obsolete("This was going to be used, but was replaced by JoinSecret instead")]
		private bool Instance { get; set; }

		public bool HasTimestamps()
		{
			return Timestamps != null && (Timestamps.Start.HasValue || Timestamps.End.HasValue);
		}

		public bool HasAssets()
		{
			return Assets != null;
		}

		public bool HasParty()
		{
			return Party != null && Party.ID != null;
		}

		public bool HasSecrets()
		{
			return Secrets != null && (Secrets.JoinSecret != null || Secrets.SpectateSecret != null);
		}

		internal static bool ValidateString(string str, out string result, int bytes, Encoding encoding)
		{
			result = str;
			if (str == null)
			{
				return true;
			}
			string str2 = str.Trim();
			if (!str2.WithinLength(bytes, encoding))
			{
				return false;
			}
			result = str2.GetNullOrString();
			return true;
		}

		public static implicit operator bool(BaseRichPresence presesnce)
		{
			return presesnce != null;
		}

		internal virtual bool Matches(RichPresence other)
		{
			if (other == null)
			{
				return false;
			}
			if (State != other.State || Details != other.Details)
			{
				return false;
			}
			if (Timestamps != null)
			{
				if (other.Timestamps == null || other.Timestamps.StartUnixMilliseconds != Timestamps.StartUnixMilliseconds || other.Timestamps.EndUnixMilliseconds != Timestamps.EndUnixMilliseconds)
				{
					return false;
				}
			}
			else if (other.Timestamps != null)
			{
				return false;
			}
			if (Secrets != null)
			{
				if (other.Secrets == null || other.Secrets.JoinSecret != Secrets.JoinSecret || other.Secrets.MatchSecret != Secrets.MatchSecret || other.Secrets.SpectateSecret != Secrets.SpectateSecret)
				{
					return false;
				}
			}
			else if (other.Secrets != null)
			{
				return false;
			}
			if (Party != null)
			{
				if (other.Party == null || other.Party.ID != Party.ID || other.Party.Max != Party.Max || other.Party.Size != Party.Size || other.Party.Privacy != Party.Privacy)
				{
					return false;
				}
			}
			else if (other.Party != null)
			{
				return false;
			}
			if (Assets != null)
			{
				if (other.Assets == null || other.Assets.LargeImageKey != Assets.LargeImageKey || other.Assets.LargeImageText != Assets.LargeImageText || other.Assets.SmallImageKey != Assets.SmallImageKey || other.Assets.SmallImageText != Assets.SmallImageText)
				{
					return false;
				}
			}
			else if (other.Assets != null)
			{
				return false;
			}
			return Instance == other.Instance;
		}
	}
	[Serializable]
	public class Secrets
	{
		private string _matchSecret;

		private string _joinSecret;

		private string _spectateSecret;

		[Obsolete("This feature has been deprecated my Mason in issue #152 on the offical library. Was originally used as a Notify Me feature, it has been replaced with Join / Spectate.")]
		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string MatchSecret
		{
			get
			{
				return _matchSecret;
			}
			set
			{
				if (!BaseRichPresence.ValidateString(value, out _matchSecret, 128, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(128);
				}
			}
		}

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string JoinSecret
		{
			get
			{
				return _joinSecret;
			}
			set
			{
				if (!BaseRichPresence.ValidateString(value, out _joinSecret, 128, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(128);
				}
			}
		}

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string SpectateSecret
		{
			get
			{
				return _spectateSecret;
			}
			set
			{
				if (!BaseRichPresence.ValidateString(value, out _spectateSecret, 128, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(128);
				}
			}
		}

		public static Encoding Encoding => Encoding.UTF8;

		public static int SecretLength => 128;

		public static string CreateSecret(Random random)
		{
			byte[] array = new byte[SecretLength];
			random.NextBytes(array);
			return Encoding.GetString(array);
		}

		public static string CreateFriendlySecret(Random random)
		{
			string text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
			string text2 = "";
			for (int i = 0; i < SecretLength; i++)
			{
				text2 += text[random.Next(text.Length)];
			}
			return text2;
		}
	}
	[Serializable]
	public class Assets
	{
		private string _largeimagekey;

		private string _largeimagetext;

		private string _smallimagekey;

		private string _smallimagetext;

		private ulong? _largeimageID;

		private ulong? _smallimageID;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string LargeImageKey
		{
			get
			{
				return _largeimagekey;
			}
			set
			{
				if (!BaseRichPresence.ValidateString(value, out _largeimagekey, 32, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(32);
				}
				_largeimageID = null;
			}
		}

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string LargeImageText
		{
			get
			{
				return _largeimagetext;
			}
			set
			{
				if (!BaseRichPresence.ValidateString(value, out _largeimagetext, 128, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(128);
				}
			}
		}

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string SmallImageKey
		{
			get
			{
				return _smallimagekey;
			}
			set
			{
				if (!BaseRichPresence.ValidateString(value, out _smallimagekey, 32, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(32);
				}
				_smallimageID = null;
			}
		}

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string SmallImageText
		{
			get
			{
				return _smallimagetext;
			}
			set
			{
				if (!BaseRichPresence.ValidateString(value, out _smallimagetext, 128, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(128);
				}
			}
		}

		[JsonIgnore]
		public ulong? LargeImageID => _largeimageID;

		[JsonIgnore]
		public ulong? SmallImageID => _smallimageID;

		internal void Merge(Assets other)
		{
			_smallimagetext = other._smallimagetext;
			_largeimagetext = other._largeimagetext;
			if (ulong.TryParse(other._largeimagekey, out var result))
			{
				_largeimageID = result;
			}
			else
			{
				_largeimagekey = other._largeimagekey;
				_largeimageID = null;
			}
			if (ulong.TryParse(other._smallimagekey, out var result2))
			{
				_smallimageID = result2;
				return;
			}
			_smallimagekey = other._smallimagekey;
			_smallimageID = null;
		}
	}
	[Serializable]
	public class Timestamps
	{
		public static Timestamps Now => new Timestamps(DateTime.UtcNow);

		[JsonIgnore]
		public DateTime? Start { get; set; }

		[JsonIgnore]
		public DateTime? End { get; set; }

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public ulong? StartUnixMilliseconds
		{
			get
			{
				return Start.HasValue ? new ulong?(ToUnixMilliseconds(Start.Value)) : null;
			}
			set
			{
				Start = (value.HasValue ? new DateTime?(FromUnixMilliseconds(value.Value)) : null);
			}
		}

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public ulong? EndUnixMilliseconds
		{
			get
			{
				return End.HasValue ? new ulong?(ToUnixMilliseconds(End.Value)) : null;
			}
			set
			{
				End = (value.HasValue ? new DateTime?(FromUnixMilliseconds(value.Value)) : null);
			}
		}

		public static Timestamps FromTimeSpan(double seconds)
		{
			return FromTimeSpan(TimeSpan.FromSeconds(seconds));
		}

		public static Timestamps FromTimeSpan(TimeSpan timespan)
		{
			return new Timestamps
			{
				Start = DateTime.UtcNow,
				End = DateTime.UtcNow + timespan
			};
		}

		public Timestamps()
		{
			Start = null;
			End = null;
		}

		public Timestamps(DateTime start, DateTime? end = null)
		{
			Start = start;
			End = end;
		}

		public static DateTime FromUnixMilliseconds(ulong unixTime)
		{
			return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(Convert.ToDouble(unixTime));
		}

		public static ulong ToUnixMilliseconds(DateTime date)
		{
			DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
			return Convert.ToUInt64((date - dateTime).TotalMilliseconds);
		}
	}
	[Serializable]
	public class Party
	{
		public enum PrivacySetting
		{
			Private,
			Public
		}

		private string _partyid;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string ID
		{
			get
			{
				return _partyid;
			}
			set
			{
				_partyid = value.GetNullOrString();
			}
		}

		[JsonIgnore]
		public int Size { get; set; }

		[JsonIgnore]
		public int Max { get; set; }

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public PrivacySetting Privacy { get; set; }

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		private int[] _size
		{
			get
			{
				int num = Math.Max(1, Size);
				return new int[2]
				{
					num,
					Math.Max(num, Max)
				};
			}
			set
			{
				if (value.Length != 2)
				{
					Size = 0;
					Max = 0;
				}
				else
				{
					Size = value[0];
					Max = value[1];
				}
			}
		}
	}
	public class Button
	{
		private string _label;

		private string _url;

		[JsonProperty("label")]
		public string Label
		{
			get
			{
				return _label;
			}
			set
			{
				if (!BaseRichPresence.ValidateString(value, out _label, 32, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(32);
				}
			}
		}

		[JsonProperty("url")]
		public string Url
		{
			get
			{
				return _url;
			}
			set
			{
				if (!BaseRichPresence.ValidateString(value, out _url, 512, Encoding.UTF8))
				{
					throw new StringOutOfRangeException(512);
				}
				if (!Uri.TryCreate(_url, UriKind.Absolute, out Uri _))
				{
					throw new ArgumentException("Url must be a valid URI");
				}
			}
		}
	}
	public sealed class RichPresence : BaseRichPresence
	{
		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public Button[] Buttons { get; set; }

		public bool HasButtons()
		{
			return Buttons != null && Buttons.Length != 0;
		}

		public RichPresence WithState(string state)
		{
			base.State = state;
			return this;
		}

		public RichPresence WithDetails(string details)
		{
			base.Details = details;
			return this;
		}

		public RichPresence WithTimestamps(Timestamps timestamps)
		{
			base.Timestamps = timestamps;
			return this;
		}

		public RichPresence WithAssets(Assets assets)
		{
			base.Assets = assets;
			return this;
		}

		public RichPresence WithParty(Party party)
		{
			base.Party = party;
			return this;
		}

		public RichPresence WithSecrets(Secrets secrets)
		{
			base.Secrets = secrets;
			return this;
		}

		public RichPresence Clone()
		{
			RichPresence richPresence = new RichPresence();
			richPresence.State = ((_state != null) ? (_state.Clone() as string) : null);
			richPresence.Details = ((_details != null) ? (_details.Clone() as string) : null);
			richPresence.Buttons = ((!HasButtons()) ? null : (Buttons.Clone() as Button[]));
			richPresence.Secrets = ((!HasSecrets()) ? null : new Secrets
			{
				JoinSecret = ((base.Secrets.JoinSecret != null) ? (base.Secrets.JoinSecret.Clone() as string) : null),
				SpectateSecret = ((base.Secrets.SpectateSecret != null) ? (base.Secrets.SpectateSecret.Clone() as string) : null)
			});
			richPresence.Timestamps = ((!HasTimestamps()) ? null : new Timestamps
			{
				Start = base.Timestamps.Start,
				End = base.Timestamps.End
			});
			richPresence.Assets = ((!HasAssets()) ? null : new Assets
			{
				LargeImageKey = ((base.Assets.LargeImageKey != null) ? (base.Assets.LargeImageKey.Clone() as string) : null),
				LargeImageText = ((base.Assets.LargeImageText != null) ? (base.Assets.LargeImageText.Clone() as string) : null),
				SmallImageKey = ((base.Assets.SmallImageKey != null) ? (base.Assets.SmallImageKey.Clone() as string) : null),
				SmallImageText = ((base.Assets.SmallImageText != null) ? (base.Assets.SmallImageText.Clone() as string) : null)
			});
			richPresence.Party = ((!HasParty()) ? null : new Party
			{
				ID = base.Party.ID,
				Size = base.Party.Size,
				Max = base.Party.Max,
				Privacy = base.Party.Privacy
			});
			return richPresence;
		}

		internal RichPresence Merge(BaseRichPresence presence)
		{
			_state = presence.State;
			_details = presence.Details;
			base.Party = presence.Party;
			base.Timestamps = presence.Timestamps;
			base.Secrets = presence.Secrets;
			if (presence.HasAssets())
			{
				if (!HasAssets())
				{
					base.Assets = presence.Assets;
				}
				else
				{
					base.Assets.Merge(presence.Assets);
				}
			}
			else
			{
				base.Assets = null;
			}
			return this;
		}

		internal override bool Matches(RichPresence other)
		{
			if (!base.Matches(other))
			{
				return false;
			}
			if ((Buttons == null) ^ (other.Buttons == null))
			{
				return false;
			}
			if (Buttons != null)
			{
				if (Buttons.Length != other.Buttons.Length)
				{
					return false;
				}
				for (int i = 0; i < Buttons.Length; i++)
				{
					Button button = Buttons[i];
					Button button2 = other.Buttons[i];
					if (button.Label != button2.Label || button.Url != button2.Url)
					{
						return false;
					}
				}
			}
			return true;
		}

		public static implicit operator bool(RichPresence presesnce)
		{
			return presesnce != null;
		}
	}
	internal sealed class RichPresenceResponse : BaseRichPresence
	{
		[JsonProperty("application_id")]
		public string ClientID { get; private set; }

		[JsonProperty("name")]
		public string Name { get; private set; }
	}
	public class User
	{
		public enum AvatarFormat
		{
			PNG,
			JPEG,
			WebP,
			GIF
		}

		public enum AvatarSize
		{
			x16 = 0x10,
			x32 = 0x20,
			x64 = 0x40,
			x128 = 0x80,
			x256 = 0x100,
			x512 = 0x200,
			x1024 = 0x400,
			x2048 = 0x800
		}

		[Flags]
		public enum Flag
		{
			None = 0,
			Employee = 1,
			Partner = 2,
			HypeSquad = 4,
			BugHunter = 8,
			HouseBravery = 0x40,
			HouseBrilliance = 0x80,
			HouseBalance = 0x100,
			EarlySupporter = 0x200,
			TeamUser = 0x400
		}

		public enum PremiumType
		{
			None,
			NitroClassic,
			Nitro
		}

		[JsonProperty("id")]
		public ulong ID { get; private set; }

		[JsonProperty("username")]
		public string Username { get; private set; }

		[JsonProperty("discriminator")]
		public int Discriminator { get; private set; }

		[JsonProperty("avatar")]
		public string Avatar { get; private set; }

		[JsonProperty("flags")]
		public Flag Flags { get; private set; }

		[JsonProperty("premium_type")]
		public PremiumType Premium { get; private set; }

		public string CdnEndpoint { get; private set; }

		internal User()
		{
			CdnEndpoint = "cdn.discordapp.com";
		}

		internal void SetConfiguration(Configuration configuration)
		{
			CdnEndpoint = configuration.CdnHost;
		}

		public string GetAvatarURL(AvatarFormat format, AvatarSize size = AvatarSize.x128)
		{
			string text = "/avatars/" + ID + "/" + Avatar;
			if (string.IsNullOrEmpty(Avatar))
			{
				if (format != 0)
				{
					throw new BadImageFormatException("The user has no avatar and the requested format " + format.ToString() + " is not supported. (Only supports PNG).");
				}
				text = "/embed/avatars/" + Discriminator % 5;
			}
			return $"https://{CdnEndpoint}{text}{GetAvatarExtension(format)}?size={(int)size}";
		}

		public string GetAvatarExtension(AvatarFormat format)
		{
			return "." + format.ToString().ToLowerInvariant();
		}

		public override string ToString()
		{
			return Username + "#" + Discriminator.ToString("D4");
		}
	}
}
namespace DiscordRPC.RPC
{
	internal class RpcConnection : IDisposable
	{
		public static readonly int VERSION = 1;

		public static readonly int POLL_RATE = 1000;

		private static readonly bool CLEAR_ON_SHUTDOWN = true;

		private static readonly bool LOCK_STEP = false;

		private ILogger _logger;

		private RpcState _state;

		private readonly object l_states = new object();

		private Configuration _configuration = null;

		private readonly object l_config = new object();

		private volatile bool aborting = false;

		private volatile bool shutdown = false;

		private string applicationID;

		private int processID;

		private long nonce;

		private Thread thread;

		private INamedPipeClient namedPipe;

		private int targetPipe;

		private readonly object l_rtqueue = new object();

		private readonly uint _maxRtQueueSize;

		private Queue<ICommand> _rtqueue;

		private readonly object l_rxqueue = new object();

		private readonly uint _maxRxQueueSize;

		private Queue<IMessage> _rxqueue;

		private AutoResetEvent queueUpdatedEvent = new AutoResetEvent(initialState: false);

		private BackoffDelay delay;

		public ILogger Logger
		{
			get
			{
				return _logger;
			}
			set
			{
				_logger = value;
				if (namedPipe != null)
				{
					namedPipe.Logger = value;
				}
			}
		}

		public RpcState State
		{
			get
			{
				RpcState result = RpcState.Disconnected;
				lock (l_states)
				{
					result = _state;
				}
				return result;
			}
		}

		public Configuration Configuration
		{
			get
			{
				Configuration result = null;
				lock (l_config)
				{
					result = _configuration;
				}
				return result;
			}
		}

		public bool IsRunning => thread != null;

		public bool ShutdownOnly { get; set; }

		public event OnRpcMessageEvent OnRpcMessage;

		public RpcConnection(string applicationID, int processID, int targetPipe, INamedPipeClient client, uint maxRxQueueSize = 128u, uint maxRtQueueSize = 512u)
		{
			this.applicationID = applicationID;
			this.processID = processID;
			this.targetPipe = targetPipe;
			namedPipe = client;
			ShutdownOnly = true;
			Logger = new ConsoleLogger();
			delay = new BackoffDelay(500, 60000);
			_maxRtQueueSize = maxRtQueueSize;
			_rtqueue = new Queue<ICommand>((int)(_maxRtQueueSize + 1));
			_maxRxQueueSize = maxRxQueueSize;
			_rxqueue = new Queue<IMessage>((int)(_maxRxQueueSize + 1));
			nonce = 0L;
		}

		private long GetNextNonce()
		{
			nonce++;
			return nonce;
		}

		internal void EnqueueCommand(ICommand command)
		{
			Logger.Trace("Enqueue Command: " + command.GetType().FullName);
			if (aborting || shutdown)
			{
				return;
			}
			lock (l_rtqueue)
			{
				if (_rtqueue.Count == _maxRtQueueSize)
				{
					Logger.Error("Too many enqueued commands, dropping oldest one. Maybe you are pushing new presences to fast?");
					_rtqueue.Dequeue();
				}
				_rtqueue.Enqueue(command);
			}
		}

		private void EnqueueMessage(IMessage message)
		{
			try
			{
				if (this.OnRpcMessage != null)
				{
					this.OnRpcMessage(this, message);
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Unhandled Exception while processing event: {0}", ex.GetType().FullName);
				Logger.Error(ex.Message);
				Logger.Error(ex.StackTrace);
			}
			if (_maxRxQueueSize == 0)
			{
				Logger.Trace("Enqueued Message, but queue size is 0.");
				return;
			}
			Logger.Trace("Enqueue Message: " + message.Type);
			lock (l_rxqueue)
			{
				if (_rxqueue.Count == _maxRxQueueSize)
				{
					Logger.Warning("Too many enqueued messages, dropping oldest one.");
					_rxqueue.Dequeue();
				}
				_rxqueue.Enqueue(message);
			}
		}

		internal IMessage DequeueMessage()
		{
			lock (l_rxqueue)
			{
				if (_rxqueue.Count == 0)
				{
					return null;
				}
				return _rxqueue.Dequeue();
			}
		}

		internal IMessage[] DequeueMessages()
		{
			lock (l_rxqueue)
			{
				IMessage[] result = _rxqueue.ToArray();
				_rxqueue.Clear();
				return result;
			}
		}

		private void MainLoop()
		{
			Logger.Info("RPC Connection Started");
			if (Logger.Level <= LogLevel.Trace)
			{
				Logger.Trace("============================");
				Logger.Trace("Assembly:             " + Assembly.GetAssembly(typeof(RichPresence)).FullName);
				Logger.Trace("Pipe:                 " + namedPipe.GetType().FullName);
				Logger.Trace("Platform:             " + Environment.OSVersion.ToString());
				Logger.Trace("applicationID:        " + applicationID);
				Logger.Trace("targetPipe:           " + targetPipe);
				ILogger logger = Logger;
				int pOLL_RATE = POLL_RATE;
				logger.Trace("POLL_RATE:            " + pOLL_RATE);
				ILogger logger2 = Logger;
				uint maxRtQueueSize = _maxRtQueueSize;
				logger2.Trace("_maxRtQueueSize:      " + maxRtQueueSize);
				ILogger logger3 = Logger;
				maxRtQueueSize = _maxRxQueueSize;
				logger3.Trace("_maxRxQueueSize:      " + maxRtQueueSize);
				Logger.Trace("============================");
			}
			while (!aborting && !shutdown)
			{
				try
				{
					if (namedPipe == null)
					{
						Logger.Error("Something bad has happened with our pipe client!");
						aborting = true;
						return;
					}
					Logger.Trace("Connecting to the pipe through the {0}", namedPipe.GetType().FullName);
					if (namedPipe.Connect(targetPipe))
					{
						Logger.Trace("Connected to the pipe. Attempting to establish handshake...");
						EnqueueMessage(new ConnectionEstablishedMessage
						{
							ConnectedPipe = namedPipe.ConnectedPipe
						});
						EstablishHandshake();
						Logger.Trace("Connection Established. Starting reading loop...");
						bool flag = true;
						while (flag && !aborting && !shutdown && namedPipe.IsConnected)
						{
							if (namedPipe.ReadFrame(out var frame))
							{
								Logger.Trace("Read Payload: {0}", frame.Opcode);
								switch (frame.Opcode)
								{
								case Opcode.Close:
								{
									ClosePayload @object = frame.GetObject<ClosePayload>();
									Logger.Warning("We have been told to terminate by discord: ({0}) {1}", @object.Code, @object.Reason);
									EnqueueMessage(new CloseMessage
									{
										Code = @object.Code,
										Reason = @object.Reason
									});
									flag = false;
									break;
								}
								case Opcode.Ping:
									Logger.Trace("PING");
									frame.Opcode = Opcode.Pong;
									namedPipe.WriteFrame(frame);
									break;
								case Opcode.Pong:
									Logger.Trace("PONG");
									break;
								case Opcode.Frame:
								{
									if (shutdown)
									{
										Logger.Warning("Skipping frame because we are shutting down.");
										break;
									}
									if (frame.Data == null)
									{
										Logger.Error("We received no data from the frame so we cannot get the event payload!");
										break;
									}
									EventPayload eventPayload = null;
									try
									{
										eventPayload = frame.GetObject<EventPayload>();
									}
									catch (Exception ex)
									{
										Logger.Error("Failed to parse event! " + ex.Message);
										Logger.Error("Data: " + frame.Message);
									}
									try
									{
										if (eventPayload != null)
										{
											ProcessFrame(eventPayload);
										}
									}
									catch (Exception ex2)
									{
										Logger.Error("Failed to process event! " + ex2.Message);
										Logger.Error("Data: " + frame.Message);
									}
									break;
								}
								default:
									Logger.Error("Invalid opcode: {0}", frame.Opcode);
									flag = false;
									break;
								}
							}
							if (!aborting && namedPipe.IsConnected)
							{
								ProcessCommandQueue();
								queueUpdatedEvent.WaitOne(POLL_RATE);
							}
						}
						Logger.Trace("Left main read loop for some reason. Aborting: {0}, Shutting Down: {1}", aborting, shutdown);
					}
					else
					{
						Logger.Error("Failed to connect for some reason.");
						EnqueueMessage(new ConnectionFailedMessage
						{
							FailedPipe = targetPipe
						});
					}
					if (!aborting && !shutdown)
					{
						long num = delay.NextDelay();
						Logger.Trace("Waiting {0}ms before attempting to connect again", num);
						Thread.Sleep(delay.NextDelay());
					}
				}
				catch (Exception ex3)
				{
					Logger.Error("Unhandled Exception: {0}", ex3.GetType().FullName);
					Logger.Error(ex3.Message);
					Logger.Error(ex3.StackTrace);
				}
				finally
				{
					if (namedPipe.IsConnected)
					{
						Logger.Trace("Closing the named pipe.");
						namedPipe.Close();
					}
					SetConnectionState(RpcState.Disconnected);
				}
			}
			Logger.Trace("Left Main Loop");
			if (namedPipe != null)
			{
				namedPipe.Dispose();
			}
			Logger.Info("Thread Terminated, no longer performing RPC connection.");
		}

		private void ProcessFrame(EventPayload response)
		{
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			Logger.Info("Handling Response. Cmd: {0}, Event: {1}", response.Command, response.Event);
			if (response.Event.HasValue && response.Event.Value == ServerEvent.Error)
			{
				Logger.Error("Error received from the RPC");
				ErrorMessage @object = response.GetObject<ErrorMessage>();
				Logger.Error("Server responded with an error message: ({0}) {1}", @object.Code.ToString(), @object.Message);
				EnqueueMessage(@object);
			}
			else if (State == RpcState.Connecting && response.Command == Command.Dispatch && response.Event.HasValue && response.Event.Value == ServerEvent.Ready)
			{
				Logger.Info("Connection established with the RPC");
				SetConnectionState(RpcState.Connected);
				delay.Reset();
				ReadyMessage object2 = response.GetObject<ReadyMessage>();
				lock (l_config)
				{
					_configuration = object2.Configuration;
					object2.User.SetConfiguration(_configuration);
				}
				EnqueueMessage(object2);
			}
			else if (State == RpcState.Connected)
			{
				switch (response.Command)
				{
				case Command.Dispatch:
					ProcessDispatch(response);
					break;
				case Command.SetActivity:
				{
					if (response.Data == null)
					{
						EnqueueMessage(new PresenceMessage());
						break;
					}
					RichPresenceResponse object3 = response.GetObject<RichPresenceResponse>();
					EnqueueMessage(new PresenceMessage(object3));
					break;
				}
				case Command.Subscribe:
				case Command.Unsubscribe:
				{
					JsonSerializer val = new JsonSerializer();
					((Collection<JsonConverter>)(object)val.Converters).Add((JsonConverter)(object)new EnumSnakeCaseConverter());
					ServerEvent value = response.GetObject<EventPayload>().Event.Value;
					if (response.Command == Command.Subscribe)
					{
						EnqueueMessage(new SubscribeMessage(value));
					}
					else
					{
						EnqueueMessage(new UnsubscribeMessage(value));
					}
					break;
				}
				case Command.SendActivityJoinInvite:
					Logger.Trace("Got invite response ack.");
					break;
				case Command.CloseActivityJoinRequest:
					Logger.Trace("Got invite response reject ack.");
					break;
				default:
					Logger.Error("Unkown frame was received! {0}", response.Command);
					break;
				}
			}
			else
			{
				Logger.Trace("Received a frame while we are disconnected. Ignoring. Cmd: {0}, Event: {1}", response.Command, response.Event);
			}
		}

		private void ProcessDispatch(EventPayload response)
		{
			if (response.Command == Command.Dispatch && response.Event.HasValue)
			{
				switch (response.Event.Value)
				{
				case ServerEvent.ActivitySpectate:
				{
					SpectateMessage object3 = response.GetObject<SpectateMessage>();
					EnqueueMessage(object3);
					break;
				}
				case ServerEvent.ActivityJoin:
				{
					JoinMessage object2 = response.GetObject<JoinMessage>();
					EnqueueMessage(object2);
					break;
				}
				case ServerEvent.ActivityJoinRequest:
				{
					JoinRequestMessage @object = response.GetObject<JoinRequestMessage>();
					EnqueueMessage(@object);
					break;
				}
				default:
					Logger.Warning("Ignoring {0}", response.Event.Value);
					break;
				}
			}
		}

		private void ProcessCommandQueue()
		{
			if (State != RpcState.Connected)
			{
				return;
			}
			if (aborting)
			{
				Logger.Warning("We have been told to write a queue but we have also been aborted.");
			}
			bool flag = true;
			ICommand command = null;
			while (flag && namedPipe.IsConnected)
			{
				lock (l_rtqueue)
				{
					flag = _rtqueue.Count > 0;
					if (!flag)
					{
						break;
					}
					command = _rtqueue.Peek();
				}
				if (shutdown || (!aborting && LOCK_STEP))
				{
					flag = false;
				}
				IPayload payload = command.PreparePayload(GetNextNonce());
				Logger.Trace("Attempting to send payload: " + payload.Command);
				PipeFrame frame = default(PipeFrame);
				if (command is CloseCommand)
				{
					SendHandwave();
					Logger.Trace("Handwave sent, ending queue processing.");
					lock (l_rtqueue)
					{
						_rtqueue.Dequeue();
						break;
					}
				}
				if (aborting)
				{
					Logger.Warning("- skipping frame because of abort.");
					lock (l_rtqueue)
					{
						_rtqueue.Dequeue();
					}
					continue;
				}
				frame.SetObject(Opcode.Frame, payload);
				Logger.Trace("Sending payload: " + payload.Command);
				if (namedPipe.WriteFrame(frame))
				{
					Logger.Trace("Sent Successfully.");
					lock (l_rtqueue)
					{
						_rtqueue.Dequeue();
					}
					continue;
				}
				Logger.Warning("Something went wrong during writing!");
				break;
			}
		}

		private void EstablishHandshake()
		{
			Logger.Trace("Attempting to establish a handshake...");
			if (State != 0)
			{
				Logger.Error("State must be disconnected in order to start a handshake!");
				return;
			}
			Logger.Trace("Sending Handshake...");
			if (!namedPipe.WriteFrame(new PipeFrame(Opcode.Handshake, new Handshake
			{
				Version = VERSION,
				ClientID = applicationID
			})))
			{
				Logger.Error("Failed to write a handshake.");
			}
			else
			{
				SetConnectionState(RpcState.Connecting);
			}
		}

		private void SendHandwave()
		{
			Logger.Info("Attempting to wave goodbye...");
			if (State == RpcState.Disconnected)
			{
				Logger.Error("State must NOT be disconnected in order to send a handwave!");
			}
			else if (!namedPipe.WriteFrame(new PipeFrame(Opcode.Close, new Handshake
			{
				Version = VERSION,
				ClientID = applicationID
			})))
			{
				Logger.Error("failed to write a handwave.");
			}
		}

		public bool AttemptConnection()
		{
			Logger.Info("Attempting a new connection");
			if (thread != null)
			{
				Logger.Error("Cannot attempt a new connection as the previous connection thread is not null!");
				return false;
			}
			if (State != 0)
			{
				Logger.Warning("Cannot attempt a new connection as the previous connection hasn't changed state yet.");
				return false;
			}
			if (aborting)
			{
				Logger.Error("Cannot attempt a new connection while aborting!");
				return false;
			}
			thread = new Thread(MainLoop);
			thread.Name = "Discord IPC Thread";
			thread.IsBackground = true;
			thread.Start();
			return true;
		}

		private void SetConnectionState(RpcState state)
		{
			Logger.Trace("Setting the connection state to {0}", state.ToString().ToSnakeCase().ToUpperInvariant());
			lock (l_states)
			{
				_state = state;
			}
		}

		public void Shutdown()
		{
			Logger.Trace("Initiated shutdown procedure");
			shutdown = true;
			lock (l_rtqueue)
			{
				_rtqueue.Clear();
				if (CLEAR_ON_SHUTDOWN)
				{
					_rtqueue.Enqueue(new PresenceCommand
					{
						PID = processID,
						Presence = null
					});
				}
				_rtqueue.Enqueue(new CloseCommand());
			}
			queueUpdatedEvent.Set();
		}

		public void Close()
		{
			if (thread == null)
			{
				Logger.Error("Cannot close as it is not available!");
				return;
			}
			if (aborting)
			{
				Logger.Error("Cannot abort as it has already been aborted");
				return;
			}
			if (ShutdownOnly)
			{
				Shutdown();
				return;
			}
			Logger.Trace("Updating Abort State...");
			aborting = true;
			queueUpdatedEvent.Set();
		}

		public void Dispose()
		{
			ShutdownOnly = false;
			Close();
		}
	}
	internal enum RpcState
	{
		Disconnected,
		Connecting,
		Connected
	}
}
namespace DiscordRPC.RPC.Payload
{
	internal class ClosePayload : IPayload
	{
		[JsonProperty("code")]
		public int Code { get; set; }

		[JsonProperty("message")]
		public string Reason { get; set; }
	}
	internal enum Command
	{
		[EnumValue("DISPATCH")]
		Dispatch,
		[EnumValue("SET_ACTIVITY")]
		SetActivity,
		[EnumValue("SUBSCRIBE")]
		Subscribe,
		[EnumValue("UNSUBSCRIBE")]
		Unsubscribe,
		[EnumValue("SEND_ACTIVITY_JOIN_INVITE")]
		SendActivityJoinInvite,
		[EnumValue("CLOSE_ACTIVITY_JOIN_REQUEST")]
		CloseActivityJoinRequest,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		Authorize,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		Authenticate,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		GetGuild,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		GetGuilds,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		GetChannel,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		GetChannels,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		SetUserVoiceSettings,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		SelectVoiceChannel,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		GetSelectedVoiceChannel,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		SelectTextChannel,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		GetVoiceSettings,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		SetVoiceSettings,
		[Obsolete("This value is appart of the RPC API and is not supported by this library.", true)]
		CaptureShortcut
	}
	internal abstract class IPayload
	{
		[JsonProperty("cmd")]
		[JsonConverter(typeof(EnumSnakeCaseConverter))]
		public Command Command { get; set; }

		[JsonProperty("nonce")]
		public string Nonce { get; set; }

		protected IPayload()
		{
		}

		protected IPayload(long nonce)
		{
			Nonce = nonce.ToString();
		}

		public override string ToString()
		{
			return "Payload || Command: " + Command.ToString() + ", Nonce: " + ((Nonce != null) ? Nonce.ToString() : "NULL");
		}
	}
	internal class ArgumentPayload : IPayload
	{
		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public JObject Arguments { get; set; }

		public ArgumentPayload()
		{
			Arguments = null;
		}

		public ArgumentPayload(long nonce)
			: base(nonce)
		{
			Arguments = null;
		}

		public ArgumentPayload(object args, long nonce)
			: base(nonce)
		{
			SetObject(args);
		}

		public void SetObject(object obj)
		{
			Arguments = JObject.FromObject(obj);
		}

		public T GetObject<T>()
		{
			return ((JToken)Arguments).ToObject<T>();
		}

		public override string ToString()
		{
			return "Argument " + base.ToString();
		}
	}
	internal class EventPayload : IPayload
	{
		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public JObject Data { get; set; }

		[JsonProperty("evt")]
		[JsonConverter(typeof(EnumSnakeCaseConverter))]
		public ServerEvent? Event { get; set; }

		public EventPayload()
		{
			Data = null;
		}

		public EventPayload(long nonce)
			: base(nonce)
		{
			Data = null;
		}

		public T GetObject<T>()
		{
			if (Data == null)
			{
				return default(T);
			}
			return ((JToken)Data).ToObject<T>();
		}

		public override string ToString()
		{
			return "Event " + base.ToString() + ", Event: " + (Event.HasValue ? Event.ToString() : "N/A");
		}
	}
	internal enum ServerEvent
	{
		[EnumValue("READY")]
		Ready,
		[EnumValue("ERROR")]
		Error,
		[EnumValue("ACTIVITY_JOIN")]
		ActivityJoin,
		[EnumValue("ACTIVITY_SPECTATE")]
		ActivitySpectate,
		[EnumValue("ACTIVITY_JOIN_REQUEST")]
		ActivityJoinRequest
	}
}
namespace DiscordRPC.RPC.Commands
{
	internal class CloseCommand : ICommand
	{
		[JsonProperty("close_reason")]
		public string value = "Unity 5.5 doesn't handle thread aborts. Can you please close me discord?";

		[JsonProperty("pid")]
		public int PID { get; set; }

		public IPayload PreparePayload(long nonce)
		{
			return new ArgumentPayload
			{
				Command = Command.Dispatch,
				Nonce = null,
				Arguments = null
			};
		}
	}
	internal interface ICommand
	{
		IPayload PreparePayload(long nonce);
	}
	internal class PresenceCommand : ICommand
	{
		[JsonProperty("pid")]
		public int PID { get; set; }

		[JsonProperty("activity")]
		public RichPresence Presence { get; set; }

		public IPayload PreparePayload(long nonce)
		{
			return new ArgumentPayload(this, nonce)
			{
				Command = Command.SetActivity
			};
		}
	}
	internal class RespondCommand : ICommand
	{
		[JsonProperty("user_id")]
		public string UserID { get; set; }

		[JsonIgnore]
		public bool Accept { get; set; }

		public IPayload PreparePayload(long nonce)
		{
			return new ArgumentPayload(this, nonce)
			{
				Command = (Accept ? Command.SendActivityJoinInvite : Command.CloseActivityJoinRequest)
			};
		}
	}
	internal class SubscribeCommand : ICommand
	{
		public ServerEvent Event { get; set; }

		public bool IsUnsubscribe { get; set; }

		public IPayload PreparePayload(long nonce)
		{
			return new EventPayload(nonce)
			{
				Command = (IsUnsubscribe ? Command.Unsubscribe : Command.Subscribe),
				Event = Event
			};
		}
	}
}
namespace DiscordRPC.Registry
{
	internal interface IUriSchemeCreator
	{
		bool RegisterUriScheme(UriSchemeRegister register);
	}
	internal class MacUriSchemeCreator : IUriSchemeCreator
	{
		private ILogger logger;

		public MacUriSchemeCreator(ILogger logger)
		{
			this.logger = logger;
		}

		public bool RegisterUriScheme(UriSchemeRegister register)
		{
			string executablePath = register.ExecutablePath;
			if (string.IsNullOrEmpty(executablePath))
			{
				logger.Error("Failed to register because the application could not be located.");
				return false;
			}
			logger.Trace("Registering Steam Command");
			string text = executablePath;
			if (register.UsingSteamApp)
			{
				text = "steam://rungameid/" + register.SteamAppID;
			}
			else
			{
				logger.Warning("This library does not fully support MacOS URI Scheme Registration.");
			}
			string text2 = "~/Library/Application Support/discord/games";
			DirectoryInfo directoryInfo = Directory.CreateDirectory(text2);
			if (!directoryInfo.Exists)
			{
				logger.Error("Failed to register because {0} does not exist", text2);
				return false;
			}
			File.WriteAllText(text2 + "/" + register.ApplicationID + ".json", "{ \"command\": \"" + text + "\" }");
			logger.Trace("Registered {0}, {1}", text2 + "/" + register.ApplicationID + ".json", text);
			return true;
		}
	}
	internal class UnixUriSchemeCreator : IUriSchemeCreator
	{
		private ILogger logger;

		public UnixUriSchemeCreator(ILogger logger)
		{
			this.logger = logger;
		}

		public bool RegisterUriScheme(UriSchemeRegister register)
		{
			string environmentVariable = Environment.GetEnvironmentVariable("HOME");
			if (string.IsNullOrEmpty(environmentVariable))
			{
				logger.Error("Failed to register because the HOME variable was not set.");
				return false;
			}
			string executablePath = register.ExecutablePath;
			if (string.IsNullOrEmpty(executablePath))
			{
				logger.Error("Failed to register because the application was not located.");
				return false;
			}
			string text = null;
			text = ((!register.UsingSteamApp) ? executablePath : ("xdg-open steam://rungameid/" + register.SteamAppID));
			string format = "[Desktop Entry]\r\nName=Game {0}\r\nExec={1} %u\r\nType=Application\r\nNoDisplay=true\r\nCategories=Discord;Games;\r\nMimeType=x-scheme-handler/discord-{2}";
			string text2 = string.Format(format, register.ApplicationID, text, register.ApplicationID);
			string text3 = "/discord-" + register.ApplicationID + ".desktop";
			string text4 = environmentVariable + "/.local/share/applications";
			DirectoryInfo directoryInfo = Directory.CreateDirectory(text4);
			if (!directoryInfo.Exists)
			{
				logger.Error("Failed to register because {0} does not exist", text4);
				return false;
			}
			File.WriteAllText(text4 + text3, text2);
			if (!RegisterMime(register.ApplicationID))
			{
				logger.Error("Failed to register because the Mime failed.");
				return false;
			}
			logger.Trace("Registered {0}, {1}, {2}", text4 + text3, text2, text);
			return true;
		}

		private bool RegisterMime(string appid)
		{
			string format = "default discord-{0}.desktop x-scheme-handler/discord-{0}";
			string arguments = string.Format(format, appid);
			Process process = Process.Start("xdg-mime", arguments);
			process.WaitForExit();
			return process.ExitCode >= 0;
		}
	}
	internal class UriSchemeRegister
	{
		private ILogger _logger;

		public string ApplicationID { get; set; }

		public string SteamAppID { get; set; }

		public bool UsingSteamApp => !string.IsNullOrEmpty(SteamAppID) && SteamAppID != "";

		public string ExecutablePath { get; set; }

		public UriSchemeRegister(ILogger logger, string applicationID, string steamAppID = null, string executable = null)
		{
			_logger = logger;
			ApplicationID = applicationID.Trim();
			SteamAppID = steamAppID?.Trim();
			ExecutablePath = executable ?? GetApplicationLocation();
		}

		public bool RegisterUriScheme()
		{
			IUriSchemeCreator uriSchemeCreator = null;
			switch (Environment.OSVersion.Platform)
			{
			case PlatformID.Win32S:
			case PlatformID.Win32Windows:
			case PlatformID.Win32NT:
			case PlatformID.WinCE:
				_logger.Trace("Creating Windows Scheme Creator");
				uriSchemeCreator = new WindowsUriSchemeCreator(_logger);
				break;
			case PlatformID.Unix:
				_logger.Trace("Creating Unix Scheme Creator");
				uriSchemeCreator = new UnixUriSchemeCreator(_logger);
				break;
			case PlatformID.MacOSX:
				_logger.Trace("Creating MacOSX Scheme Creator");
				uriSchemeCreator = new MacUriSchemeCreator(_logger);
				break;
			default:
				_logger.Error("Unkown Platform: " + Environment.OSVersion.Platform);
				throw new PlatformNotSupportedException("Platform does not support registration.");
			}
			if (uriSchemeCreator.RegisterUriScheme(this))
			{
				_logger.Info("URI scheme registered.");
				return true;
			}
			return false;
		}

		public static string GetApplicationLocation()
		{
			return Process.GetCurrentProcess().MainModule.FileName;
		}
	}
	internal class WindowsUriSchemeCreator : IUriSchemeCreator
	{
		private ILogger logger;

		public WindowsUriSchemeCreator(ILogger logger)
		{
			this.logger = logger;
		}

		public bool RegisterUriScheme(UriSchemeRegister register)
		{
			if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
			{
				throw new PlatformNotSupportedException("URI schemes can only be registered on Windows");
			}
			string executablePath = register.ExecutablePath;
			if (executablePath == null)
			{
				logger.Error("Failed to register application because the location was null.");
				return false;
			}
			string scheme = "discord-" + register.ApplicationID;
			string friendlyName = "Run game " + register.ApplicationID + " protocol";
			string defaultIcon = executablePath;
			string command = executablePath;
			if (register.UsingSteamApp)
			{
				string steamLocation = GetSteamLocation();
				if (steamLocation != null)
				{
					command = $"\"{steamLocation}\" steam://rungameid/{register.SteamAppID}";
				}
			}
			CreateUriScheme(scheme, friendlyName, defaultIcon, command);
			return true;
		}

		private void CreateUriScheme(string scheme, string friendlyName, string defaultIcon, string command)
		{
			using (RegistryKey registryKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("SOFTWARE\\Classes\\" + scheme))
			{
				registryKey.SetValue("", "URL:" + friendlyName);
				registryKey.SetValue("URL Protocol", "");
				using (RegistryKey registryKey2 = registryKey.CreateSubKey("DefaultIcon"))
				{
					registryKey2.SetValue("", defaultIcon);
				}
				using RegistryKey registryKey3 = registryKey.CreateSubKey("shell\\open\\command");
				registryKey3.SetValue("", command);
			}
			logger.Trace("Registered {0}, {1}, {2}", scheme, friendlyName, command);
		}

		public string GetSteamLocation()
		{
			using RegistryKey registryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Valve\\Steam");
			if (registryKey == null)
			{
				return null;
			}
			return registryKey.GetValue("SteamExe") as string;
		}
	}
}
namespace DiscordRPC.Message
{
	public class CloseMessage : IMessage
	{
		public override MessageType Type => MessageType.Close;

		public string Reason { get; internal set; }

		public int Code { get; internal set; }

		internal CloseMessage()
		{
		}

		internal CloseMessage(string reason)
		{
			Reason = reason;
		}
	}
	public class ConnectionEstablishedMessage : IMessage
	{
		public override MessageType Type => MessageType.ConnectionEstablished;

		public int ConnectedPipe { get; internal set; }
	}
	public class ConnectionFailedMessage : IMessage
	{
		public override MessageType Type => MessageType.ConnectionFailed;

		public int FailedPipe { get; internal set; }
	}
	public class ErrorMessage : IMessage
	{
		public override MessageType Type => MessageType.Error;

		[JsonProperty("code")]
		public ErrorCode Code { get; internal set; }

		[JsonProperty("message")]
		public string Message { get; internal set; }
	}
	public enum ErrorCode
	{
		Success = 0,
		PipeException = 1,
		ReadCorrupt = 2,
		NotImplemented = 10,
		UnkownError = 1000,
		InvalidPayload = 4000,
		InvalidCommand = 4002,
		InvalidEvent = 4004
	}
	public abstract class IMessage
	{
		private DateTime _timecreated;

		public abstract MessageType Type { get; }

		public DateTime TimeCreated => _timecreated;

		public IMessage()
		{
			_timecreated = DateTime.Now;
		}
	}
	public class JoinMessage : IMessage
	{
		public override MessageType Type => MessageType.Join;

		[JsonProperty("secret")]
		public string Secret { get; internal set; }
	}
	public class JoinRequestMessage : IMessage
	{
		public override MessageType Type => MessageType.JoinRequest;

		[JsonProperty("user")]
		public User User { get; internal set; }
	}
	public enum MessageType
	{
		Ready,
		Close,
		Error,
		PresenceUpdate,
		Subscribe,
		Unsubscribe,
		Join,
		Spectate,
		JoinRequest,
		ConnectionEstablished,
		ConnectionFailed
	}
	public class PresenceMessage : IMessage
	{
		public override MessageType Type => MessageType.PresenceUpdate;

		public BaseRichPresence Presence { get; internal set; }

		public string Name { get; internal set; }

		public string ApplicationID { get; internal set; }

		internal PresenceMessage()
			: this(null)
		{
		}

		internal PresenceMessage(RichPresenceResponse rpr)
		{
			if (rpr == null)
			{
				Presence = null;
				Name = "No Rich Presence";
				ApplicationID = "";
			}
			else
			{
				Presence = rpr;
				Name = rpr.Name;
				ApplicationID = rpr.ClientID;
			}
		}
	}
	public class ReadyMessage : IMessage
	{
		public override MessageType Type => MessageType.Ready;

		[JsonProperty("config")]
		public Configuration Configuration { get; set; }

		[JsonProperty("user")]
		public User User { get; set; }

		[JsonProperty("v")]
		public int Version { get; set; }
	}
	public class SpectateMessage : JoinMessage
	{
		public override MessageType Type => MessageType.Spectate;
	}
	public class SubscribeMessage : IMessage
	{
		public override MessageType Type => MessageType.Subscribe;

		public EventType Event { get; internal set; }

		internal SubscribeMessage(ServerEvent evt)
		{
			switch (evt)
			{
			default:
				Event = EventType.Join;
				break;
			case ServerEvent.ActivityJoinRequest:
				Event = EventType.JoinRequest;
				break;
			case ServerEvent.ActivitySpectate:
				Event = EventType.Spectate;
				break;
			}
		}
	}
	public class UnsubscribeMessage : IMessage
	{
		public override MessageType Type => MessageType.Unsubscribe;

		public EventType Event { get; internal set; }

		internal UnsubscribeMessage(ServerEvent evt)
		{
			switch (evt)
			{
			default:
				Event = EventType.Join;
				break;
			case ServerEvent.ActivityJoinRequest:
				Event = EventType.JoinRequest;
				break;
			case ServerEvent.ActivitySpectate:
				Event = EventType.Spectate;
				break;
			}
		}
	}
}
namespace DiscordRPC.Logging
{
	public class ConsoleLogger : ILogger
	{
		public LogLevel Level { get; set; }

		public bool Coloured { get; set; }

		public bool Colored
		{
			get
			{
				return Coloured;
			}
			set
			{
				Coloured = value;
			}
		}

		public ConsoleLogger()
		{
			Level = LogLevel.Info;
			Coloured = false;
		}

		public ConsoleLogger(LogLevel level, bool coloured = false)
		{
			Level = level;
			Coloured = coloured;
		}

		public void Trace(string message, params object[] args)
		{
			if (Level <= LogLevel.Trace)
			{
				if (Coloured)
				{
					Console.ForegroundColor = ConsoleColor.Gray;
				}
				Console.WriteLine("TRACE: " + message, args);
			}
		}

		public void Info(string message, params object[] args)
		{
			if (Level <= LogLevel.Info)
			{
				if (Coloured)
				{
					Console.ForegroundColor = ConsoleColor.White;
				}
				Console.WriteLine("INFO: " + message, args);
			}
		}

		public void Warning(string message, params object[] args)
		{
			if (Level <= LogLevel.Warning)
			{
				if (Coloured)
				{
					Console.ForegroundColor = ConsoleColor.Yellow;
				}
				Console.WriteLine("WARN: " + message, args);
			}
		}

		public void Error(string message, params object[] args)
		{
			if (Level <= LogLevel.Error)
			{
				if (Coloured)
				{
					Console.ForegroundColor = ConsoleColor.Red;
				}
				Console.WriteLine("ERR : " + message, args);
			}
		}
	}
	public class FileLogger : ILogger
	{
		private object filelock;

		public LogLevel Level { get; set; }

		public string File { get; set; }

		public FileLogger(string path)
			: this(path, LogLevel.Info)
		{
		}

		public FileLogger(string path, LogLevel level)
		{
			Level = level;
			File = path;
			filelock = new object();
		}

		public void Trace(string message, params object[] args)
		{
			if (Level > LogLevel.Trace)
			{
				return;
			}
			lock (filelock)
			{
				System.IO.File.AppendAllText(File, "\r\nTRCE: " + ((args.Length != 0) ? string.Format(message, args) : message));
			}
		}

		public void Info(string message, params object[] args)
		{
			if (Level > LogLevel.Info)
			{
				return;
			}
			lock (filelock)
			{
				System.IO.File.AppendAllText(File, "\r\nINFO: " + ((args.Length != 0) ? string.Format(message, args) : message));
			}
		}

		public void Warning(string message, params object[] args)
		{
			if (Level > LogLevel.Warning)
			{
				return;
			}
			lock (filelock)
			{
				System.IO.File.AppendAllText(File, "\r\nWARN: " + ((args.Length != 0) ? string.Format(message, args) : message));
			}
		}

		public void Error(string message, params object[] args)
		{
			if (Level > LogLevel.Error)
			{
				return;
			}
			lock (filelock)
			{
				System.IO.File.AppendAllText(File, "\r\nERR : " + ((args.Length != 0) ? string.Format(message, args) : message));
			}
		}
	}
	public interface ILogger
	{
		LogLevel Level { get; set; }

		void Trace(string message, params object[] args);

		void Info(string message, params object[] args);

		void Warning(string message, params object[] args);

		void Error(string message, params object[] args);
	}
	public enum LogLevel
	{
		Trace = 1,
		Info = 2,
		Warning = 3,
		Error = 4,
		None = 256
	}
	public class NullLogger : ILogger
	{
		public LogLevel Level { get; set; }

		public void Trace(string message, params object[] args)
		{
		}

		public void Info(string message, params object[] args)
		{
		}

		public void Warning(string message, params object[] args)
		{
		}

		public void Error(string message, params object[] args)
		{
		}
	}
}
namespace DiscordRPC.IO
{
	internal class Handshake
	{
		[JsonProperty("v")]
		public int Version { get; set; }

		[JsonProperty("client_id")]
		public string ClientID { get; set; }
	}
	public interface INamedPipeClient : IDisposable
	{
		ILogger Logger { get; set; }

		bool IsConnected { get; }

		int ConnectedPipe { get; }

		bool Connect(int pipe);

		bool ReadFrame(out PipeFrame frame);

		bool WriteFrame(PipeFrame frame);

		void Close();
	}
	public sealed class ManagedNamedPipeClient : INamedPipeClient, IDisposable
	{
		private const string PIPE_NAME = "discord-ipc-{0}";

		private int _connectedPipe;

		private NamedPipeClientStream _stream;

		private byte[] _buffer = new byte[PipeFrame.MAX_SIZE];

		private Queue<PipeFrame> _framequeue = new Queue<PipeFrame>();

		private object _framequeuelock = new object();

		private volatile bool _isDisposed = false;

		private volatile bool _isClosed = true;

		private object l_stream = new object();

		public ILogger Logger { get; set; }

		public bool IsConnected
		{
			get
			{
				if (_isClosed)
				{
					return false;
				}
				lock (l_stream)
				{
					return _stream != null && _stream.IsConnected;
				}
			}
		}

		public int ConnectedPipe => _connectedPipe;

		public ManagedNamedPipeClient()
		{
			_buffer = new byte[PipeFrame.MAX_SIZE];
			Logger = new NullLogger();
			_stream = null;
		}

		public bool Connect(int pipe)
		{
			Logger.Trace("ManagedNamedPipeClient.Connection(" + pipe + ")");
			if (_isDisposed)
			{
				throw new ObjectDisposedException("NamedPipe");
			}
			if (pipe > 9)
			{
				throw new ArgumentOutOfRangeException("pipe", "Argument cannot be greater than 9");
			}
			if (pipe < 0)
			{
				for (int i = 0; i < 10; i++)
				{
					if (AttemptConnection(i) || AttemptConnection(i, isSandbox: true))
					{
						BeginReadStream();
						return true;
					}
				}
			}
			else if (AttemptConnection(pipe) || AttemptConnection(pipe, isSandbox: true))
			{
				BeginReadStream();
				return true;
			}
			return false;
		}

		private bool AttemptConnection(int pipe, bool isSandbox = false)
		{
			if (_isDisposed)
			{
				throw new ObjectDisposedException("_stream");
			}
			string text = (isSandbox ? GetPipeSandbox() : "");
			if (isSandbox && text == null)
			{
				Logger.Trace("Skipping sandbox connection.");
				return false;
			}
			Logger.Trace("Connection Attempt " + pipe + " (" + text + ")");
			string pipeName = GetPipeName(pipe, text);
			try
			{
				lock (l_stream)
				{
					Logger.Info("Attempting to connect to " + pipeName);
					_stream = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
					_stream.Connect(1000);
					Logger.Trace("Waiting for connection...");
					do
					{
						Thread.Sleep(10);
					}
					while (!_stream.IsConnected);
				}
				Logger.Info("Connected to " + pipeName);
				_connectedPipe = pipe;
				_isClosed = false;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed connection to {0}. {1}", pipeName, ex.Message);
				Close();
			}
			Logger.Trace("Done. Result: {0}", _isClosed);
			return !_isClosed;
		}

		private void BeginReadStream()
		{
			if (_isClosed)
			{
				return;
			}
			try
			{
				lock (l_stream)
				{
					if (_stream != null && _stream.IsConnected)
					{
						Logger.Trace("Begining Read of {0} bytes", _buffer.Length);
						_stream.BeginRead(_buffer, 0, _buffer.Length, EndReadStream, _stream.IsConnected);
					}
				}
			}
			catch (ObjectDisposedException)
			{
				Logger.Warning("Attempted to start reading from a disposed pipe");
			}
			catch (InvalidOperationException)
			{
				Logger.Warning("Attempted to start reading from a closed pipe");
			}
			catch (Exception ex3)
			{
				Logger.Error("An exception occured while starting to read a stream: {0}", ex3.Message);
				Logger.Error(ex3.StackTrace);
			}
		}

		private void EndReadStream(IAsyncResult callback)
		{
			Logger.Trace("Ending Read");
			int num = 0;
			try
			{
				lock (l_stream)
				{
					if (_stream == null || !_stream.IsConnected)
					{
						return;
					}
					num = _stream.EndRead(callback);
				}
			}
			catch (IOException)
			{
				Logger.Warning("Attempted to end reading from a closed pipe");
				return;
			}
			catch (NullReferenceException)
			{
				Logger.Warning("Attempted to read from a null pipe");
				return;
			}
			catch (ObjectDisposedException)
			{
				Logger.Warning("Attemped to end reading from a disposed pipe");
				return;
			}
			catch (Exception ex4)
			{
				Logger.Error("An exception occured while ending a read of a stream: {0}", ex4.Message);
				Logger.Error(ex4.StackTrace);
				return;
			}
			Logger.Trace("Read {0} bytes", num);
			if (num > 0)
			{
				using MemoryStream stream = new MemoryStream(_buffer, 0, num);
				try
				{
					PipeFrame item = default(PipeFrame);
					if (item.ReadStream(stream))
					{
						Logger.Trace("Read a frame: {0}", item.Opcode);
						lock (_framequeuelock)
						{
							_framequeue.Enqueue(item);
						}
					}
					else
					{
						Logger.Error("Pipe failed to read from the data received by the stream.");
						Close();
					}
				}
				catch (Exception ex5)
				{
					Logger.Error("A exception has occured while trying to parse the pipe data: " + ex5.Message);
					Close();
				}
			}
			else if (IsUnix())
			{
				Logger.Error("Empty frame was read on " + Environment.OSVersion.ToString() + ", aborting.");
				Close();
			}
			else
			{
				Logger.Warning("Empty frame was read. Please send report to Lachee.");
			}
			if (!_isClosed && IsConnected)
			{
				Logger.Trace("Starting another read");
				BeginReadStream();
			}
		}

		public bool ReadFrame(out PipeFrame frame)
		{
			if (_isDisposed)
			{
				throw new ObjectDisposedException("_stream");
			}
			lock (_framequeuelock)
			{
				if (_framequeue.Count == 0)
				{
					frame = default(PipeFrame);
					return false;
				}
				frame = _framequeue.Dequeue();
				return true;
			}
		}

		public bool WriteFrame(PipeFrame frame)
		{
			if (_isDisposed)
			{
				throw new ObjectDisposedException("_stream");
			}
			if (_isClosed || !IsConnected)
			{
				Logger.Error("Failed to write frame because the stream is closed");
				return false;
			}
			try
			{
				frame.WriteStream(_stream);
				return true;
			}
			catch (IOException ex)
			{
				Logger.Error("Failed to write frame because of a IO Exception: {0}", ex.Message);
			}
			catch (ObjectDisposedException)
			{
				Logger.Warning("Failed to write frame as the stream was already disposed");
			}
			catch (InvalidOperationException)
			{
				Logger.Warning("Failed to write frame because of a invalid operation");
			}
			return false;
		}

		public void Close()
		{
			if (_isClosed)
			{
				Logger.Warning("Tried to close a already closed pipe.");
				return;
			}
			try
			{
				lock (l_stream)
				{
					if (_stream != null)
					{
						try
						{
							_stream.Flush();
							_stream.Dispose();
						}
						catch (Exception)
						{
						}
						_stream = null;
						_isClosed = true;
					}
					else
					{
						Logger.Warning("Stream was closed, but no stream was available to begin with!");
					}
				}
			}
			catch (ObjectDisposedException)
			{
				Logger.Warning("Tried to dispose already disposed stream");
			}
			finally
			{
				_isClosed = true;
				_connectedPipe = -1;
			}
		}

		public void Dispose()
		{
			if (_isDisposed)
			{
				return;
			}
			if (!_isClosed)
			{
				Close();
			}
			lock (l_stream)
			{
				if (_stream != null)
				{
					_stream.Dispose();
					_stream = null;
				}
			}
			_isDisposed = true;
		}

		public static string GetPipeName(int pipe, string sandbox = "")
		{
			if (!IsUnix())
			{
				return sandbox + $"discord-ipc-{pipe}";
			}
			return Path.Combine(GetTemporaryDirectory(), sandbox + $"discord-ipc-{pipe}");
		}

		public static string GetPipeSandbox()
		{
			PlatformID platform = Environment.OSVersion.Platform;
			PlatformID platformID = platform;
			if (platformID != PlatformID.Unix)
			{
				return null;
			}
			return "snap.discord/";
		}

		private static string GetTemporaryDirectory()
		{
			string text = null;
			text = text ?? Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR");
			text = text ?? Environment.GetEnvironmentVariable("TMPDIR");
			text = text ?? Environment.GetEnvironmentVariable("TMP");
			text = text ?? Environment.GetEnvironmentVariable("TEMP");
			return text ?? "/tmp";
		}

		public static bool IsUnix()
		{
			PlatformID platform = Environment.OSVersion.Platform;
			PlatformID platformID = platform;
			if (platformID != PlatformID.Unix && platformID != PlatformID.MacOSX)
			{
				return false;
			}
			return true;
		}
	}
	public enum Opcode : uint
	{
		Handshake,
		Frame,
		Close,
		Ping,
		Pong
	}
	public struct PipeFrame
	{
		public static readonly int MAX_SIZE = 16384;

		public Opcode Opcode { get; set; }

		public uint Length => (uint)Data.Length;

		public byte[] Data { get; set; }

		public string Message
		{
			get
			{
				return GetMessage();
			}
			set
			{
				SetMessage(value);
			}
		}

		public Encoding MessageEncoding => Encoding.UTF8;

		public PipeFrame(Opcode opcode, object data)
		{
			Opcode = opcode;
			Data = null;
			SetObject(data);
		}

		private void SetMessage(string str)
		{
			Data = MessageEncoding.GetBytes(str);
		}

		private string GetMessage()
		{
			return MessageEncoding.GetString(Data);
		}

		public void SetObject(object obj)
		{
			string message = JsonConvert.SerializeObject(obj);
			SetMessage(message);
		}

		public void SetObject(Opcode opcode, object obj)
		{
			Opcode = opcode;
			SetObject(obj);
		}

		public T GetObject<T>()
		{
			string message = GetMessage();
			return JsonConvert.DeserializeObject<T>(message);
		}

		public bool ReadStream(Stream stream)
		{
			if (!TryReadUInt32(stream, out var value))
			{
				return false;
			}
			if (!TryReadUInt32(stream, out var value2))
			{
				return false;
			}
			uint num = value2;
			using MemoryStream memoryStream = new MemoryStream();
			byte[] array = new byte[Min(2048, value2)];
			int count;
			while ((count = stream.Read(array, 0, Min(array.Length, num))) > 0)
			{
				num -= value2;
				memoryStream.Write(array, 0, count);
			}
			byte[] array2 = memoryStream.ToArray();
			if (array2.LongLength != value2)
			{
				return false;
			}
			Opcode = (Opcode)value;
			Data = array2;
			return true;
		}

		private int Min(int a, uint b)
		{
			if (b >= a)
			{
				return a;
			}
			return (int)b;
		}

		private bool TryReadUInt32(Stream stream, out uint value)
		{
			byte[] array = new byte[4];
			int num = stream.Read(array, 0, array.Length);
			if (num != 4)
			{
				value = 0u;
				return false;
			}
			value = BitConverter.ToUInt32(array, 0);
			return true;
		}

		public void WriteStream(Stream stream)
		{
			byte[] bytes = BitConverter.GetBytes((uint)Opcode);
			byte[] bytes2 = BitConverter.GetBytes(Length);
			byte[] array = new byte[bytes.Length + bytes2.Length + Data.Length];
			bytes.CopyTo(array, 0);
			bytes2.CopyTo(array, bytes.Length);
			Data.CopyTo(array, bytes.Length + bytes2.Length);
			stream.Write(array, 0, array.Length);
		}
	}
}
namespace DiscordRPC.Helper
{
	internal class BackoffDelay
	{
		private int _current;

		private int _fails;

		public int Maximum { get; private set; }

		public int Minimum { get; private set; }

		public int Current => _current;

		public int Fails => _fails;

		public Random Random { get; set; }

		private BackoffDelay()
		{
		}

		public BackoffDelay(int min, int max)
			: this(min, max, new Random())
		{
		}

		public BackoffDelay(int min, int max, Random random)
		{
			Minimum = min;
			Maximum = max;
			_current = min;
			_fails = 0;
			Random = random;
		}

		public void Reset()
		{
			_fails = 0;
			_current = Minimum;
		}

		public int NextDelay()
		{
			_fails++;
			double num = (float)(Maximum - Minimum) / 100f;
			_current = (int)Math.Floor(num * (double)_fails) + Minimum;
			return Math.Min(Math.Max(_current, Minimum), Maximum);
		}
	}
	public static class StringTools
	{
		public static string GetNullOrString(this string str)
		{
			return (str.Length == 0 || string.IsNullOrEmpty(str.Trim())) ? null : str;
		}

		public static bool WithinLength(this string str, int bytes)
		{
			return str.WithinLength(bytes, Encoding.UTF8);
		}

		public static bool WithinLength(this string str, int bytes, Encoding encoding)
		{
			return encoding.GetByteCount(str) <= bytes;
		}

		public static string ToCamelCase(this string str)
		{
			return (from s in str?.ToLower().Split(new string[2] { "_", " " }, StringSplitOptions.RemoveEmptyEntries)
				select char.ToUpper(s[0]) + s.Substring(1, s.Length - 1)).Aggregate(string.Empty, (string s1, string s2) => s1 + s2);
		}

		public static string ToSnakeCase(this string str)
		{
			if (str == null)
			{
				return null;
			}
			string text = string.Concat(str.Select((char x, int i) => (i > 0 && char.IsUpper(x)) ? ("_" + x) : x.ToString()).ToArray());
			return text.ToUpper();
		}
	}
}
namespace DiscordRPC.Exceptions
{
	public class BadPresenceException : Exception
	{
		internal BadPresenceException(string message)
			: base(message)
		{
		}
	}
	public class InvalidConfigurationException : Exception
	{
		internal InvalidConfigurationException(string message)
			: base(message)
		{
		}
	}
	[Obsolete("Not actually used anywhere")]
	public class InvalidPipeException : Exception
	{
		internal InvalidPipeException(string message)
			: base(message)
		{
		}
	}
	public class StringOutOfRangeException : Exception
	{
		public int MaximumLength { get; private set; }

		public int MinimumLength { get; private set; }

		internal StringOutOfRangeException(string message, int min, int max)
			: base(message)
		{
			MinimumLength = min;
			MaximumLength = max;
		}

		internal StringOutOfRangeException(int minumum, int max)
			: this("Length of string is out of range. Expected a value between " + minumum + " and " + max, minumum, max)
		{
		}

		internal StringOutOfRangeException(int max)
			: this("Length of string is out of range. Expected a value with a maximum length of " + max, 0, max)
		{
		}
	}
	public class UninitializedException : Exception
	{
		internal UninitializedException(string message)
			: base(message)
		{
		}

		internal UninitializedException()
			: this("Cannot perform action because the client has not been initialized yet or has been deinitialized.")
		{
		}
	}
}
namespace DiscordRPC.Events
{
	public delegate void OnReadyEvent(object sender, ReadyMessage args);
	public delegate void OnCloseEvent(object sender, CloseMessage args);
	public delegate void OnErrorEvent(object sender, ErrorMessage args);
	public delegate void OnPresenceUpdateEvent(object sender, PresenceMessage args);
	public delegate void OnSubscribeEvent(object sender, SubscribeMessage args);
	public delegate void OnUnsubscribeEvent(object sender, UnsubscribeMessage args);
	public delegate void OnJoinEvent(object sender, JoinMessage args);
	public delegate void OnSpectateEvent(object sender, SpectateMessage args);
	public delegate void OnJoinRequestedEvent(object sender, JoinRequestMessage args);
	public delegate void OnConnectionEstablishedEvent(object sender, ConnectionEstablishedMessage args);
	public delegate void OnConnectionFailedEvent(object sender, ConnectionFailedMessage args);
	public delegate void OnRpcMessageEvent(object sender, IMessage msg);
}
namespace DiscordRPC.Converters
{
	internal class EnumSnakeCaseConverter : JsonConverter
	{
		public override bool CanConvert(Type objectType)
		{
			return objectType.IsEnum;
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			if (reader.Value == null)
			{
				return null;
			}
			object obj = null;
			if (TryParseEnum(objectType, (string)reader.Value, out obj))
			{
				return obj;
			}
			return existingValue;
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			Type type = value.GetType();
			string text = Enum.GetName(type, value);
			MemberInfo[] members = type.GetMembers(BindingFlags.Static | BindingFlags.Public);
			MemberInfo[] array = members;
			foreach (MemberInfo memberInfo in array)
			{
				if (memberInfo.Name.Equals(text))
				{
					object[] customAttributes = memberInfo.GetCustomAttributes(typeof(EnumValueAttribute), inherit: true);
					if (customAttributes.Length != 0)
					{
						text = ((EnumValueAttribute)customAttributes[0]).Value;
					}
				}
			}
			writer.WriteValue(text);
		}

		public bool TryParseEnum(Type enumType, string str, out object obj)
		{
			if (str == null)
			{
				obj = null;
				return false;
			}
			Type type = enumType;
			if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				type = type.GetGenericArguments().First();
			}
			if (!type.IsEnum)
			{
				obj = null;
				return false;
			}
			MemberInfo[] members = type.GetMembers(BindingFlags.Static | BindingFlags.Public);
			MemberInfo[] array = members;
			foreach (MemberInfo memberInfo in array)
			{
				object[] customAttributes = memberInfo.GetCustomAttributes(typeof(EnumValueAttribute), inherit: true);
				object[] array2 = customAttributes;
				foreach (object obj2 in array2)
				{
					EnumValueAttribute enumValueAttribute = (EnumValueAttribute)obj2;
					if (str.Equals(enumValueAttribute.Value))
					{
						obj = Enum.Parse(type, memberInfo.Name, ignoreCase: true);
						return true;
					}
				}
			}
			obj = null;
			return false;
		}
	}
	internal class EnumValueAttribute : Attribute
	{
		public string Value { get; set; }

		public EnumValueAttribute(string value)
		{
			Value = value;
		}
	}
}

Cuno-DiscordRichPresence-1.2.1/Newtonsoft.Json.dll

Decompiled 2 months 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.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
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.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(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[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("12.0.2.23222")]
[assembly: AssemblyInformationalVersion("12.0.2+4ab34b0461fb595805d092a46a58f35f66c84d6a")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyTitle("Json.NET .NET Standard 2.0")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("12.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
	{
	}
}
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 = num & _mask;
			for (Entry entry = _entries[num3]; 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;
			_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 ?? false;
			}
			set
			{
				_isReference = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference ?? false;
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling ?? TypeNameHandling.None;
			}
			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) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		private static string EnsureDecimalPlace(string text)
		{
			if (text.IndexOf('.') != -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)
		{
			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 ?? MissingMemberHandling.Ignore;
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public NullValueHandling ItemNullValueHandling
		{
			get
			{
				return _itemNullValueHandling ?? NullValueHandling.Include;
			}
			set
			{
				_itemNullValueHandling = value;
			}
		}

		public Required ItemRequired
		{
			get
			{
				return _itemRequired ?? Required.Default;
			}
			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 ?? NullValueHandling.Include;
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling ?? DefaultValueHandling.Include;
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling ?? ObjectCreationHandling.Auto;
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public bool IsReference
		{
			get
			{
				return _isReference ?? false;
			}
			set
			{
				_isReference = value;
			}
		}

		public int Order
		{
			get
			{
				return _order ?? 0;
			}
			set
			{
				_order = value;
			}
		}

		public Required Required
		{
			get
			{
				return _required ?? Required.Default;
			}
			set
			{
				_required = value;
			}
		}

		public string PropertyName { get; set; }

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference ?? false;
			}
			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;
			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;
				object obj;
				if ((obj = value) is int)
				{
					return (int)obj;
				}
				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 (string.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;
				object obj;
				if ((obj = value) is double)
				{
					return (double)obj;
				}
				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 (string.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 (string.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;
				object obj;
				if ((obj = value) is decimal)
				{
					return (decimal)obj;
				}
				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 (string.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:
			{
				string s = (string)Value;
				return ReadDateTimeString(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		internal DateTime? ReadDateTimeString(string s)
		{
			if (string.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 (string.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 == null)
				{
					return null;
				}
				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 ?? Formatting.None;
			}
			set
			{
				_formatting = value;
			}
		}

		public virtual DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling ?? DateFormatHandling.IsoDateFormat;
			}
			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 ?? FloatParseHandling.Double;
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public virtual FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling ?? FloatFormatHandling.String;
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public virtual StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling ?? StringEscapeHandling.Default;
			}
			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 ?? false;
			}
			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 var previousCulture, out var previousDateTimeZoneHandling, out var previousDateParseHandling, out var previousFloatParseHandling, out var previousMaxDepth, out var 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 var previousCulture, out var previousDateTimeZoneHandling, out var previousDateParseHandling, out var previousFloatParseHandling, out var previousMaxDepth, out var 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;
		}

		private 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 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 ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling ?? MissingMemberHandling.Ignore;
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling ?? ObjectCreationHandling.Auto;
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling ?? NullValueHandling.Include;
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling ?? DefaultValueHandling.Include;
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public IList<JsonConverter> Converters { get; set; }

		public PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling ?? PreserveReferencesHandling.None;
			}
			set
			{
				_preserveReferencesHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling ?? MetadataPropertyHandling.Default;
			}
			set
			{
				_metadataPropertyHandling = value;
			}
		}

		[Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")]
		public FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return (FormatterAssemblyStyle)TypeNameAssemblyFormatHandling;
			}
			set
			{
				TypeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value;
			}
		}

		public TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling
		{
			get
			{
				return _typeNameAssemblyFormatHandling ?? TypeNameAssemblyFormatHandling.Simple;
			}
			set
			{
				_typeNameAssemblyFormatHandling = value;
			}
		}

		public ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling ?? ConstructorHandling.Default;
			}
			set
			{
				_constructorHandling = value;
			}
		}

		public IContractResolver ContractResolver { get; set; }

		public IEqualityComparer EqualityComparer { get; set; }

		[Obsolete("ReferenceResolver property is obsolete. Use the ReferenceResolverProvider property to set the IReferenceResolver: settings.ReferenceResolverProvider = () => resolver")]
		public IReferenceResolver ReferenceResolver
		{
			get
			{
				return ReferenceResolverProvider?.Invoke();
			}
			set
			{
				ReferenceResolverProvider = ((value != null) ? ((Func<IReferenceResolver>)(() => value)) : null);
			}
		}

		public Func<IReferenceResolver> ReferenceResolverProvider { get; set; }

		public ITraceWriter TraceWriter { get; set; }

		[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
		public SerializationBinder Binder
		{
			get
			{
				if (SerializationBinder == null)
				{
					return null;
				}
				if (SerializationBinder is SerializationBinderAdapter serializationBinderAdapter)
				{
					return serializationBinderAdapter.SerializationBinder;
				}
				throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
			}
			set
			{
				SerializationBinder = ((value == null) ? null : new SerializationBinderAdapter(value));
			}
		}

		public ISerializationBinder SerializationBinder { get; set; }

		public EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> Error { get; set; }

		public StreamingContext Context
		{

Cuno-DiscordRichPresence-1.2.1/UnityNamedPipe.dll

Decompiled 2 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Lachee.IO.Exceptions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("UnityNamedPipe")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("UnityNamedPipe")]
[assembly: AssemblyTitle("UnityNamedPipe")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Lachee.IO
{
	public class NamedPipeClientStream : Stream
	{
		private static class Native
		{
			private const string LIBRARY_NAME = "NativeNamedPipe";

			[DllImport("NativeNamedPipe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "createClient")]
			public static extern IntPtr CreateClient();

			[DllImport("NativeNamedPipe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "destroyClient")]
			public static extern void DestroyClient(IntPtr client);

			[DllImport("NativeNamedPipe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "isConnected")]
			public static extern bool IsConnected([MarshalAs(UnmanagedType.SysInt)] IntPtr client);

			[DllImport("NativeNamedPipe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "open")]
			public static extern int Open(IntPtr client, [MarshalAs(UnmanagedType.LPStr)] string pipename);

			[DllImport("NativeNamedPipe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "close")]
			public static extern void Close(IntPtr client);

			[DllImport("NativeNamedPipe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "readFrame")]
			public static extern int ReadFrame(IntPtr client, IntPtr buffer, int length);

			[DllImport("NativeNamedPipe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "writeFrame")]
			public static extern int WriteFrame(IntPtr client, IntPtr buffer, int length);
		}

		private IntPtr ptr;

		private bool _isDisposed;

		private static readonly string s_pipePrefix = Path.Combine(Path.GetTempPath(), "CoreFxPipe_");

		public override bool CanRead => true;

		public override bool CanSeek => false;

		public override bool CanWrite => true;

		public override long Length => 0L;

		public override long Position
		{
			get
			{
				return 0L;
			}
			set
			{
			}
		}

		public bool IsConnected => Native.IsConnected(ptr);

		public string PipeName { get; }

		public NamedPipeClientStream(string server, string pipeName)
		{
			ptr = Native.CreateClient();
			PipeName = FormatPipe(server, pipeName);
			Console.WriteLine("Created new NamedPipeClientStream '{0}' => '{1}'", pipeName, PipeName);
		}

		~NamedPipeClientStream()
		{
			Dispose(disposing: false);
		}

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			if (!_isDisposed)
			{
				Disconnect();
				Native.DestroyClient(ptr);
				_isDisposed = true;
			}
		}

		private static string FormatPipe(string server, string pipeName)
		{
			PlatformID platform = Environment.OSVersion.Platform;
			if (platform == PlatformID.Win32NT || platform != PlatformID.Unix)
			{
				return $"\\\\{server}\\pipe\\{pipeName}";
			}
			if (server != ".")
			{
				throw new PlatformNotSupportedException("Remote pipes are not supported on this platform.");
			}
			return s_pipePrefix + pipeName;
		}

		public void Connect()
		{
			int err = Native.Open(ptr, PipeName);
			if (!IsConnected)
			{
				throw new NamedPipeOpenException(err);
			}
		}

		public void Disconnect()
		{
			Native.Close(ptr);
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			if (!IsConnected)
			{
				throw new NamedPipeConnectionException("Cannot read stream as pipe is not connected");
			}
			if (offset + count > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("count", "Cannot read as the count exceeds the buffer size");
			}
			int num = 0;
			int cb = Marshal.SizeOf(buffer[0]) * count;
			IntPtr intPtr = Marshal.AllocHGlobal(cb);
			try
			{
				num = Native.ReadFrame(ptr, intPtr, count);
				if (num <= 0)
				{
					if (num < 0)
					{
						throw new NamedPipeReadException(num);
					}
					return 0;
				}
				Marshal.Copy(intPtr, buffer, offset, num);
				return num;
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
			}
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			if (!IsConnected)
			{
				throw new NamedPipeConnectionException("Cannot write stream as pipe is not connected");
			}
			int cb = Marshal.SizeOf(buffer[0]) * count;
			IntPtr intPtr = Marshal.AllocHGlobal(cb);
			try
			{
				Marshal.Copy(buffer, offset, intPtr, count);
				int num = Native.WriteFrame(ptr, intPtr, count);
				if (num < 0)
				{
					throw new NamedPipeWriteException(num);
				}
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
			}
		}

		public override void Flush()
		{
			throw new NotSupportedException();
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw new NotSupportedException();
		}

		public override void SetLength(long value)
		{
			throw new NotSupportedException();
		}
	}
	internal class Program
	{
		private const string LIBRARY_NAME = "NativeNamedPipe";

		private const string PIPE_NAME = "testpipe";

		private static CancellationTokenSource source;

		[DllImport("NativeNamedPipe", CallingConvention = CallingConvention.Cdecl)]
		private static extern bool test(int a, int b, IntPtr @out);

		private static void TestPipe()
		{
			using NamedPipeClientStream namedPipeClientStream = new NamedPipeClientStream(".", "testpipe");
			try
			{
				Console.WriteLine("CLIENT: Connecting...");
				namedPipeClientStream.Connect();
				string text = "Hello World!";
				Console.WriteLine("CLIENT: Sending '{0}'...", text);
				byte[] bytes = Encoding.ASCII.GetBytes(text);
				namedPipeClientStream.Write(bytes, 0, bytes.Length);
				Console.WriteLine("CLIENT: Sent. Reading message...");
				text = "";
				int num = 0;
				byte[] array = new byte[2048];
				while ((num = namedPipeClientStream.Read(array, 0, array.Length)) == 0)
				{
					Console.Write(".");
					Thread.Sleep(1);
				}
				Console.WriteLine();
				text = Encoding.ASCII.GetString(array, 0, num);
				Console.WriteLine("CLIENT: Server said '{0}'", text);
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed pipe test: {0}", ex.Message);
			}
		}

		private static void Main(string[] args)
		{
			if (ValidateDll())
			{
				Console.WriteLine("Starting Server...");
				source = new CancellationTokenSource();
				Task.Factory.StartNew((Func<Task>)async delegate
				{
					await ServerIO(source.Token);
				}, source.Token);
				Console.WriteLine("How many times do you wish the test to be run?");
				string text = Console.ReadLine();
				if (string.IsNullOrWhiteSpace(text))
				{
					text = "1";
				}
				int num = int.Parse(text);
				for (int i = 0; i < num; i++)
				{
					Console.WriteLine("Testing Pipe #{0}....", i);
					TestPipe();
				}
				Console.WriteLine("Canceling Token...");
				source.Cancel();
				source.Dispose();
				Console.WriteLine("Press any key to exit.");
				Console.ReadKey(intercept: true);
			}
		}

		private static async Task ServerIO(CancellationToken token)
		{
			using NamedPipeServerStream server = new NamedPipeServerStream("testpipe", PipeDirection.InOut);
			while (!token.IsCancellationRequested)
			{
				Console.WriteLine("SERVER: Waiting for connection...");
				string message3 = "";
				await server.WaitForConnectionAsync(token);
				Console.WriteLine("SERVER: Connection established. Reading message...");
				byte[] buffer = new byte[2048];
				int bytesRead = await server.ReadAsync(buffer, 0, buffer.Length);
				Console.WriteLine("SERVER: Read {0} bytes", bytesRead);
				string msg = Encoding.ASCII.GetString(buffer, 0, bytesRead);
				message3 += msg;
				char[] chars = message3.ToCharArray();
				Array.Reverse((Array)chars);
				message3 = new string(chars);
				Console.WriteLine("SERVER: Message read. Returning message '{0}'...", message3);
				byte[] msgbytes = Encoding.ASCII.GetBytes(message3);
				await server.WriteAsync(msgbytes, 0, msgbytes.Length);
				Console.WriteLine("SERVER: Disconnecting...");
				server.Disconnect();
			}
		}

		private static bool ValidateDll()
		{
			IntPtr intPtr = Marshal.AllocHGlobal(4);
			try
			{
				return test(-10, 10, intPtr) && Marshal.ReadInt32(intPtr) == 0;
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed DLL Test!");
				Console.WriteLine(ex.Message);
				return false;
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
			}
		}
	}
}
namespace Lachee.IO.Exceptions
{
	public class NamedPipeConnectionException : Exception
	{
		internal NamedPipeConnectionException(string message)
			: base(message)
		{
		}
	}
	public class NamedPipeOpenException : Exception
	{
		public int ErrorCode { get; private set; }

		internal NamedPipeOpenException(int err)
			: base("An exception has occured while trying to open the pipe. Error Code: " + err)
		{
			ErrorCode = err;
		}
	}
	public class NamedPipeReadException : Exception
	{
		public int ErrorCode { get; private set; }

		internal NamedPipeReadException(int err)
			: base("An exception occured while reading from the pipe. Error Code: " + err)
		{
			ErrorCode = err;
		}
	}
	public class NamedPipeWriteException : Exception
	{
		public int ErrorCode { get; private set; }

		internal NamedPipeWriteException(int err)
			: base("An exception occured while reading from the pipe. Error Code: " + err)
		{
			ErrorCode = err;
		}
	}
}