Decompiled source of Server Manager v2.6.2

BepInEx/plugins/ServerManager/Newtonsoft.Json.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Schema, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: CLSCompliant(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
[assembly: AssemblyFileVersion("13.0.3.27908")]
[assembly: AssemblyInformationalVersion("13.0.3+0a2e291c0d9c0c7675d445703e51750363a549ef")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyTitle("Json.NET .NET 4.5")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JamesNK/Newtonsoft.Json")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("13.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
}
namespace Newtonsoft.Json
{
	public enum ConstructorHandling
	{
		Default,
		AllowNonPublicDefaultConstructor
	}
	public enum DateFormatHandling
	{
		IsoDateFormat,
		MicrosoftDateFormat
	}
	public enum DateParseHandling
	{
		None,
		DateTime,
		DateTimeOffset
	}
	public enum DateTimeZoneHandling
	{
		Local,
		Utc,
		Unspecified,
		RoundtripKind
	}
	public class DefaultJsonNameTable : JsonNameTable
	{
		private class Entry
		{
			internal readonly string Value;

			internal readonly int HashCode;

			internal Entry Next;

			internal Entry(string value, int hashCode, Entry next)
			{
				Value = value;
				HashCode = hashCode;
				Next = next;
			}
		}

		private static readonly int HashCodeRandomizer;

		private int _count;

		private Entry[] _entries;

		private int _mask = 31;

		static DefaultJsonNameTable()
		{
			HashCodeRandomizer = Environment.TickCount;
		}

		public DefaultJsonNameTable()
		{
			_entries = new Entry[_mask + 1];
		}

		public override string? Get(char[] key, int start, int length)
		{
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			num += (num << 7) ^ key[start];
			int num2 = start + length;
			for (int i = start + 1; i < num2; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			int num3 = Volatile.Read(ref _mask);
			int num4 = num & num3;
			for (Entry entry = _entries[num4]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && TextEquals(entry.Value, key, start, length))
				{
					return entry.Value;
				}
			}
			return null;
		}

		public string Add(string key)
		{
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			int length = key.Length;
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			for (int i = 0; i < key.Length; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal))
				{
					return entry.Value;
				}
			}
			return AddEntry(key, num);
		}

		private string AddEntry(string str, int hashCode)
		{
			int num = hashCode & _mask;
			Entry entry = new Entry(str, hashCode, _entries[num]);
			_entries[num] = entry;
			if (_count++ == _mask)
			{
				Grow();
			}
			return entry.Value;
		}

		private void Grow()
		{
			Entry[] entries = _entries;
			int num = _mask * 2 + 1;
			Entry[] array = new Entry[num + 1];
			for (int i = 0; i < entries.Length; i++)
			{
				Entry entry = entries[i];
				while (entry != null)
				{
					int num2 = entry.HashCode & num;
					Entry next = entry.Next;
					entry.Next = array[num2];
					array[num2] = entry;
					entry = next;
				}
			}
			_entries = array;
			Volatile.Write(ref _mask, num);
		}

		private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length)
		{
			if (str1.Length != str2Length)
			{
				return false;
			}
			for (int i = 0; i < str1.Length; i++)
			{
				if (str1[i] != str2[str2Start + i])
				{
					return false;
				}
			}
			return true;
		}
	}
	[Flags]
	public enum DefaultValueHandling
	{
		Include = 0,
		Ignore = 1,
		Populate = 2,
		IgnoreAndPopulate = 3
	}
	public enum FloatFormatHandling
	{
		String,
		Symbol,
		DefaultValue
	}
	public enum FloatParseHandling
	{
		Double,
		Decimal
	}
	public enum Formatting
	{
		None,
		Indented
	}
	public interface IArrayPool<T>
	{
		T[] Rent(int minimumLength);

		void Return(T[]? array);
	}
	public interface IJsonLineInfo
	{
		int LineNumber { get; }

		int LinePosition { get; }

		bool HasLineInfo();
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonArrayAttribute : JsonContainerAttribute
	{
		private bool _allowNullItems;

		public bool AllowNullItems
		{
			get
			{
				return _allowNullItems;
			}
			set
			{
				_allowNullItems = value;
			}
		}

		public JsonArrayAttribute()
		{
		}

		public JsonArrayAttribute(bool allowNullItems)
		{
			_allowNullItems = allowNullItems;
		}

		public JsonArrayAttribute(string id)
			: base(id)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
	public sealed class JsonConstructorAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public abstract class JsonContainerAttribute : Attribute
	{
		internal bool? _isReference;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		private Type? _namingStrategyType;

		private object[]? _namingStrategyParameters;

		public string? Id { get; set; }

		public string? Title { get; set; }

		public string? Description { get; set; }

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType
		{
			get
			{
				return _namingStrategyType;
			}
			set
			{
				_namingStrategyType = value;
				NamingStrategyInstance = null;
			}
		}

		public object[]? NamingStrategyParameters
		{
			get
			{
				return _namingStrategyParameters;
			}
			set
			{
				_namingStrategyParameters = value;
				NamingStrategyInstance = null;
			}
		}

		internal NamingStrategy? NamingStrategyInstance { get; set; }

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		protected JsonContainerAttribute()
		{
		}

		protected JsonContainerAttribute(string id)
		{
			Id = id;
		}
	}
	public static class JsonConvert
	{
		public static readonly string True = "true";

		public static readonly string False = "false";

		public static readonly string Null = "null";

		public static readonly string Undefined = "undefined";

		public static readonly string PositiveInfinity = "Infinity";

		public static readonly string NegativeInfinity = "-Infinity";

		public static readonly string NaN = "NaN";

		public static Func<JsonSerializerSettings>? DefaultSettings { get; set; }

		public static string ToString(DateTime value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
		}

		public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
		{
			DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling);
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(DateTimeOffset value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat);
		}

		public static string ToString(DateTimeOffset value, DateFormatHandling format)
		{
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(bool value)
		{
			if (!value)
			{
				return False;
			}
			return True;
		}

		public static string ToString(char value)
		{
			return ToString(char.ToString(value));
		}

		public static string ToString(Enum value)
		{
			return value.ToString("D");
		}

		public static string ToString(int value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(short value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ushort value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(uint value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(long value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		private static string ToStringInternal(BigInteger value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ulong value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(float value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value)))
			{
				return text;
			}
			if (floatFormatHandling == FloatFormatHandling.DefaultValue)
			{
				if (nullable)
				{
					return Null;
				}
				return "0.0";
			}
			return quoteChar + text + quoteChar;
		}

		public static string ToString(double value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureDecimalPlace(double value, string text)
		{
			if (double.IsNaN(value) || double.IsInfinity(value) || StringUtils.IndexOf(text, '.') != -1 || StringUtils.IndexOf(text, 'E') != -1 || StringUtils.IndexOf(text, 'e') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		private static string EnsureDecimalPlace(string text)
		{
			if (StringUtils.IndexOf(text, '.') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		public static string ToString(byte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(sbyte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(decimal value)
		{
			return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
		}

		public static string ToString(Guid value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(Guid value, char quoteChar)
		{
			string text = value.ToString("D", CultureInfo.InvariantCulture);
			string text2 = quoteChar.ToString(CultureInfo.InvariantCulture);
			return text2 + text + text2;
		}

		public static string ToString(TimeSpan value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(TimeSpan value, char quoteChar)
		{
			return ToString(value.ToString(), quoteChar);
		}

		public static string ToString(Uri? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ToString(value, '"');
		}

		internal static string ToString(Uri value, char quoteChar)
		{
			return ToString(value.OriginalString, quoteChar);
		}

		public static string ToString(string? value)
		{
			return ToString(value, '"');
		}

		public static string ToString(string? value, char delimiter)
		{
			return ToString(value, delimiter, StringEscapeHandling.Default);
		}

		public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling)
		{
			if (delimiter != '"' && delimiter != '\'')
			{
				throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter");
			}
			return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling);
		}

		public static string ToString(object? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ConvertUtils.GetTypeCode(value.GetType()) switch
			{
				PrimitiveTypeCode.String => ToString((string)value), 
				PrimitiveTypeCode.Char => ToString((char)value), 
				PrimitiveTypeCode.Boolean => ToString((bool)value), 
				PrimitiveTypeCode.SByte => ToString((sbyte)value), 
				PrimitiveTypeCode.Int16 => ToString((short)value), 
				PrimitiveTypeCode.UInt16 => ToString((ushort)value), 
				PrimitiveTypeCode.Int32 => ToString((int)value), 
				PrimitiveTypeCode.Byte => ToString((byte)value), 
				PrimitiveTypeCode.UInt32 => ToString((uint)value), 
				PrimitiveTypeCode.Int64 => ToString((long)value), 
				PrimitiveTypeCode.UInt64 => ToString((ulong)value), 
				PrimitiveTypeCode.Single => ToString((float)value), 
				PrimitiveTypeCode.Double => ToString((double)value), 
				PrimitiveTypeCode.DateTime => ToString((DateTime)value), 
				PrimitiveTypeCode.Decimal => ToString((decimal)value), 
				PrimitiveTypeCode.DBNull => Null, 
				PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), 
				PrimitiveTypeCode.Guid => ToString((Guid)value), 
				PrimitiveTypeCode.Uri => ToString((Uri)value), 
				PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), 
				PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value), 
				_ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), 
			};
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value)
		{
			return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting)
		{
			return SerializeObject(value, formatting, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			jsonSerializer.Formatting = formatting;
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer)
		{
			StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture);
			using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))
			{
				jsonTextWriter.Formatting = jsonSerializer.Formatting;
				jsonSerializer.Serialize(jsonTextWriter, value, type);
			}
			return stringWriter.ToString();
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value)
		{
			return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, JsonSerializerSettings settings)
		{
			return DeserializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type)
		{
			return DeserializeObject(value, type, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value)
		{
			return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
		{
			return DeserializeObject<T>(value);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings)
		{
			return DeserializeObject<T>(value, settings);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, params JsonConverter[] converters)
		{
			return (T)DeserializeObject(value, typeof(T), converters);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings)
		{
			return (T)DeserializeObject(value, typeof(T), settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return DeserializeObject(value, type, settings);
		}

		public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings)
		{
			ValidationUtils.ArgumentNotNull(value, "value");
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			if (!jsonSerializer.IsCheckAdditionalContentSet())
			{
				jsonSerializer.CheckAdditionalContent = true;
			}
			using JsonTextReader reader = new JsonTextReader(new StringReader(value));
			return jsonSerializer.Deserialize(reader, type);
		}

		[DebuggerStepThrough]
		public static void PopulateObject(string value, object target)
		{
			PopulateObject(value, target, null);
		}

		public static void PopulateObject(string value, object target, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			using JsonReader jsonReader = new JsonTextReader(new StringReader(value));
			jsonSerializer.Populate(jsonReader, target);
			if (settings == null || !settings.CheckAdditionalContent)
			{
				return;
			}
			while (jsonReader.Read())
			{
				if (jsonReader.TokenType != JsonToken.Comment)
				{
					throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object.");
				}
			}
		}

		public static string SerializeXmlNode(XmlNode? node)
		{
			return SerializeXmlNode(node, Formatting.None);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XmlDocument? DeserializeXmlNode(string value)
		{
			return DeserializeXmlNode(value, null);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter);
		}

		public static string SerializeXNode(XObject? node)
		{
			return SerializeXNode(node, Formatting.None);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting)
		{
			return SerializeXNode(node, formatting, omitRootObject: false);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XDocument? DeserializeXNode(string value)
		{
			return DeserializeXNode(value, null);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter);
		}
	}
	public abstract class JsonConverter
	{
		public virtual bool CanRead => true;

		public virtual bool CanWrite => true;

		public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer);

		public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer);

		public abstract bool CanConvert(Type objectType);
	}
	public abstract class JsonConverter<T> : JsonConverter
	{
		public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T))))
			{
				throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			WriteJson(writer, (T)value, serializer);
		}

		public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer);

		public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			bool flag = existingValue == null;
			if (!flag && !(existingValue is T))
			{
				throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer);
		}

		public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer);

		public sealed override bool CanConvert(Type objectType)
		{
			return typeof(T).IsAssignableFrom(objectType);
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonConverterAttribute : Attribute
	{
		private readonly Type _converterType;

		public Type ConverterType => _converterType;

		public object[]? ConverterParameters { get; }

		public JsonConverterAttribute(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			_converterType = converterType;
		}

		public JsonConverterAttribute(Type converterType, params object[] converterParameters)
			: this(converterType)
		{
			ConverterParameters = converterParameters;
		}
	}
	public class JsonConverterCollection : Collection<JsonConverter>
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonDictionaryAttribute : JsonContainerAttribute
	{
		public JsonDictionaryAttribute()
		{
		}

		public JsonDictionaryAttribute(string id)
			: base(id)
		{
		}
	}
	[Serializable]
	public class JsonException : Exception
	{
		public JsonException()
		{
		}

		public JsonException(string message)
			: base(message)
		{
		}

		public JsonException(string message, Exception? innerException)
			: base(message, innerException)
		{
		}

		public JsonException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			return new JsonException(message);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public class JsonExtensionDataAttribute : Attribute
	{
		public bool WriteData { get; set; }

		public bool ReadData { get; set; }

		public JsonExtensionDataAttribute()
		{
			WriteData = true;
			ReadData = true;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonIgnoreAttribute : Attribute
	{
	}
	public abstract class JsonNameTable
	{
		public abstract string? Get(char[] key, int start, int length);
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonObjectAttribute : JsonContainerAttribute
	{
		private MemberSerialization _memberSerialization;

		internal MissingMemberHandling? _missingMemberHandling;

		internal Required? _itemRequired;

		internal NullValueHandling? _itemNullValueHandling;

		public MemberSerialization MemberSerialization
		{
			get
			{
				return _memberSerialization;
			}
			set
			{
				_memberSerialization = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public NullValueHandling ItemNullValueHandling
		{
			get
			{
				return _itemNullValueHandling.GetValueOrDefault();
			}
			set
			{
				_itemNullValueHandling = value;
			}
		}

		public Required ItemRequired
		{
			get
			{
				return _itemRequired.GetValueOrDefault();
			}
			set
			{
				_itemRequired = value;
			}
		}

		public JsonObjectAttribute()
		{
		}

		public JsonObjectAttribute(MemberSerialization memberSerialization)
		{
			MemberSerialization = memberSerialization;
		}

		public JsonObjectAttribute(string id)
			: base(id)
		{
		}
	}
	internal enum JsonContainerType
	{
		None,
		Object,
		Array,
		Constructor
	}
	internal struct JsonPosition
	{
		private static readonly char[] SpecialCharacters = new char[18]
		{
			'.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t',
			'\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029'
		};

		internal JsonContainerType Type;

		internal int Position;

		internal string? PropertyName;

		internal bool HasIndex;

		public JsonPosition(JsonContainerType type)
		{
			Type = type;
			HasIndex = TypeHasIndex(type);
			Position = -1;
			PropertyName = null;
		}

		internal int CalculateLength()
		{
			switch (Type)
			{
			case JsonContainerType.Object:
				return PropertyName.Length + 5;
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				return MathUtils.IntLength((ulong)Position) + 2;
			default:
				throw new ArgumentOutOfRangeException("Type");
			}
		}

		internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer)
		{
			switch (Type)
			{
			case JsonContainerType.Object:
			{
				string propertyName = PropertyName;
				if (propertyName.IndexOfAny(SpecialCharacters) != -1)
				{
					sb.Append("['");
					if (writer == null)
					{
						writer = new StringWriter(sb);
					}
					JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer);
					sb.Append("']");
				}
				else
				{
					if (sb.Length > 0)
					{
						sb.Append('.');
					}
					sb.Append(propertyName);
				}
				break;
			}
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				sb.Append('[');
				sb.Append(Position);
				sb.Append(']');
				break;
			}
		}

		internal static bool TypeHasIndex(JsonContainerType type)
		{
			if (type != JsonContainerType.Array)
			{
				return type == JsonContainerType.Constructor;
			}
			return true;
		}

		internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
		{
			int num = 0;
			if (positions != null)
			{
				for (int i = 0; i < positions.Count; i++)
				{
					num += positions[i].CalculateLength();
				}
			}
			if (currentPosition.HasValue)
			{
				num += currentPosition.GetValueOrDefault().CalculateLength();
			}
			StringBuilder stringBuilder = new StringBuilder(num);
			StringWriter writer = null;
			char[] buffer = null;
			if (positions != null)
			{
				foreach (JsonPosition position in positions)
				{
					position.WriteTo(stringBuilder, ref writer, ref buffer);
				}
			}
			currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer);
			return stringBuilder.ToString();
		}

		internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message)
		{
			if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
			{
				message = message.Trim();
				if (!StringUtils.EndsWith(message, '.'))
				{
					message += ".";
				}
				message += " ";
			}
			message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
			}
			message += ".";
			return message;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonPropertyAttribute : Attribute
	{
		internal NullValueHandling? _nullValueHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal bool? _isReference;

		internal int? _order;

		internal Required? _required;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType { get; set; }

		public object[]? NamingStrategyParameters { get; set; }

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling.GetValueOrDefault();
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public int Order
		{
			get
			{
				return _order.GetValueOrDefault();
			}
			set
			{
				_order = value;
			}
		}

		public Required Required
		{
			get
			{
				return _required.GetValueOrDefault();
			}
			set
			{
				_required = value;
			}
		}

		public string? PropertyName { get; set; }

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public JsonPropertyAttribute()
		{
		}

		public JsonPropertyAttribute(string propertyName)
		{
			PropertyName = propertyName;
		}
	}
	public abstract class JsonReader : IDisposable
	{
		protected internal enum State
		{
			Start,
			Complete,
			Property,
			ObjectStart,
			Object,
			ArrayStart,
			Array,
			Closed,
			PostValue,
			ConstructorStart,
			Constructor,
			Error,
			Finished
		}

		private JsonToken _tokenType;

		private object? _value;

		internal char _quoteChar;

		internal State _currentState;

		private JsonPosition _currentPosition;

		private CultureInfo? _culture;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private int? _maxDepth;

		private bool _hasExceededMaxDepth;

		internal DateParseHandling _dateParseHandling;

		internal FloatParseHandling _floatParseHandling;

		private string? _dateFormatString;

		private List<JsonPosition>? _stack;

		protected State CurrentState => _currentState;

		public bool CloseInput { get; set; }

		public bool SupportMultipleContent { get; set; }

		public virtual char QuoteChar
		{
			get
			{
				return _quoteChar;
			}
			protected internal set
			{
				_quoteChar = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling;
			}
			set
			{
				if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateTimeZoneHandling = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling;
			}
			set
			{
				if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateParseHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling;
			}
			set
			{
				if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_floatParseHandling = value;
			}
		}

		public string? DateFormatString
		{
			get
			{
				return _dateFormatString;
			}
			set
			{
				_dateFormatString = value;
			}
		}

		public int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
			}
		}

		public virtual JsonToken TokenType => _tokenType;

		public virtual object? Value => _value;

		public virtual Type? ValueType => _value?.GetType();

		public virtual int Depth
		{
			get
			{
				int num = _stack?.Count ?? 0;
				if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
				{
					return num;
				}
				return num + 1;
			}
		}

		public virtual string Path
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null);
				return JsonPosition.BuildPath(_stack, currentPosition);
			}
		}

		public CultureInfo Culture
		{
			get
			{
				return _culture ?? CultureInfo.InvariantCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync();
		}

		public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			if (TokenType == JsonToken.PropertyName)
			{
				await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false) && depth < Depth)
				{
				}
			}
		}

		internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken)
		{
			if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
			{
				throw CreateUnexpectedEndException();
			}
		}

		public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean());
		}

		public virtual Task<byte[]?> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes());
		}

		internal async Task<byte[]?> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
		{
			List<byte> buffer = new List<byte>();
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(buffer));
			byte[] array = buffer.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime());
		}

		public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset());
		}

		public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal());
		}

		public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return Task.FromResult(ReadAsDouble());
		}

		public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32());
		}

		public virtual Task<string?> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString());
		}

		internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken)
		{
			bool flag = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (flag)
			{
				flag = await MoveToContentAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			return flag;
		}

		internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType = TokenType;
			if (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				return MoveToContentFromNonContentAsync(cancellationToken);
			}
			return AsyncUtils.True;
		}

		private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType;
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					return false;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment);
			return true;
		}

		internal JsonPosition GetPosition(int depth)
		{
			if (_stack != null && depth < _stack.Count)
			{
				return _stack[depth];
			}
			return _currentPosition;
		}

		protected JsonReader()
		{
			_currentState = State.Start;
			_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
			_dateParseHandling = DateParseHandling.DateTime;
			_floatParseHandling = FloatParseHandling.Double;
			_maxDepth = 64;
			CloseInput = true;
		}

		private void Push(JsonContainerType value)
		{
			UpdateScopeWithFinishedValue();
			if (_currentPosition.Type == JsonContainerType.None)
			{
				_currentPosition = new JsonPosition(value);
				return;
			}
			if (_stack == null)
			{
				_stack = new List<JsonPosition>();
			}
			_stack.Add(_currentPosition);
			_currentPosition = new JsonPosition(value);
			if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth)
			{
				return;
			}
			_hasExceededMaxDepth = true;
			throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth));
		}

		private JsonContainerType Pop()
		{
			JsonPosition currentPosition;
			if (_stack != null && _stack.Count > 0)
			{
				currentPosition = _currentPosition;
				_currentPosition = _stack[_stack.Count - 1];
				_stack.RemoveAt(_stack.Count - 1);
			}
			else
			{
				currentPosition = _currentPosition;
				_currentPosition = default(JsonPosition);
			}
			if (_maxDepth.HasValue && Depth <= _maxDepth)
			{
				_hasExceededMaxDepth = false;
			}
			return currentPosition.Type;
		}

		private JsonContainerType Peek()
		{
			return _currentPosition.Type;
		}

		public abstract bool Read();

		public virtual int? ReadAsInt32()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is int)
				{
					return (int)value;
				}
				int num;
				if (value is BigInteger bigInteger)
				{
					num = (int)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToInt32(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Integer, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadInt32String(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal int? ReadInt32String(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (int.TryParse(s, NumberStyles.Integer, Culture, out var result))
			{
				SetToken(JsonToken.Integer, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual string? ReadAsString()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.String:
				return (string)Value;
			default:
				if (JsonTokenUtils.IsPrimitiveToken(contentToken))
				{
					object value = Value;
					if (value != null)
					{
						string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture));
						SetToken(JsonToken.String, text, updateIndex: false);
						return text;
					}
				}
				throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		public virtual byte[]? ReadAsBytes()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.StartObject:
			{
				ReadIntoWrappedTypeObject();
				byte[] array2 = ReadAsBytes();
				ReaderReadAndAssert();
				if (TokenType != JsonToken.EndObject)
				{
					throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
				}
				SetToken(JsonToken.Bytes, array2, updateIndex: false);
				return array2;
			}
			case JsonToken.String:
			{
				string text = (string)Value;
				Guid g;
				byte[] array3 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray()));
				SetToken(JsonToken.Bytes, array3, updateIndex: false);
				return array3;
			}
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Bytes:
				if (Value is Guid guid)
				{
					byte[] array = guid.ToByteArray();
					SetToken(JsonToken.Bytes, array, updateIndex: false);
					return array;
				}
				return (byte[])Value;
			case JsonToken.StartArray:
				return ReadArrayIntoByteArray();
			default:
				throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal byte[] ReadArrayIntoByteArray()
		{
			List<byte> list = new List<byte>();
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(list));
			byte[] array = list.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer)
		{
			switch (TokenType)
			{
			case JsonToken.None:
				throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
			case JsonToken.Integer:
				buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
				return false;
			case JsonToken.EndArray:
				return true;
			case JsonToken.Comment:
				return false;
			default:
				throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		public virtual double? ReadAsDouble()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is double)
				{
					return (double)value;
				}
				double num = ((!(value is BigInteger bigInteger)) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger));
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDoubleString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal double? ReadDoubleString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual bool? ReadAsBoolean()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				bool flag = ((!(Value is BigInteger bigInteger)) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L));
				SetToken(JsonToken.Boolean, flag, updateIndex: false);
				return flag;
			}
			case JsonToken.String:
				return ReadBooleanString((string)Value);
			case JsonToken.Boolean:
				return (bool)Value;
			default:
				throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal bool? ReadBooleanString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (bool.TryParse(s, out var result))
			{
				SetToken(JsonToken.Boolean, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual decimal? ReadAsDecimal()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is decimal)
				{
					return (decimal)value;
				}
				decimal num;
				if (value is BigInteger bigInteger)
				{
					num = (decimal)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToDecimal(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDecimalString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal decimal? ReadDecimalString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success)
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTime? ReadAsDateTime()
		{
			switch (GetContentToken())
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTimeOffset dateTimeOffset)
				{
					SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false);
				}
				return (DateTime)Value;
			case JsonToken.String:
				return ReadDateTimeString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		internal DateTime? ReadDateTimeString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTimeOffset? ReadAsDateTimeOffset()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTime dateTime)
				{
					SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false);
				}
				return (DateTimeOffset)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadDateTimeOffsetString(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal DateTimeOffset? ReadDateTimeOffsetString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		internal void ReaderReadAndAssert()
		{
			if (!Read())
			{
				throw CreateUnexpectedEndException();
			}
		}

		internal JsonReaderException CreateUnexpectedEndException()
		{
			return JsonReaderException.Create(this, "Unexpected end when reading JSON.");
		}

		internal void ReadIntoWrappedTypeObject()
		{
			ReaderReadAndAssert();
			if (Value != null && Value.ToString() == "$type")
			{
				ReaderReadAndAssert();
				if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
				{
					ReaderReadAndAssert();
					if (Value.ToString() == "$value")
					{
						return;
					}
				}
			}
			throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
		}

		public void Skip()
		{
			if (TokenType == JsonToken.PropertyName)
			{
				Read();
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (Read() && depth < Depth)
				{
				}
			}
		}

		protected void SetToken(JsonToken newToken)
		{
			SetToken(newToken, null, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value)
		{
			SetToken(newToken, value, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value, bool updateIndex)
		{
			_tokenType = newToken;
			_value = value;
			switch (newToken)
			{
			case JsonToken.StartObject:
				_currentState = State.ObjectStart;
				Push(JsonContainerType.Object);
				break;
			case JsonToken.StartArray:
				_currentState = State.ArrayStart;
				Push(JsonContainerType.Array);
				break;
			case JsonToken.StartConstructor:
				_currentState = State.ConstructorStart;
				Push(JsonContainerType.Constructor);
				break;
			case JsonToken.EndObject:
				ValidateEnd(JsonToken.EndObject);
				break;
			case JsonToken.EndArray:
				ValidateEnd(JsonToken.EndArray);
				break;
			case JsonToken.EndConstructor:
				ValidateEnd(JsonToken.EndConstructor);
				break;
			case JsonToken.PropertyName:
				_currentState = State.Property;
				_currentPosition.PropertyName = (string)value;
				break;
			case JsonToken.Raw:
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				SetPostValueState(updateIndex);
				break;
			case JsonToken.Comment:
				break;
			}
		}

		internal void SetPostValueState(bool updateIndex)
		{
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
			if (updateIndex)
			{
				UpdateScopeWithFinishedValue();
			}
		}

		private void UpdateScopeWithFinishedValue()
		{
			if (_currentPosition.HasIndex)
			{
				_currentPosition.Position++;
			}
		}

		private void ValidateEnd(JsonToken endToken)
		{
			JsonContainerType jsonContainerType = Pop();
			if (GetTypeForCloseToken(endToken) != jsonContainerType)
			{
				throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType));
			}
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
		}

		protected void SetStateBasedOnCurrent()
		{
			JsonContainerType jsonContainerType = Peek();
			switch (jsonContainerType)
			{
			case JsonContainerType.Object:
				_currentState = State.Object;
				break;
			case JsonContainerType.Array:
				_currentState = State.Array;
				break;
			case JsonContainerType.Constructor:
				_currentState = State.Constructor;
				break;
			case JsonContainerType.None:
				SetFinished();
				break;
			default:
				throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType));
			}
		}

		private void SetFinished()
		{
			_currentState = ((!SupportMultipleContent) ? State.Finished : State.Start);
		}

		private JsonContainerType GetTypeForCloseToken(JsonToken token)
		{
			return token switch
			{
				JsonToken.EndObject => JsonContainerType.Object, 
				JsonToken.EndArray => JsonContainerType.Array, 
				JsonToken.EndConstructor => JsonContainerType.Constructor, 
				_ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), 
			};
		}

		void IDisposable.Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_currentState != State.Closed && disposing)
			{
				Close();
			}
		}

		public virtual void Close()
		{
			_currentState = State.Closed;
			_tokenType = JsonToken.None;
			_value = null;
		}

		internal void ReadAndAssert()
		{
			if (!Read())
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter)
		{
			if (!ReadForType(contract, hasConverter))
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal bool ReadForType(JsonContract? contract, bool hasConverter)
		{
			if (hasConverter)
			{
				return Read();
			}
			switch (contract?.InternalReadType ?? ReadType.Read)
			{
			case ReadType.Read:
				return ReadAndMoveToContent();
			case ReadType.ReadAsInt32:
				ReadAsInt32();
				break;
			case ReadType.ReadAsInt64:
			{
				bool result = ReadAndMoveToContent();
				if (TokenType == JsonToken.Undefined)
				{
					throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long)));
				}
				return result;
			}
			case ReadType.ReadAsDecimal:
				ReadAsDecimal();
				break;
			case ReadType.ReadAsDouble:
				ReadAsDouble();
				break;
			case ReadType.ReadAsBytes:
				ReadAsBytes();
				break;
			case ReadType.ReadAsBoolean:
				ReadAsBoolean();
				break;
			case ReadType.ReadAsString:
				ReadAsString();
				break;
			case ReadType.ReadAsDateTime:
				ReadAsDateTime();
				break;
			case ReadType.ReadAsDateTimeOffset:
				ReadAsDateTimeOffset();
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
			return TokenType != JsonToken.None;
		}

		internal bool ReadAndMoveToContent()
		{
			if (Read())
			{
				return MoveToContent();
			}
			return false;
		}

		internal bool MoveToContent()
		{
			JsonToken tokenType = TokenType;
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				if (!Read())
				{
					return false;
				}
				tokenType = TokenType;
			}
			return true;
		}

		private JsonToken GetContentToken()
		{
			JsonToken tokenType;
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
					return JsonToken.None;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.Comment);
			return tokenType;
		}
	}
	[Serializable]
	public class JsonReaderException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonReaderException()
		{
		}

		public JsonReaderException(string message)
			: base(message)
		{
		}

		public JsonReaderException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonReaderException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonReaderException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonReaderException(message, path, lineNumber, linePosition, ex);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonRequiredAttribute : Attribute
	{
	}
	[Serializable]
	public class JsonSerializationException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonSerializationException()
		{
		}

		public JsonSerializationException(string message)
			: base(message)
		{
		}

		public JsonSerializationException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonSerializationException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonSerializationException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonSerializationException(message, path, lineNumber, linePosition, ex);
		}
	}
	public class JsonSerializer
	{
		internal TypeNameHandling _typeNameHandling;

		internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling;

		internal PreserveReferencesHandling _preserveReferencesHandling;

		internal ReferenceLoopHandling _referenceLoopHandling;

		internal MissingMemberHandling _missingMemberHandling;

		internal ObjectCreationHandling _objectCreationHandling;

		internal NullValueHandling _nullValueHandling;

		internal DefaultValueHandling _defaultValueHandling;

		internal ConstructorHandling _constructorHandling;

		internal MetadataPropertyHandling _metadataPropertyHandling;

		internal JsonConverterCollection? _converters;

		internal IContractResolver _contractResolver;

		internal ITraceWriter? _traceWriter;

		internal IEqualityComparer? _equalityComparer;

		internal ISerializationBinder _serializationBinder;

		internal StreamingContext _context;

		private IReferenceResolver? _referenceResolver;

		private Formatting? _formatting;

		private DateFormatHandling? _dateFormatHandling;

		private DateTimeZoneHandling? _dateTimeZoneHandling;

		private DateParseHandling? _dateParseHandling;

		private FloatFormatHandling? _floatFormatHandling;

		private FloatParseHandling? _floatParseHandling;

		private StringEscapeHandling? _stringEscapeHandling;

		private CultureInfo _culture;

		private int? _maxDepth;

		private bool _maxDepthSet;

		private bool? _checkAdditionalContent;

		private string? _dateFormatString;

		private bool _dateFormatStringSet;

		public virtual IReferenceResolver? ReferenceResolver
		{
			get
			{
				return GetReferenceResolver();
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Reference resolver cannot be null.");
				}
				_referenceResolver = value;
			}
		}

		[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
		public virtual SerializationBinder Binder
		{
			get
			{
				if (_serializationBinder is SerializationBinder result)
				{
					return result;
				}
				if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter)
				{
					return serializationBinderAdapter.SerializationBinder;
				}
				throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value);
			}
		}

		public virtual ISerializationBinder SerializationBinder
		{
			get
			{
				return _serializationBinder;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = value;
			}
		}

		public virtual ITraceWriter? TraceWriter
		{
			get
			{
				return _traceWriter;
			}
			set
			{
				_traceWriter = value;
			}
		}

		public virtual IEqualityComparer? EqualityComparer
		{
			get
			{
				return _equalityComparer;
			}
			set
			{
				_equalityComparer = value;
			}
		}

		public virtual TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling;
			}
			set
			{
				if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameHandling = value;
			}
		}

		[Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")]
		public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value;
			}
		}

		public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling
		{
			get
			{
				return _typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = value;
			}
		}

		public virtual PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling;
			}
			set
			{
				if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_preserveReferencesHandling = value;
			}
		}

		public virtual ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling;
			}
			set
			{
				if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_referenceLoopHandling = value;
			}
		}

		public virtual MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling;
			}
			set
			{
				if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_missingMemberHandling = value;
			}
		}

		public virtual NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling;
			}
			set
			{
				if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_nullValueHandling = value;
			}
		}

		public virtual DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling;
			}
			set
			{
				if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_defaultValueHandling = value;
			}
		}

		public virtual ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling;
			}
			set
			{
				if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_objectCreationHandling = value;
			}
		}

		public virtual ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling;
			}
			set
			{
				if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_constructorHandling = value;
			}
		}

		public virtual MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling;
			}
			set
			{
				if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_metadataPropertyHandling = value;
			}
		}

		public virtual JsonConverterCollection Converters
		{
			get
			{
				if (_converters == null)
				{
					_converters = new JsonConverterCollection();
				}
				return _converters;
			}
		}

		public virtual IContractResolver ContractResolver
		{
			get
			{
				return _contractResolver;
			}
			set
			{
				_contractResolver = value ?? DefaultContractResolver.Instance;
			}
		}

		public virtual StreamingContext Context
		{
			get
			{
				return _context;
			}
			set
			{
				_context = value;
			}
		}

		public virtual Formatting Formatting
		{
			get
			{
				return _formatting.GetValueOrDefault();
			}
			set
			{
				_formatting = value;
			}
		}

		public virtual DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling.GetValueOrDefault();
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

		public virtual DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind;
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public virtual DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling ?? DateParseHandling.DateTime;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public virtual FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling.GetValueOrDefault();
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public virtual FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling.GetValueOrDefault();
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public virtual StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling.GetValueOrDefault();
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

		public virtual string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

		public virtual CultureInfo Culture
		{
			get
			{
				return _culture ?? JsonSerializerSettings.DefaultCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
				_maxDepthSet = true;
			}
		}

		public virtual bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent.GetValueOrDefault();
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>? Error;

		internal bool IsCheckAdditionalContentSet()
		{
			return _checkAdditionalContent.HasValue;
		}

		public JsonSerializer()
		{
			_referenceLoopHandling = ReferenceLoopHandling.Error;
			_missingMemberHandling = MissingMemberHandling.Ignore;
			_nullValueHandling = NullValueHandling.Include;
			_defaultValueHandling = DefaultValueHandling.Include;
			_objectCreationHandling = ObjectCreationHandling.Auto;
			_preserveReferencesHandling = PreserveReferencesHandling.None;
			_constructorHandling = ConstructorHandling.Default;
			_typeNameHandling = TypeNameHandling.None;
			_metadataPropertyHandling = MetadataPropertyHandling.Default;
			_context = JsonSerializerSettings.DefaultContext;
			_serializationBinder = DefaultSerializationBinder.Instance;
			_culture = JsonSerializerSettings.DefaultCulture;
			_contractResolver = DefaultContractResolver.Instance;
		}

		public static JsonSerializer Create()
		{
			return new JsonSerializer();
		}

		public static JsonSerializer Create(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = Create();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		public static JsonSerializer CreateDefault()
		{
			return Create(JsonConvert.DefaultSettings?.Invoke());
		}

		public static JsonSerializer CreateDefault(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = CreateDefault();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings)
		{
			if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
			{
				for (int i = 0; i < settings.Converters.Count; i++)
				{
					serializer.Converters.Insert(i, settings.Converters[i]);
				}
			}
			if (settings._typeNameHandling.HasValue)
			{
				serializer.TypeNameHandling = settings.TypeNameHandling;
			}
			if (settings._metadataPropertyHandling.HasValue)
			{
				serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling;
			}
			if (settings._typeNameAssemblyFormatHandling.HasValue)
			{
				serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling;
			}
			if (settings._preserveReferencesHandling.HasValue)
			{
				serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
			}
			if (settings._referenceLoopHandling.HasValue)
			{
				serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
			}
			if (settings._missingMemberHandling.HasValue)
			{
				serializer.MissingMemberHandling = settings.MissingMemberHandling;
			}
			if (settings._objectCreationHandling.HasValue)
			{
				serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
			}
			if (settings._nullValueHandling.HasValue)
			{
				serializer.NullValueHandling = settings.NullValueHandling;
			}
			if (settings._defaultValueHandling.HasValue)
			{
				serializer.DefaultValueHandling = settings.DefaultValueHandling;
			}
			if (settings._constructorHandling.HasValue)
			{
				serializer.ConstructorHandling = settings.ConstructorHandling;
			}
			if (settings._context.HasValue)
			{
				serializer.Context = settings.Context;
			}
			if (settings._checkAdditionalContent.HasValue)
			{
				serializer._checkAdditionalContent = settings._checkAdditionalContent;
			}
			if (settings.Error != null)
			{
				serializer.Error += settings.Error;
			}
			if (settings.ContractResolver != null)
			{
				serializer.ContractResolver = settings.ContractResolver;
			}
			if (settings.ReferenceResolverProvider != null)
			{
				serializer.ReferenceResolver = settings.ReferenceResolverProvider();
			}
			if (settings.TraceWriter != null)
			{
				serializer.TraceWriter = settings.TraceWriter;
			}
			if (settings.EqualityComparer != null)
			{
				serializer.EqualityComparer = settings.EqualityComparer;
			}
			if (settings.SerializationBinder != null)
			{
				serializer.SerializationBinder = settings.SerializationBinder;
			}
			if (settings._formatting.HasValue)
			{
				serializer._formatting = settings._formatting;
			}
			if (settings._dateFormatHandling.HasValue)
			{
				serializer._dateFormatHandling = settings._dateFormatHandling;
			}
			if (settings._dateTimeZoneHandling.HasValue)
			{
				serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
			}
			if (settings._dateParseHandling.HasValue)
			{
				serializer._dateParseHandling = settings._dateParseHandling;
			}
			if (settings._dateFormatStringSet)
			{
				serializer._dateFormatString = settings._dateFormatString;
				serializer._dateFormatStringSet = settings._dateFormatStringSet;
			}
			if (settings._floatFormatHandling.HasValue)
			{
				serializer._floatFormatHandling = settings._floatFormatHandling;
			}
			if (settings._floatParseHandling.HasValue)
			{
				serializer._floatParseHandling = settings._floatParseHandling;
			}
			if (settings._stringEscapeHandling.HasValue)
			{
				serializer._stringEscapeHandling = settings._stringEscapeHandling;
			}
			if (settings._culture != null)
			{
				serializer._culture = settings._culture;
			}
			if (settings._maxDepthSet)
			{
				serializer._maxDepth = settings._maxDepth;
				serializer._maxDepthSet = settings._maxDepthSet;
			}
		}

		[DebuggerStepThrough]
		public void Populate(TextReader reader, object target)
		{
			Populate(new JsonTextReader(reader), target);
		}

		[DebuggerStepThrough]
		public void Populate(JsonReader reader, object target)
		{
			PopulateInternal(reader, target);
		}

		internal virtual void PopulateInternal(JsonReader reader, object target)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			ValidationUtils.ArgumentNotNull(target, "target");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader)
		{
			return Deserialize(reader, null);
		}

		[DebuggerStepThrough]
		public object? Deserialize(TextReader reader, Type objectType)
		{
			return Deserialize(new JsonTextReader(reader), objectType);
		}

		[DebuggerStepThrough]
		public T? Deserialize<T>(JsonReader reader)
		{
			return (T)Deserialize(reader, typeof(T));
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader, Type? objectType)
		{
			return DeserializeInternal(reader, objectType);
		}

		internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			object? result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
			return result;
		}

		internal void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString)
		{
			if (_culture != null && !_culture.Equals(reader.Culture))
			{
				previousCulture = reader.Culture;
				reader.Culture = _culture;
			}
			else
			{
				previousCulture = null;
			}
			if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
				reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			else
			{
				previousDateTimeZoneHandling = null;
			}
			if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling)
			{
				previousDateParseHandling = reader.DateParseHandling;
				reader.DateParseHandling = _dateParseHandling.GetValueOrDefault();
			}
			else
			{
				previousDateParseHandling = null;
			}
			if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling)
			{
				previousFloatParseHandling = reader.FloatParseHandling;
				reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault();
			}
			else
			{
				previousFloatParseHandling = null;
			}
			if (_maxDepthSet && reader.MaxDepth != _maxDepth)
			{
				previousMaxDepth = reader.MaxDepth;
				reader.MaxDepth = _maxDepth;
			}
			else
			{
				previousMaxDepth = null;
			}
			if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString)
			{
				previousDateFormatString = reader.DateFormatString;
				reader.DateFormatString = _dateFormatString;
			}
			else
			{
				previousDateFormatString = null;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable == null && _contractResolver is DefaultContractResolver defaultContractResolver)
			{
				jsonTextReader.PropertyNameTable = defaultContractResolver.GetNameTable();
			}
		}

		private void ResetReader(JsonReader reader, CultureInfo? previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string? previousDateFormatString)
		{
			if (previousCulture != null)
			{
				reader.Culture = previousCulture;
			}
			if (previousDateTimeZoneHandling.HasValue)
			{
				reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault();
			}
			if (previousDateParseHandling.HasValue)
			{
				reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault();
			}
			if (previousFloatParseHandling.HasValue)
			{
				reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault();
			}
			if (_maxDepthSet)
			{
				reader.MaxDepth = previousMaxDepth;
			}
			if (_dateFormatStringSet)
			{
				reader.DateFormatString = previousDateFormatString;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable != null && _contractResolver is DefaultContractResolver defaultContractResolver && jsonTextReader.PropertyNameTable == defaultContractResolver.GetNameTable())
			{
				jsonTextReader.PropertyNameTable = null;
			}
		}

		public void Serialize(TextWriter textWriter, object? value)
		{
			Serialize(new JsonTextWriter(textWriter), value);
		}

		public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			SerializeInternal(jsonWriter, value, objectType);
		}

		public void Serialize(TextWriter textWriter, object? value, Type objectType)
		{
			Serialize(new JsonTextWriter(textWriter), value, objectType);
		}

		public void Serialize(JsonWriter jsonWriter, object? value)
		{
			SerializeInternal(jsonWriter, value, null);
		}

		private TraceJsonReader CreateTraceJsonReader(JsonReader reader)
		{
			TraceJsonReader traceJsonReader = new TraceJsonReader(reader);
			if (reader.TokenType != 0)
			{
				traceJsonReader.WriteCurrentToken();
			}
			return traceJsonReader;
		}

		internal virtual void SerializeInternal(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
			Formatting? formatting = null;
			if (_formatting.HasValue && jsonWriter.Formatting != _formatting)
			{
				formatting = jsonWriter.Formatting;
				jsonWriter.Formatting = _formatting.GetValueOrDefault();
			}
			DateFormatHandling? dateFormatHandling = null;
			if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling)
			{
				dateFormatHandling = jsonWriter.DateFormatHandling;
				jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault();
			}
			DateTimeZoneHandling? dateTimeZoneHandling = null;
			if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling;
				jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			FloatFormatHandling? floatFormatHandling = null;
			if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling)
			{
				floatFormatHandling = jsonWriter.FloatFormatHandling;
				jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault();
			}
			StringEscapeHandling? stringEscapeHandling = null;
			if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling)
			{
				stringEscapeHandling = jsonWriter.StringEscapeHandling;
				jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault();
			}
			CultureInfo cultureInfo = null;
			if (_culture != null && !_culture.Equals(jsonWriter.Culture))
			{
				cultureInfo = jsonWriter.Culture;
				jsonWriter.Culture = _culture;
			}
			string dateFormatString = null;
			if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString)
			{
				dateFormatString = jsonWriter.DateFormatString;
				jsonWriter.DateFormatString = _dateFormatString;
			}
			TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null);
			new JsonSerializerInternalWriter(this).Serialize(traceJsonWriter ?? jsonWriter, value, objectType);
			if (traceJsonWriter != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null);
			}
			if (formatting.HasValue)
			{
				jsonWriter.Formatting = formatting.GetValueOrDefault();
			}
			if (dateFormatHandling.HasValue)
			{
				jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault();
			}
			if (dateTimeZoneHandling.HasValue)
			{
				jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault();
			}
			if (floatFormatHandling.HasValue)
			{
				jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault();
			}
			if (stringEscapeHandling.HasValue)
			{
				jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault();
			}
			if (_dateFormatStringSet)
			{
				jsonWriter.DateFormatString = dateFormatString;
			}
			if (cultureInfo != null)
			{
				jsonWriter.Culture = cultureInfo;
			}
		}

		internal IReferenceResolver GetReferenceResolver()
		{
			if (_referenceResolver == null)
			{
				_referenceResolver = new DefaultReferenceResolver();
			}
			return _referenceResolver;
		}

		internal JsonConverter? GetMatchingConverter(Type type)
		{
			return GetMatchingConverter(_converters, type);
		}

		internal static JsonConverter? GetMatchingConverter(IList<JsonConverter>? converters, Type objectType)
		{
			if (converters != null)
			{
				for (int i = 0; i < converters.Count; i++)
				{
					JsonConverter jsonConverter = converters[i];
					if (jsonConverter.CanConvert(objectType))
					{
						return jsonConverter;
					}
				}
			}
			return null;
		}

		internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e)
		{
			this.Error?.Invoke(this, e);
		}
	}
	public class JsonSerializerSettings
	{
		internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;

		internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;

		internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;

		internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;

		internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;

		internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;

		internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;

		internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;

		internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default;

		internal static readonly StreamingContext DefaultContext;

		internal const Formatting DefaultFormatting = Formatting.None;

		internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat;

		internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;

		internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime;

		internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double;

		internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String;

		internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default;

		internal const TypeNameAssemblyFormatHandling DefaultTypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple;

		internal static readonly CultureInfo DefaultCulture;

		internal const bool DefaultCheckAdditionalContent = false;

		internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

		internal const int DefaultMaxDepth = 64;

		internal Formatting? _formatting;

		internal DateFormatHandling? _dateFormatHandling;

		internal DateTimeZoneHandling? _dateTimeZoneHandling;

		internal DateParseHandling? _dateParseHandling;

		internal FloatFormatHandling? _floatFormatHandling;

		internal FloatParseHandling? _floatParseHandling;

		internal StringEscapeHandling? _stringEscapeHandling;

		internal CultureInfo? _culture;

		internal bool? _checkAdditionalContent;

		internal int? _maxDepth;

		internal bool _maxDepthSet;

		internal string? _dateFormatString;

		internal bool _dateFormatStringSet;

		internal TypeNameAssemblyFormatHandling? _typeNameAssemblyFormatHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal PreserveReferencesHandling? _preserveReferencesHandling;

		internal NullValueHandling? _nullValueHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal MissingMemberHandling? _missingMemberHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal StreamingContext? _context;

		internal ConstructorHandling? _constructorHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal MetadataPropertyHandling? _metadataPropertyHandling;

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

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

		public PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling.GetValueOrDef

BepInEx/plugins/ServerManager/ValheimServerManager.Client.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using ValheimServerManager.ClientSupport;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ValheimServerManager.Client")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.6.2.0")]
[assembly: AssemblyInformationalVersion("2.6.2+8f44cae60f2f4dfad003196b3bab5429bb85ecae")]
[assembly: AssemblyProduct("ValheimServerManager.Client")]
[assembly: AssemblyTitle("ValheimServerManager.Client")]
[assembly: AssemblyVersion("2.6.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 ValheimServerManager.ServerSupport
{
	internal static class ConnectionPolicy
	{
		internal const int VanillaPlayerLimit = 10;

		internal static bool ShouldBufferWorldTraffic(bool serverCharactersEnabled, bool requiredModsEnabled)
		{
			return serverCharactersEnabled || requiredModsEnabled;
		}

		internal static bool ShouldOverridePlayerLimit(int maximumPlayers)
		{
			return maximumPlayers != 10;
		}
	}
}
namespace ValheimServerManager.ClientSupport
{
	internal sealed class ClientHandshake
	{
		private float _nextHello;

		private float _deadline;

		private int _helloCount;

		public bool Active { get; private set; }

		public bool Acknowledged { get; private set; }

		public bool RequiresCharacter { get; private set; }

		public bool ReceivedProfile { get; private set; }

		public bool Ready { get; private set; }

		public bool Failed { get; private set; }

		public bool ShouldWait
		{
			get
			{
				if (Active && RequiresCharacter)
				{
					return !Ready;
				}
				return false;
			}
		}

		public void Begin(float now)
		{
			Reset();
			Active = true;
			_nextHello = now;
		}

		public bool TrySendHello(float now)
		{
			if (!Active || Acknowledged || Failed || _helloCount >= 3 || now < _nextHello)
			{
				return false;
			}
			_helloCount++;
			_nextHello = now + 2f;
			return true;
		}

		public void SetPolicy(bool requiresCharacter, int timeoutSeconds, float now)
		{
			if (Active && !Acknowledged && !ReceivedProfile && !Failed)
			{
				Acknowledged = true;
				RequiresCharacter = requiresCharacter;
				Ready = !requiresCharacter;
				_deadline = now + (float)Math.Max(30, Math.Min(120, timeoutSeconds));
			}
		}

		public bool TryReceiveProfile(float now)
		{
			if (!Active || ReceivedProfile || Failed || (Acknowledged && !RequiresCharacter))
			{
				return false;
			}
			Acknowledged = true;
			RequiresCharacter = true;
			ReceivedProfile = true;
			_deadline = now + 30f;
			return true;
		}

		public bool HasTimedOut(float now)
		{
			if (ShouldWait && !Failed)
			{
				return now >= _deadline;
			}
			return false;
		}

		public void CompleteProfile()
		{
			if (!Failed)
			{
				Ready = true;
			}
		}

		public void Fail()
		{
			Failed = true;
			Ready = false;
		}

		public void Reset()
		{
			bool flag = (Failed = false);
			bool flag3 = (Ready = flag);
			bool flag5 = (ReceivedProfile = flag3);
			bool flag7 = (RequiresCharacter = flag5);
			bool active = (Acknowledged = flag7);
			Active = active;
			_nextHello = (_deadline = 0f);
			_helloCount = 0;
		}
	}
	internal sealed class ClientModPackage
	{
		public string Namespace { get; set; } = "";

		public string Name { get; set; } = "";

		public string Version { get; set; } = "";

		public string? InstalledVersion { get; set; }

		public bool Present => string.Equals(Version, InstalledVersion, StringComparison.Ordinal);
	}
	internal sealed class ClientModGroup
	{
		public string Name { get; set; } = "";

		public IReadOnlyList<ClientModPackage> Packages { get; set; } = Array.Empty<ClientModPackage>();
	}
	internal sealed class ClientModCatalogStatus
	{
		public string Revision { get; set; } = "";

		public bool RequiredReceipt { get; set; }

		public IReadOnlyList<ClientModPackage> Required { get; set; } = Array.Empty<ClientModPackage>();

		public IReadOnlyList<ClientModGroup> Optional { get; set; } = Array.Empty<ClientModGroup>();

		public IReadOnlyList<string> Unexpected { get; set; } = Array.Empty<string>();

		public bool RequiredPresent => Required.All((ClientModPackage package) => package.Present);

		public bool CanAcknowledge
		{
			get
			{
				if (RequiredPresent)
				{
					return Unexpected.Count == 0;
				}
				return false;
			}
		}
	}
	internal static class ClientModCompatibility
	{
		public static ClientModCatalogStatus Check(string json, string bepinexRoot)
		{
			if (string.IsNullOrEmpty(json) || json.Length > 8388608)
			{
				throw new InvalidDataException("Invalid server mod list size.");
			}
			JObject val = JObject.Parse(json);
			if ((int?)val["schemaVersion"] != 2)
			{
				throw new InvalidDataException("Unsupported server mod list.");
			}
			string text = (string)val["revision"];
			if (text == null || text.Length != 64 || !text.All(IsHex))
			{
				throw new InvalidDataException("Invalid server mod list revision.");
			}
			IReadOnlyList<ClientModPackage> readOnlyList = ReadPackages(val["packages"], bepinexRoot);
			List<ClientModGroup> list = new List<ClientModGroup>();
			JToken obj = val["optionalGroups"];
			JArray val2 = (JArray)(object)((obj is JArray) ? obj : null);
			if (val2 != null)
			{
				if (((JContainer)val2).Count > 100)
				{
					throw new InvalidDataException("Too many optional mod groups.");
				}
				foreach (JToken item in val2)
				{
					string text2 = (string)item[(object)"name"];
					if (text2 == null || text2.Length > 200 || string.IsNullOrWhiteSpace(text2))
					{
						throw new InvalidDataException("Invalid optional mod group.");
					}
					list.Add(new ClientModGroup
					{
						Name = text2,
						Packages = ReadPackages(item[(object)"packages"], bepinexRoot)
					});
				}
			}
			Dictionary<string, ClientModPackage[]> allowed = readOnlyList.Concat(list.SelectMany((ClientModGroup group) => group.Packages)).GroupBy<ClientModPackage, string>((ClientModPackage package) => package.Namespace + "-" + package.Name, StringComparer.OrdinalIgnoreCase).ToDictionary<IGrouping<string, ClientModPackage>, string, ClientModPackage[]>((IGrouping<string, ClientModPackage> group) => group.Key, (IGrouping<string, ClientModPackage> group) => group.ToArray(), StringComparer.OrdinalIgnoreCase);
			return new ClientModCatalogStatus
			{
				Revision = text,
				RequiredReceipt = ((bool?)val["requiredReceipt"] == true),
				Required = readOnlyList,
				Optional = list,
				Unexpected = UnexpectedPackages(bepinexRoot, allowed)
			};
		}

		private static IReadOnlyList<string> UnexpectedPackages(string bepinexRoot, IReadOnlyDictionary<string, ClientModPackage[]> allowed)
		{
			List<string> list = new List<string>();
			string[] array = new string[2] { "plugins", "patchers" };
			foreach (string text in array)
			{
				string path = Path.Combine(bepinexRoot, text);
				if (!Directory.Exists(path))
				{
					continue;
				}
				foreach (string item in Directory.EnumerateDirectories(path))
				{
					string fileName = Path.GetFileName(item);
					if (text == "plugins" && (fileName.Equals("ServerManager", StringComparison.OrdinalIgnoreCase) || fileName.Equals("Creaton-Server_Manager", StringComparison.OrdinalIgnoreCase)))
					{
						continue;
					}
					if ((File.GetAttributes(item) & FileAttributes.ReparsePoint) != FileAttributes.None)
					{
						list.Add(fileName + " (linked folder)");
						continue;
					}
					string path2 = Path.Combine(item, "manifest.json");
					if (File.Exists(path2))
					{
						allowed.TryGetValue(fileName, out ClientModPackage[] value);
						string version = ReadVersion(path2, value?.FirstOrDefault()?.Name);
						if (value == null || !value.Any((ClientModPackage package) => package.Version == version))
						{
							list.Add(fileName + ((version == null) ? " (unreadable manifest)" : ("-" + version)));
						}
					}
					else if (Directory.EnumerateFiles(item, "*.dll", SearchOption.AllDirectories).Any())
					{
						list.Add(fileName + (allowed.ContainsKey(fileName) ? " (unverified plugin)" : " (unlisted plugin)"));
					}
				}
				foreach (string item2 in Directory.EnumerateFiles(path, "*.dll"))
				{
					list.Add(Path.GetFileName(item2) + " (unlisted plugin)");
				}
			}
			return list.OrderBy<string, string>((string result) => result, StringComparer.OrdinalIgnoreCase).ToArray();
		}

		private static IReadOnlyList<ClientModPackage> ReadPackages(JToken? token, string bepinexRoot)
		{
			JArray val = (JArray)(object)((token is JArray) ? token : null);
			if (val == null || ((JContainer)val).Count > 500)
			{
				throw new InvalidDataException("Invalid server mod packages.");
			}
			List<ClientModPackage> list = new List<ClientModPackage>();
			foreach (JToken item in val)
			{
				string text = (string)item[(object)"namespace"];
				string text2 = (string)item[(object)"packageName"];
				string text3 = (string)item[(object)"versionNumber"];
				if (!SafeSegment(text) || !SafeSegment(text2) || !SafeVersion(text3) || (string)item[(object)"coordinate"] != text + "-" + text2 + "-" + text3)
				{
					throw new InvalidDataException("Invalid package identity in server mod list.");
				}
				list.Add(new ClientModPackage
				{
					Namespace = text,
					Name = text2,
					Version = text3,
					InstalledVersion = InstalledVersion(bepinexRoot, text, text2)
				});
			}
			return list;
		}

		private static string? InstalledVersion(string bepinexRoot, string packageNamespace, string name)
		{
			string path = Path.Combine(bepinexRoot, "plugins", packageNamespace + "-" + name, "manifest.json");
			try
			{
				return ReadVersion(path, name);
			}
			catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || ex is JsonException)
			{
				return null;
			}
		}

		private static string? ReadVersion(string path, string? expectedName)
		{
			if (!File.Exists(path) || new FileInfo(path).Length > 65536)
			{
				return null;
			}
			JObject val = JObject.Parse(File.ReadAllText(path));
			if (expectedName != null && !string.Equals((string)val["name"], expectedName, StringComparison.OrdinalIgnoreCase))
			{
				return null;
			}
			return (string)val["version_number"];
		}

		private static bool SafeSegment(string? value)
		{
			if (value != null && value.Length > 0 && value.Length <= 100)
			{
				return value.All((char character) => char.IsLetterOrDigit(character) || character == '_' || character == '-');
			}
			return false;
		}

		private static bool SafeVersion(string? value)
		{
			if (value != null && value.Length > 0 && value.Length <= 32)
			{
				return value.All((char character) => char.IsDigit(character) || character == '.');
			}
			return false;
		}

		private static bool IsHex(char value)
		{
			if (value < '0' || value > '9')
			{
				if (value >= 'a')
				{
					return value <= 'f';
				}
				return false;
			}
			return true;
		}
	}
	internal enum NoticeKind
	{
		Information,
		Attention,
		Error,
		RestartRequired
	}
	internal sealed class ClientNotice
	{
		public string Title { get; }

		public string Message { get; }

		public NoticeKind Kind { get; }

		public bool Persistent => Kind != NoticeKind.Information;

		public float VisibleUntil { get; set; }

		public ClientNotice(string title, string message, NoticeKind kind)
		{
			Title = Clean(title, 80, "Server notice");
			Message = Clean(message, 1600, "");
			Kind = kind;
		}

		internal static string Clean(string value, int maximum, string fallback)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return fallback;
			}
			StringBuilder stringBuilder = new StringBuilder(Math.Min(value.Length, maximum));
			string text = value.Trim();
			foreach (char c in text)
			{
				if (stringBuilder.Length >= maximum)
				{
					break;
				}
				if (c == '\n' || !char.IsControl(c))
				{
					stringBuilder.Append(c);
				}
			}
			if (stringBuilder.Length > 0 && char.IsHighSurrogate(stringBuilder[stringBuilder.Length - 1]))
			{
				stringBuilder.Length--;
			}
			if (stringBuilder.Length != 0)
			{
				return stringBuilder.ToString();
			}
			return fallback;
		}

		public static NoticeKind ForServerTitle(string title)
		{
			if (!string.Equals(title, "Welcome", StringComparison.OrdinalIgnoreCase) && !string.Equals(title, "Server notice", StringComparison.OrdinalIgnoreCase) && !string.Equals(title, "Server restarting", StringComparison.OrdinalIgnoreCase))
			{
				return NoticeKind.Attention;
			}
			return NoticeKind.Information;
		}
	}
	internal sealed class NoticeQueue
	{
		private readonly List<ClientNotice> _pending = new List<ClientNotice>();

		private ClientNotice _last;

		private float _lastAt;

		public ClientNotice Current { get; private set; }

		internal int Count => _pending.Count + ((Current != null) ? 1 : 0);

		public void Add(ClientNotice notice, float now)
		{
			if (Same(Current, notice) || _pending.Exists((ClientNotice item) => Same(item, notice)) || (Same(_last, notice) && now - _lastAt < 10f))
			{
				return;
			}
			_last = notice;
			_lastAt = now;
			if (notice.Persistent && Current != null && !Current.Persistent)
			{
				Current = null;
			}
			if (Count >= 8)
			{
				int num = _pending.FindIndex((ClientNotice item) => !item.Persistent);
				if (num >= 0)
				{
					_pending.RemoveAt(num);
				}
				else
				{
					if (!notice.Persistent)
					{
						return;
					}
					if (_pending.Count > 0)
					{
						_pending.RemoveAt(0);
					}
				}
			}
			_pending.Add(notice);
		}

		public void Tick(bool playerReady, float now)
		{
			if (Current != null && !Current.Persistent && now >= Current.VisibleUntil)
			{
				Current = null;
			}
			if (Current == null)
			{
				int num = _pending.FindIndex((ClientNotice item) => item.Persistent);
				if (num < 0 && playerReady && _pending.Count > 0)
				{
					num = 0;
				}
				if (num >= 0)
				{
					Current = _pending[num];
					_pending.RemoveAt(num);
					Current.VisibleUntil = now + Math.Min(45f, Math.Max(8f, (float)Current.Message.Length / 18f));
				}
			}
		}

		public void Dismiss()
		{
			Current = null;
		}

		public void ClearTransient()
		{
			_pending.RemoveAll((ClientNotice item) => !item.Persistent);
			if (Current != null && !Current.Persistent)
			{
				Current = null;
			}
		}

		private static bool Same(ClientNotice left, ClientNotice right)
		{
			if (left != null && right != null && left.Title == right.Title && left.Message == right.Message)
			{
				return left.Kind == right.Kind;
			}
			return false;
		}
	}
	internal static class NoticeInputGuard
	{
		internal static bool ExternalModal { get; set; }

		internal static bool Install(Harmony harmony)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("UnityEngine.EventSystems.EventSystem");
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "Update", (Type[])null, (Type[])null));
			Type type2 = AccessTools.TypeByName("UnifiedPopup");
			MethodInfo methodInfo2 = ((type2 == null) ? null : AccessTools.Method(type2, "IsVisible", (Type[])null, (Type[])null));
			if (methodInfo == null || methodInfo2 == null)
			{
				return false;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(NoticeInputGuard), "AllowMenuInput", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(NoticeInputGuard), "IncludeOurModal", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			return true;
		}

		private static bool AllowMenuInput()
		{
			if (!NoticeOverlay.BlocksMenuInput)
			{
				return !ExternalModal;
			}
			return false;
		}

		private static void IncludeOurModal(ref bool __result)
		{
			__result |= NoticeOverlay.BlocksMenuInput || ExternalModal;
		}
	}
	internal sealed class NoticeOverlay
	{
		private readonly NoticeQueue _queue = new NoticeQueue();

		private GUIStyle _title;

		private GUIStyle _body;

		private GUIStyle _caption;

		private GUIStyle _button;

		private ClientNotice _displayed;

		private Vector2 _scroll;

		private bool _playerReady;

		private string _progress;

		private float _progressSince;

		private float _bodyHeight;

		private float _headerHeight;

		private float _panelHeight;

		private float _panelWidth;

		internal static bool BlocksMenuInput { get; private set; }

		public void Show(string title, string message, NoticeKind kind)
		{
			_queue.Add(new ClientNotice(title, message, kind), Time.unscaledTime);
		}

		public void SetProgress(string progress)
		{
			if (string.IsNullOrEmpty(_progress))
			{
				_progressSince = Time.unscaledTime;
			}
			_progress = progress;
		}

		public void ClearTransient()
		{
			_queue.ClearTransient();
			_progress = null;
		}

		public void Tick(bool playerReady)
		{
			if (_playerReady && !playerReady)
			{
				_queue.ClearTransient();
			}
			_playerReady = playerReady;
			_queue.Tick(playerReady, Time.unscaledTime);
			ClientNotice current = _queue.Current;
			BlocksMenuInput = current != null && current.Persistent && !playerReady;
		}

		public void Dispose()
		{
			BlocksMenuInput = false;
		}

		public void Draw()
		{
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Expected O, but got Unknown
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Expected O, but got Unknown
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			if (_playerReady)
			{
				return;
			}
			ClientNotice current = _queue.Current;
			bool flag = !string.IsNullOrEmpty(_progress) && Time.unscaledTime - _progressSince >= 1f;
			if (current == null && !flag)
			{
				return;
			}
			if (_displayed != current)
			{
				_displayed = current;
				_scroll = Vector2.zero;
			}
			EnsureStyles();
			Matrix4x4 matrix = GUI.matrix;
			Color color = GUI.color;
			int depth = GUI.depth;
			try
			{
				float num = Mathf.Min(new float[3]
				{
					Mathf.Clamp((float)Screen.height / 900f, 1f, 2f),
					(float)Screen.width / 420f,
					(float)Screen.height / 360f
				});
				float num2 = (float)Screen.width / num;
				float num3 = (float)Screen.height / num;
				GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f));
				GUI.color = Color.white;
				GUI.depth = -1000;
				bool flag2 = current != null && current.Persistent && !_playerReady;
				_panelWidth = Mathf.Min(flag2 ? 620f : 440f, num2 - 32f);
				string title = current?.Title ?? "Preparing server mods";
				string message = current?.Message ?? _progress;
				_headerHeight = 50f + _title.CalcHeight(new GUIContent(title), _panelWidth - 48f);
				_bodyHeight = _body.CalcHeight(new GUIContent(message), _panelWidth - 64f);
				_panelHeight = Mathf.Min(num3 - 48f, _headerHeight + Mathf.Min(_bodyHeight, flag2 ? 300f : 170f) + (flag2 ? 92f : 54f));
				if (flag2)
				{
					GUI.ModalWindow(5657421, new Rect((num2 - _panelWidth) / 2f, (num3 - _panelHeight) / 2f, _panelWidth, _panelHeight), (WindowFunction)delegate
					{
						DrawPanel(title, message, modal: true);
					}, GUIContent.none, GUIStyle.none);
				}
				else
				{
					GUI.BeginGroup(new Rect(num2 - _panelWidth - 16f, num3 - _panelHeight - 24f, _panelWidth, _panelHeight));
					DrawPanel(title, message, modal: false);
					GUI.EndGroup();
				}
			}
			finally
			{
				GUI.matrix = matrix;
				GUI.color = color;
				GUI.depth = depth;
			}
		}

		private void DrawPanel(string title, string message, bool modal)
		{
			//IL_0027: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Invalid comparison between Unknown and I4
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Invalid comparison between Unknown and I4
			ClientNotice current = _queue.Current;
			Color color = ((current != null && current.Kind == NoticeKind.Error) ? new Color(1f, 0.52f, 0.42f) : new Color(0.94f, 0.76f, 0.39f));
			Fill(new Rect(0f, 0f, _panelWidth, _panelHeight), new Color(0.075f, 0.085f, 0.1f, 0.98f));
			Fill(new Rect(0f, 0f, 4f, _panelHeight), color);
			GUI.Label(new Rect(24f, 16f, _panelWidth - 48f, 20f), "SERVER MANAGER", _caption);
			GUI.Label(new Rect(24f, 42f, _panelWidth - 48f, _headerHeight - 42f), title, _title);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(24f, _headerHeight, _panelWidth - 48f, _panelHeight - _headerHeight - (modal ? 82f : 42f));
			if (modal || _bodyHeight > ((Rect)(ref val)).height)
			{
				_scroll = GUI.BeginScrollView(val, _scroll, new Rect(0f, 0f, ((Rect)(ref val)).width - 16f, _bodyHeight));
				GUI.Label(new Rect(0f, 0f, ((Rect)(ref val)).width - 16f, _bodyHeight), message, _body);
				GUI.EndScrollView();
			}
			else
			{
				GUI.Label(val, message, _body);
			}
			if (modal)
			{
				float num = _panelHeight - 58f;
				bool flag = current != null && current.Kind == NoticeKind.RestartRequired;
				if (GUI.Button(new Rect(24f, num, 156f, 38f), flag ? "Quit Valheim" : "Dismiss", _button))
				{
					if (flag)
					{
						Application.Quit();
					}
					else
					{
						_queue.Dismiss();
					}
				}
				if (GUI.Button(new Rect(_panelWidth - 180f, num, 156f, 38f), flag ? "Later" : "Copy message", _button))
				{
					if (flag)
					{
						_queue.Dismiss();
					}
					else
					{
						GUIUtility.systemCopyBuffer = title + "\n" + message;
					}
				}
				if ((int)Event.current.type == 4 && (int)Event.current.keyCode == 27)
				{
					_queue.Dismiss();
					Event.current.Use();
				}
			}
			else
			{
				GUI.Label(new Rect(24f, _panelHeight - 30f, _panelWidth - 48f, 22f), (current != null && current.Persistent) ? "Details remain available after disconnecting." : ((_bodyHeight > ((Rect)(ref val)).height) ? "Scroll to read the full message." : ((current == null) ? "Please wait. Files are being prepared for restart." : "From your server")), _caption);
			}
		}

		private void EnsureStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			if (_body == null)
			{
				_body = new GUIStyle(GUI.skin.label)
				{
					fontSize = 17,
					wordWrap = true,
					richText = false,
					padding = new RectOffset(),
					alignment = (TextAnchor)0
				};
				_body.normal.textColor = new Color(0.92f, 0.94f, 0.96f);
				_title = new GUIStyle(_body)
				{
					fontSize = 23,
					fontStyle = (FontStyle)1
				};
				_caption = new GUIStyle(_body)
				{
					fontSize = 12
				};
				_caption.normal.textColor = new Color(0.72f, 0.76f, 0.81f);
				_button = new GUIStyle(GUI.skin.button)
				{
					fontSize = 16,
					richText = false,
					wordWrap = true
				};
			}
		}

		private static void Fill(Rect area, Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Color color2 = GUI.color;
			GUI.color = color;
			GUI.DrawTexture(area, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color2;
		}
	}
}
namespace ValheimServerManager.Client
{
	[BepInPlugin("dev.creaton.valheim-server-manager.client", "Valheim Server Manager Client", "2.6.2")]
	public sealed class ClientPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class ConnectionNoticePatch
		{
			private static void Postfix(ZNet __instance, ZNetPeer __0)
			{
				//IL_014a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0154: Expected O, but got Unknown
				if ((Object)(object)Instance == (Object)null || __instance.IsServer() || __0?.m_rpc == null)
				{
					return;
				}
				Instance.AttachServerPeer(__0);
				__0.m_rpc.Register<bool>("VSM_InspectionPolicy", (Action<ZRpc, bool>)delegate(ZRpc rpc, bool required)
				{
					if (rpc == Instance?._serverRpc)
					{
						Instance.OnInspectionPolicy(required);
					}
				});
				__0.m_rpc.Register<bool, int>("VSM_ServerPolicy", (Action<ZRpc, bool, int>)delegate(ZRpc rpc, bool required, int timeout)
				{
					if (rpc == Instance?._serverRpc)
					{
						Instance.OnServerPolicy(required, timeout);
					}
				});
				__0.m_rpc.Register<string>("VSM_InventoryRequest", (Action<ZRpc, string>)delegate(ZRpc rpc, string requestId)
				{
					if (rpc == Instance?._serverRpc)
					{
						Instance.OnInventoryRequest(__0.m_uid, requestId);
					}
				});
				__0.m_rpc.Register<string>("VSM_ItemCatalogRequest", (Action<ZRpc, string>)delegate(ZRpc rpc, string requestId)
				{
					if (rpc == Instance?._serverRpc)
					{
						Instance.OnItemCatalogRequest(__0.m_uid, requestId);
					}
				});
				__0.m_rpc.Register<string, string, int, int>("VSM_GiveItem", (Method<string, string, int, int>)delegate(ZRpc rpc, string requestId, string prefab, int quantity, int quality)
				{
					if (rpc == Instance?._serverRpc)
					{
						Instance.OnGiveItem(__0.m_uid, requestId, prefab, quantity, quality);
					}
				});
				__0.m_rpc.Register<bool, string, bool>("VSM_CharacterProfile", (Action<ZRpc, bool, string, bool>)delegate(ZRpc rpc, bool found, string encoded, bool rejectPreviouslyUsed)
				{
					if (rpc == Instance?._serverRpc)
					{
						Instance.OnCharacterProfile(__0.m_uid, found, encoded, rejectPreviouslyUsed);
					}
				});
				__0.m_rpc.Register("VSM_CharacterCheckpoint", (Method)delegate(ZRpc rpc)
				{
					if (rpc == Instance?._serverRpc)
					{
						Instance.OnCharacterCheckpoint(__0.m_uid);
					}
				});
				__0.m_rpc.Register<string, string>("VSM_AdminNotice", (Action<ZRpc, string, string>)delegate(ZRpc rpc, string title, string message)
				{
					if (rpc == Instance?._serverRpc)
					{
						Instance.QueueAdminNotice(title, message);
					}
				});
				__0.m_rpc.Register<string>("ValheimServerManager_Manifest_v1", (Action<ZRpc, string>)delegate(ZRpc rpc, string json)
				{
					if (rpc == Instance?._serverRpc)
					{
						Instance.ReceiveModCatalog(json);
					}
				});
				__0.m_rpc.Register<string>("VSM_DiscordActivity", (Action<ZRpc, string>)delegate(ZRpc rpc, string json)
				{
					if (rpc != Instance?._serverRpc)
					{
						return;
					}
					try
					{
						if (json != null && json.Length <= 4096)
						{
							JObject val = JObject.Parse(json);
							Instance._discordApplicationId = (string)val["applicationId"];
							Instance._discordServerName = (string)val["serverName"];
							Instance._discordWorldName = (string)val["worldName"];
							Instance._discordPlayerCount = Math.Max(0, Math.Min(1000, ((int?)val["players"]).GetValueOrDefault()));
							Instance._discordMaxPlayers = Math.Max(1, Math.Min(1000, ((int?)val["maxPlayers"]) ?? 10));
							Instance._discordDetailsTemplate = ((string)val["detailsTemplate"]) ?? "{server}";
							Instance._discordStateTemplate = ((string)val["stateTemplate"]) ?? "{region} · {players} players online";
							Instance._discordImageUrl = (string)val["imageUrl"];
						}
					}
					catch (Exception)
					{
						((BaseUnityPlugin)Instance).Logger.LogDebug((object)"Ignored malformed Discord activity settings from the server.");
					}
				});
			}
		}

		[HarmonyPatch(typeof(Game), "FindSpawnPoint")]
		private static class FindSpawnPointPatch
		{
			private static bool Prefix(ref bool __result)
			{
				if ((Object)(object)Instance == (Object)null || !Instance.ShouldWaitForServerCharacter)
				{
					return true;
				}
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(Game), "SavePlayerProfile")]
		private static class ProfileSavePatch
		{
			private static bool Prefix()
			{
				ClientPlugin instance = Instance;
				if (instance == null)
				{
					return true;
				}
				return !instance._handshake.Failed;
			}

			private static void Postfix()
			{
				Instance?.UploadCharacter(alreadySaved: true);
			}
		}

		[HarmonyPatch(typeof(Player), "OnDeath")]
		private static class DeathPatch
		{
			private static void Postfix(Player __instance)
			{
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				ClientPlugin instance = Instance;
				if (instance != null && instance.TelemetryEnabled && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					HitData value = Traverse.Create((object)__instance).Field("m_lastHit").GetValue<HitData>();
					Character val = ((value != null) ? value.GetAttacker() : null);
					Instance.SendEvent("player.death.reported", new
					{
						player = __instance.GetPlayerName(),
						position = ((Component)__instance).transform.position,
						cause = (((Object)(object)val != (Object)null) ? val.GetHoverName() : "environment"),
						damage = ((value != null) ? value.GetTotalDamage() : 0f)
					});
				}
			}
		}

		[HarmonyPatch(typeof(Character), "OnDeath")]
		private static class KillPatch
		{
			private static void Postfix(Character __instance)
			{
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				ClientPlugin instance = Instance;
				if (instance != null && instance.TelemetryEnabled && !((Object)(object)__instance == (Object)null) && !__instance.IsPlayer() && !((Object)(object)Player.m_localPlayer == (Object)null))
				{
					HitData value = Traverse.Create((object)__instance).Field("m_lastHit").GetValue<HitData>();
					if (!((Object)(object)((value != null) ? value.GetAttacker() : null) != (Object)(object)Player.m_localPlayer))
					{
						Instance.SendEvent(__instance.IsBoss() ? "boss.kill.reported" : "creature.kill.reported", new
						{
							player = Player.m_localPlayer.GetPlayerName(),
							target = __instance.GetHoverName(),
							position = ((Component)__instance).transform.position
						});
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		private static class CraftPatch
		{
			private sealed class CraftState
			{
				public string Name;

				public string Prefab;

				public int Before;
			}

			private static void Prefix(InventoryGui __instance, Player player, out CraftState __state)
			{
				__state = null;
				ClientPlugin instance = Instance;
				if (instance != null && instance.TelemetryEnabled && !((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer))
				{
					Recipe value = Traverse.Create((object)__instance).Field("m_craftRecipe").GetValue<Recipe>();
					ItemData val = value?.m_item?.m_itemData;
					__state = ((val == null) ? null : new CraftState
					{
						Name = val.m_shared.m_name,
						Prefab = ((Object)((Component)value.m_item).gameObject).name,
						Before = ((Humanoid)player).GetInventory().CountItems(val.m_shared.m_name, -1, true)
					});
				}
			}

			private static void Postfix(Player player, CraftState __state)
			{
				if (__state != null && !((Object)(object)player != (Object)(object)Player.m_localPlayer))
				{
					int num = ((Humanoid)player).GetInventory().CountItems(__state.Name, -1, true) - __state.Before;
					if (num > 0)
					{
						Instance.SendEvent("item.crafted", new
						{
							player = player.GetPlayerName(),
							prefab = __state.Prefab,
							name = __state.Name,
							stack = num
						});
					}
				}
			}
		}

		public const string PluginGuid = "dev.creaton.valheim-server-manager.client";

		public const string PluginName = "Valheim Server Manager Client";

		public const string PluginVersion = "2.6.2";

		private const string LegacyPluginGuid = "dev.monokai.valheim-server-manager.client";

		private ConfigEntry<bool> _allowInventory;

		private bool? _advertisedInventory;

		private bool? _inspectionPolicy;

		private ConfigEntry<bool> _allowTelemetry;

		private DiscordActivityClient _discordActivity;

		private string _discordApplicationId;

		private string _discordServerName;

		private string _discordWorldName;

		private string _discordRegion;

		private string _discordDetailsTemplate = "{server}";

		private string _discordStateTemplate = "{region} · {players} players online";

		private string _discordImageUrl;

		private int _discordPlayerCount;

		private int _discordMaxPlayers = 10;

		private float _nextDiscordRegionCheck;

		private ConfigEntry<bool> _enableServerCharacters;

		private ZRoutedRpc _registeredRouter;

		private readonly ClientHandshake _handshake = new ClientHandshake();

		private readonly NoticeOverlay _notices = new NoticeOverlay();

		private readonly Dictionary<int, string> _iconCache = new Dictionary<int, string>();

		private ClientModCatalogStatus _modCatalog;

		private string _lastModCatalog;

		private float _nextModReceipt;

		private bool _bootstrapPending;

		private bool _pendingFirstProfile;

		private bool _rejectPreviouslyUsed;

		private float _nextCharacterUpload;

		private float _nextBiomeCheck;

		private float _nextInventoryRequest;

		private Coroutine _inventoryCapture;

		private byte[] _pendingCharacterProfile;

		private PlayerProfile _serverProfile;

		private string _temporaryProfileName;

		private bool _uploading;

		private Biome _biome;

		private ZNetPeer _serverPeer;

		private ZRpc _serverRpc;

		private static readonly Type LocalizationType = AccessTools.TypeByName("Localization");

		private static readonly FieldInfo LocalizationInstance = ((LocalizationType == null) ? null : AccessTools.Field(LocalizationType, "instance"));

		private static readonly PropertyInfo LocalizationProperty = ((LocalizationType == null) ? null : AccessTools.Property(LocalizationType, "instance"));

		private static readonly MethodInfo LocalizeMethod = ((LocalizationType == null) ? null : AccessTools.Method(LocalizationType, "Localize", new Type[1] { typeof(string) }, (Type[])null));

		internal static ClientPlugin Instance { get; private set; }

		internal bool ShouldWaitForServerCharacter => _handshake.ShouldWait;

		private bool TelemetryEnabled
		{
			get
			{
				if (_allowTelemetry.Value)
				{
					return _serverRpc != null;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			if (Application.isBatchMode)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Client runtime disabled in the dedicated-server process.");
				((Behaviour)this).enabled = false;
				return;
			}
			Instance = this;
			_discordActivity = new DiscordActivityClient();
			MigrateLegacyConfig();
			_allowInventory = ((BaseUnityPlugin)this).Config.Bind<bool>("Privacy", "AllowInventoryInspection", true, "Allow the connected server's authenticated administrators to inspect current stats and inventory, including a live view. Required to join Server Manager realms.");
			_allowTelemetry = ((BaseUnityPlugin)this).Config.Bind<bool>("Privacy", "AllowDetailedTelemetry", false, "Share death and biome events with the connected server.");
			_enableServerCharacters = ((BaseUnityPlugin)this).Config.Bind<bool>("ServerCharacters", "Enabled", true, "Allow this server to make its native character profile authoritative for this session.");
			if (!NoticeInputGuard.Install(new Harmony("dev.creaton.valheim-server-manager.client")))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"The game menu input guard is unavailable on this Valheim build.");
			}
			Harmony.CreateAndPatchAll(typeof(DeathPatch), "dev.creaton.valheim-server-manager.client");
			Harmony.CreateAndPatchAll(typeof(KillPatch), "dev.creaton.valheim-server-manager.client");
			Harmony.CreateAndPatchAll(typeof(CraftPatch), "dev.creaton.valheim-server-manager.client");
			Harmony.CreateAndPatchAll(typeof(FindSpawnPointPatch), "dev.creaton.valheim-server-manager.client");
			Harmony.CreateAndPatchAll(typeof(ProfileSavePatch), "dev.creaton.valheim-server-manager.client");
			Harmony.CreateAndPatchAll(typeof(ConnectionNoticePatch), "dev.creaton.valheim-server-manager.client");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"VSM client component loaded. Inventory inspection is enabled by default; detailed telemetry remains opt-in.");
		}

		private void MigrateLegacyConfig()
		{
			try
			{
				string text = Path.Combine(Paths.ConfigPath, "dev.monokai.valheim-server-manager.client.cfg");
				string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
				if (File.Exists(text) && !File.Exists(configFilePath))
				{
					File.Copy(text, configFilePath, overwrite: false);
				}
				if (File.Exists(configFilePath))
				{
					((BaseUnityPlugin)this).Config.Reload();
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not migrate legacy plugin configuration: " + ex.Message));
			}
		}

		private unsafe void Update()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			_notices.Tick((Object)(object)Player.m_localPlayer != (Object)null);
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				_discordRegion = null;
			}
			else if (_serverRpc != null && !string.IsNullOrEmpty(_discordApplicationId) && Time.unscaledTime >= _nextDiscordRegionCheck)
			{
				_nextDiscordRegionCheck = Time.unscaledTime + 1f;
				string text = ((object)Player.m_localPlayer.GetCurrentBiome()/*cast due to .constrained prefix*/).ToString();
				_discordRegion = text switch
				{
					"None" => null, 
					"BlackForest" => "Black Forest", 
					"DeepNorth" => "Deep North", 
					"AshLands" => "Ashlands", 
					_ => text, 
				};
			}
			_discordActivity?.SetActivity((_serverRpc != null) ? _discordApplicationId : null, _discordServerName, _discordWorldName, _discordPlayerCount, _discordMaxPlayers, _discordRegion, _discordDetailsTemplate, _discordStateTemplate, _discordImageUrl);
			if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer())
			{
				if (_handshake.Active)
				{
					ResetConnection();
				}
				return;
			}
			if (_registeredRouter != ZRoutedRpc.instance && ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.Register<string>("VSM_InventoryRequest", (Action<long, string>)OnInventoryRequest);
				ZRoutedRpc.instance.Register<string>("VSM_ItemCatalogRequest", (Action<long, string>)OnItemCatalogRequest);
				ZRoutedRpc.instance.Register<string, string, int, int>("VSM_GiveItem", (Method<string, string, int, int>)OnGiveItem);
				ZRoutedRpc.instance.Register<bool, string, bool>("VSM_CharacterProfile", (Action<long, bool, string, bool>)OnCharacterProfile);
				ZRoutedRpc.instance.Register("VSM_CharacterCheckpoint", (Action<long>)OnCharacterCheckpoint);
				ZRoutedRpc.instance.Register<string, string>("VSM_AdminNotice", (Action<long, string, string>)OnAdminNotice);
				_registeredRouter = ZRoutedRpc.instance;
			}
			if (_serverRpc != null && (_handshake.TrySendHello(Time.unscaledTime) || (_handshake.Active && _advertisedInventory != _allowInventory.Value)))
			{
				_advertisedInventory = _allowInventory.Value;
				InvokeServer("VSM_ClientHello", _allowInventory.Value, _enableServerCharacters.Value ? "2.6.2" : "");
				((BaseUnityPlugin)this).Logger.LogDebug((object)"Sent VSM capability handshake to the server.");
			}
			if (_serverRpc != null)
			{
				ClientModCatalogStatus modCatalog = _modCatalog;
				if (modCatalog != null && modCatalog.RequiredReceipt && _modCatalog.CanAcknowledge && Time.unscaledTime >= _nextModReceipt)
				{
					_nextModReceipt = Time.unscaledTime + 2f;
					InvokeServer("VSM_ModReceipt", _modCatalog.Revision);
				}
			}
			if (_pendingCharacterProfile != null && (Object)(object)Game.instance != (Object)null)
			{
				ApplyServerProfile();
			}
			if (_pendingFirstProfile && (Object)(object)Game.instance != (Object)null)
			{
				PrepareFirstProfile();
			}
			if (_bootstrapPending && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)Game.instance != (Object)null)
			{
				AdoptCurrentProfile();
			}
			if (_handshake.HasTimedOut(Time.unscaledTime))
			{
				FailCharacter("Server character timed out", "Your server character did not finish loading. Return to the menu and reconnect. If this continues, ask an administrator to check your server save.");
			}
			if (_handshake.RequiresCharacter && _handshake.Ready && (Object)(object)Player.m_localPlayer != (Object)null && Time.unscaledTime >= _nextCharacterUpload)
			{
				_nextCharacterUpload = Time.unscaledTime + 30f;
				UploadCharacter();
			}
			if (_allowTelemetry.Value && (Object)(object)Player.m_localPlayer != (Object)null && Time.unscaledTime >= _nextBiomeCheck)
			{
				_nextBiomeCheck = Time.unscaledTime + 1f;
				Biome currentBiome = Player.m_localPlayer.GetCurrentBiome();
				if ((int)_biome != 0 && currentBiome != _biome)
				{
					SendEvent("player.biome.changed", new
					{
						from = ((object)Unsafe.As<Biome, Biome>(ref _biome)/*cast due to .constrained prefix*/).ToString(),
						to = ((object)(*(Biome*)(&currentBiome))/*cast due to .constrained prefix*/).ToString(),
						player = Player.m_localPlayer.GetPlayerName()
					});
				}
				_biome = currentBiome;
			}
		}

		private void OnInspectionPolicy(bool required)
		{
			if (_inspectionPolicy != required)
			{
				_inspectionPolicy = required;
				if (required && !_allowInventory.Value)
				{
					QueueAdminNotice("Inventory inspection required", "This realm requires live inventory and character inspection by authenticated administrators. Enable Privacy > AllowInventoryInspection in the Server Manager client configuration and reconnect, or choose another realm. Your privacy setting has not been changed; this connection will be refused after the grace period.");
				}
			}
		}

		private void OnServerPolicy(bool serverCharacters, int timeoutSeconds)
		{
			_handshake.SetPolicy(serverCharacters, timeoutSeconds, Time.unscaledTime);
			if (serverCharacters)
			{
				if (!_enableServerCharacters.Value)
				{
					FailCharacter("Server characters required", "This server uses server-owned characters. Enable ServerCharacters → Enabled in your Server Manager client configuration, then reconnect.");
				}
				else if ((Object)(object)Player.m_localPlayer != (Object)null && !_handshake.ReceivedProfile)
				{
					FailCharacter("Reconnect to load your character", "This server requires a server-owned character. Return to the menu and reconnect so it can load before you enter the world.");
				}
			}
		}

		private void OnCharacterProfile(long sender, bool found, string encoded, bool rejectPreviouslyUsed)
		{
			if (_serverRpc == null || sender != ServerPeerId() || !_enableServerCharacters.Value || !_handshake.TryReceiveProfile(Time.unscaledTime))
			{
				return;
			}
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				FailCharacter("Reconnect to load your character", "Your server character arrived after the world loaded. Please reconnect to load it safely.");
				return;
			}
			try
			{
				if (found)
				{
					if (encoded == null || encoded.Length > 2796204)
					{
						throw new InvalidDataException("Server character profile size is invalid.");
					}
					byte[] array = Convert.FromBase64String(encoded ?? "");
					if (array.Length < 32 || array.Length > 2097152)
					{
						throw new InvalidDataException("Server character profile size is invalid.");
					}
					_pendingCharacterProfile = array;
					if ((Object)(object)Game.instance != (Object)null)
					{
						ApplyServerProfile();
					}
				}
				else
				{
					_pendingFirstProfile = true;
					_rejectPreviouslyUsed = rejectPreviouslyUsed;
					if ((Object)(object)Game.instance != (Object)null)
					{
						PrepareFirstProfile();
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Unable to receive server character: " + ex));
				FailCharacter("Server character unavailable", "Your server character could not be read. Reconnect once; if this continues, ask an administrator to restore or re-import your server save.");
			}
		}

		private void PrepareFirstProfile()
		{
			_pendingFirstProfile = false;
			PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
			object obj = ((playerProfile == null) ? null : Traverse.Create((object)playerProfile).Field("m_worldData").GetValue());
			if (playerProfile == null || (_rejectPreviouslyUsed && obj is ICollection { Count: not 0 }))
			{
				FailCharacter("New character required", "Select a character that has never entered a world, or ask an administrator to import your existing save. Then reconnect.");
				return;
			}
			_handshake.CompleteProfile();
			_bootstrapPending = true;
		}

		private void FailCharacter(string title, string message)
		{
			_handshake.Fail();
			_pendingCharacterProfile = null;
			_pendingFirstProfile = (_bootstrapPending = false);
			QueueAdminNotice(title, message);
			if ((Object)(object)Game.instance != (Object)null)
			{
				Game.instance.Logout(true, true);
				return;
			}
			ZRpc serverRpc = _serverRpc;
			if (serverRpc != null)
			{
				ISocket socket = serverRpc.GetSocket();
				if (socket != null)
				{
					socket.Close();
				}
			}
		}

		private void OnAdminNotice(long sender, string title, string message)
		{
			if (_serverRpc != null && sender == ServerPeerId())
			{
				QueueAdminNotice(title, message);
			}
		}

		private void QueueAdminNotice(string title, string message)
		{
			NoticeKind kind = ClientNotice.ForServerTitle(title);
			_notices.Show(title, message, kind);
		}

		private void ReceiveModCatalog(string json)
		{
			if (string.Equals(json, _lastModCatalog, StringComparison.Ordinal))
			{
				return;
			}
			try
			{
				_modCatalog = ClientModCompatibility.Check(json, Paths.BepInExRootPath);
				_lastModCatalog = json;
				_nextModReceipt = 0f;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Checked server mods against the active BepInEx profile.");
				if (!_modCatalog.RequiredReceipt || _modCatalog.CanAcknowledge)
				{
					return;
				}
				string[] array = (from package in _modCatalog.Required
					where !package.Present
					select package.Namespace + "-" + package.Name + "-" + package.Version + ((package.InstalledVersion == null) ? " (missing)" : (" (found " + package.InstalledVersion + ")"))).ToArray();
				List<string> list = new List<string>();
				if (array.Length != 0)
				{
					list.Add("Required versions:\n" + string.Join("\n", array));
				}
				if (_modCatalog.Unexpected.Count > 0)
				{
					list.Add("Unapproved packages:\n" + string.Join("\n", _modCatalog.Unexpected));
				}
				QueueAdminNotice("Mod list does not match", string.Join("\n\n", list) + "\n\nChange this profile in your external mod manager, restart Valheim, then reconnect.");
				ZRpc serverRpc = _serverRpc;
				if (serverRpc != null)
				{
					ISocket socket = serverRpc.GetSocket();
					if (socket != null)
					{
						socket.Close();
					}
				}
			}
			catch (Exception ex)
			{
				_modCatalog = null;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not check the server mod list: " + ex.Message));
				QueueAdminNotice("Mod list unavailable", "The server's mod list could not be checked. Review your BepInEx log and reconnect.");
				ZRpc serverRpc2 = _serverRpc;
				if (serverRpc2 != null)
				{
					ISocket socket2 = serverRpc2.GetSocket();
					if (socket2 != null)
					{
						socket2.Close();
					}
				}
			}
		}

		private void OnGUI()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				_notices.Draw();
			}
		}

		private void ApplyServerProfile()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			if (_pendingCharacterProfile == null || (Object)(object)Game.instance == (Object)null)
			{
				return;
			}
			try
			{
				PrepareTemporaryProfileName();
				string characterPath = SaveSystem.GetCharacterPath((FileSource)2, _temporaryProfileName);
				Directory.CreateDirectory(Path.GetDirectoryName(characterPath));
				File.WriteAllBytes(characterPath, _pendingCharacterProfile);
				PlayerProfile val = new PlayerProfile(_temporaryProfileName, (FileSource)2);
				if (!val.Load())
				{
					throw new InvalidDataException("Valheim rejected the server-owned native character profile.");
				}
				Traverse.Create((object)Game.instance).Field("m_playerProfile").SetValue((object)val);
				_serverProfile = val;
				_pendingCharacterProfile = null;
				_handshake.CompleteProfile();
				_nextCharacterUpload = Time.unscaledTime + 30f;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Server-owned character profile loaded for " + val.GetName() + "."));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Unable to apply server-owned character: " + ex));
				FailCharacter("Server character unavailable", "Your server character could not be loaded. Check that Valheim can write to its save folder, then reconnect. If it still fails, ask an administrator to check your server save.");
			}
		}

		private void AdoptCurrentProfile()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			if (!_bootstrapPending || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Game.instance == (Object)null)
			{
				return;
			}
			try
			{
				PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
				PrepareTemporaryProfileName();
				PlayerProfile val = new PlayerProfile(_temporaryProfileName, (FileSource)2);
				val.SetName(playerProfile.GetName());
				Traverse.Create((object)val).Field("m_playerID").SetValue((object)playerProfile.GetPlayerID());
				val.SavePlayerData(Player.m_localPlayer);
				Traverse.Create((object)Game.instance).Field("m_playerProfile").SetValue((object)val);
				_serverProfile = val;
				_bootstrapPending = false;
				_handshake.CompleteProfile();
				UploadCharacter();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("First server-owned character profile created for " + val.GetName() + "."));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Unable to seed server-owned character: " + ex));
				FailCharacter("Character import failed", "Your first server character could not be created. Check that Valheim can write to its save folder, then reconnect.");
			}
		}

		private void PrepareTemporaryProfileName()
		{
			if (string.IsNullOrEmpty(_temporaryProfileName))
			{
				_temporaryProfileName = "VSMServer_" + Guid.NewGuid().ToString("N");
			}
		}

		private void OnCharacterCheckpoint(long sender)
		{
			if (_serverRpc != null && sender == ServerPeerId())
			{
				UploadCharacter();
			}
		}

		internal void UploadCharacter(bool alreadySaved = false)
		{
			if (_uploading || !_handshake.RequiresCharacter || !_handshake.Ready || _serverProfile == null || (Object)(object)Player.m_localPlayer == (Object)null || _serverRpc == null)
			{
				return;
			}
			_uploading = true;
			try
			{
				if (!alreadySaved)
				{
					_serverProfile.SavePlayerData(Player.m_localPlayer);
					_serverProfile.SaveLogoutPoint();
					if (!_serverProfile.Save())
					{
						throw new IOException("Valheim could not serialize the server-owned character.");
					}
				}
				string path = _serverProfile.GetPath();
				byte[] array = File.ReadAllBytes(path);
				if (array.Length > 2097152)
				{
					throw new InvalidDataException("Server character profile exceeds 2 MiB.");
				}
				InvokeServer("VSM_CharacterUpload", Convert.ToBase64String(array));
				_nextCharacterUpload = Time.unscaledTime + 30f;
				try
				{
					File.Delete(path);
				}
				catch
				{
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Unable to upload server-owned character: " + ex));
			}
			finally
			{
				_uploading = false;
			}
		}

		private void ResetConnection()
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			_discordActivity?.SetActivity(null, null, null, 0, 0, null, null, null, null);
			_discordApplicationId = (_discordServerName = (_discordWorldName = (_discordRegion = null)));
			_discordDetailsTemplate = "{server}";
			_discordStateTemplate = "{region} · {players} players online";
			_discordImageUrl = null;
			_discordPlayerCount = 0;
			_discordMaxPlayers = 10;
			_nextDiscordRegionCheck = 0f;
			_advertisedInventory = null;
			_inspectionPolicy = null;
			if (!string.IsNullOrEmpty(_temporaryProfileName))
			{
				try
				{
					File.Delete(SaveSystem.GetCharacterPath((FileSource)2, _temporaryProfileName));
				}
				catch
				{
				}
			}
			_handshake.Reset();
			_registeredRouter = null;
			_bootstrapPending = false;
			_pendingFirstProfile = false;
			_pendingCharacterProfile = null;
			_serverProfile = null;
			_temporaryProfileName = null;
			_serverPeer = null;
			_serverRpc = null;
			_biome = (Biome)0;
			_nextBiomeCheck = (_nextInventoryRequest = 0f);
			if (_inventoryCapture != null)
			{
				((MonoBehaviour)this).StopCoroutine(_inventoryCapture);
			}
			_inventoryCapture = null;
			_iconCache.Clear();
			_notices.ClearTransient();
			_modCatalog = null;
			_lastModCatalog = null;
		}

		private void AttachServerPeer(ZNetPeer peer)
		{
			ResetConnection();
			_serverPeer = peer;
			_serverRpc = peer?.m_rpc;
			_handshake.Begin(Time.unscaledTime);
		}

		private void OnDestroy()
		{
			_discordActivity?.Dispose();
			_notices.Dispose();
			ResetConnection();
			Harmony.UnpatchID("dev.creaton.valheim-server-manager.client");
			if (Instance == this)
			{
				Instance = null;
			}
		}

		private void OnInventoryRequest(long sender, string requestId)
		{
			long num = ServerPeerId();
			if (_serverRpc == null || sender != num || string.IsNullOrEmpty(requestId) || requestId.Length > 100)
			{
				return;
			}
			if (!_allowInventory.Value)
			{
				Reply(requestId, new
				{
					ok = false,
					status = "denied",
					error = "The player has not enabled inventory inspection."
				});
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				Reply(requestId, new
				{
					ok = false,
					status = "unavailable",
					error = "Player character is not loaded."
				});
				return;
			}
			if (_inventoryCapture != null || Time.unscaledTime < _nextInventoryRequest)
			{
				Reply(requestId, new
				{
					ok = false,
					status = "busy",
					error = "An inventory snapshot is already being prepared. Try again in a moment."
				});
				return;
			}
			_nextInventoryRequest = Time.unscaledTime + 1f;
			try
			{
				CaptureInventory(requestId, localPlayer);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not prepare inventory snapshot: " + ex.Message));
				Reply(requestId, new
				{
					ok = false,
					status = "unavailable",
					error = "The character snapshot could not be prepared. Try again in a moment."
				});
			}
		}

		private void OnItemCatalogRequest(long sender, string requestId)
		{
			if (_serverRpc == null || sender != ServerPeerId() || string.IsNullOrEmpty(requestId) || requestId.Length > 100)
			{
				return;
			}
			if (!_allowInventory.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				Reply(requestId, new
				{
					ok = false,
					error = "The item catalog is unavailable."
				});
				return;
			}
			try
			{
				var items = (from prefab in ObjectDB.instance.m_items
					where (Object)(object)prefab != (Object)null && (Object)(object)prefab.GetComponent<ItemDrop>() != (Object)null
					select new
					{
						prefab = ((Object)prefab).name,
						name = Localize(prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name),
						maxStack = Math.Max(1, prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize),
						maxQuality = Math.Max(1, prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxQuality)
					} into item
					orderby item.name, item.prefab
					select item).ToArray();
				Reply(requestId, new
				{
					ok = true,
					items = items
				});
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not build item catalog: " + ex.Message));
				Reply(requestId, new
				{
					ok = false,
					error = "The item catalog could not be loaded."
				});
			}
		}

		private void OnGiveItem(long sender, string requestId, string prefab, int quantity, int quality)
		{
			if (_serverRpc == null || sender != ServerPeerId() || string.IsNullOrEmpty(requestId) || requestId.Length > 100)
			{
				return;
			}
			if (!_allowInventory.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				GiveReply(requestId, new
				{
					ok = false,
					error = "The player inventory is unavailable."
				});
				return;
			}
			if (string.IsNullOrEmpty(prefab) || prefab.Length > 128 || quantity < 1 || quantity > 1000 || quality < 1 || quality > 100)
			{
				GiveReply(requestId, new
				{
					ok = false,
					error = "Invalid item, quantity, or quality."
				});
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab);
			ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val == (Object)null || ((Object)((Component)val).gameObject).name != prefab)
			{
				GiveReply(requestId, new
				{
					ok = false,
					error = "Item prefab is not available on this client."
				});
				return;
			}
			SharedData shared = val.m_itemData.m_shared;
			if (quality > Math.Max(1, shared.m_maxQuality))
			{
				GiveReply(requestId, new
				{
					ok = false,
					error = "Quality exceeds this item's maximum."
				});
				return;
			}
			int num = 0;
			try
			{
				Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
				while (num < quantity)
				{
					int num2 = Math.Min(quantity - num, Math.Max(1, shared.m_maxStackSize));
					int num3 = (from item in inventory.GetAllItems()
						where (Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == prefab && item.m_quality == quality
						select item).Sum((ItemData item) => item.m_stack);
					AddGivenItem(inventory, prefab, num2, quality);
					int num4 = (from item in inventory.GetAllItems()
						where (Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == prefab && item.m_quality == quality
						select item).Sum((ItemData item) => item.m_stack);
					int num5 = Math.Max(0, Math.Min(num2, num4 - num3));
					num += num5;
					if (num5 < num2)
					{
						break;
					}
				}
				GiveReply(requestId, new
				{
					ok = (num > 0),
					prefab = prefab,
					requested = quantity,
					given = num,
					quality = quality,
					error = ((num == quantity) ? null : "Inventory is full; only part of the quantity could be delivered.")
				});
				if (num > 0)
				{
					UploadCharacter();
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not give item: " + ex.Message));
				GiveReply(requestId, new
				{
					ok = (num > 0),
					prefab = prefab,
					requested = quantity,
					given = num,
					quality = quality,
					error = "Delivery stopped before the full quantity was added."
				});
				if (num > 0)
				{
					UploadCharacter();
				}
			}
		}

		private void GiveReply(string requestId, object payload)
		{
			InvokeServer("VSM_GiveResponse", requestId, JsonConvert.SerializeObject(payload));
		}

		private static void AddGivenItem(Inventory inventory, string prefab, int stack, int quality)
		{
			MethodInfo methodInfo = typeof(Inventory).GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo candidate) => candidate.Name == "AddItem" && (from parameter in candidate.GetParameters()
				select parameter.ParameterType).Take(6).SequenceEqual(new Type[6]
			{
				typeof(string),
				typeof(int),
				typeof(int),
				typeof(int),
				typeof(long),
				typeof(string)
			}) && candidate.GetParameters().Skip(6).All((ParameterInfo parameter) => parameter.ParameterType == typeof(bool)));
			if (methodInfo == null)
			{
				throw new MissingMethodException("Inventory.AddItem");
			}
			object[] array = new object[methodInfo.GetParameters().Length];
			array[0] = prefab;
			array[1] = stack;
			array[2] = quality;
			array[3] = 0;
			array[4] = 0L;
			array[5] = "";
			for (int num = 6; num < array.Length; num++)
			{
				array[num] = false;
			}
			methodInfo.Invoke(inventory, array);
		}

		private void CaptureInventory(string requestId, Player player)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = ((Humanoid)player).GetInventory();
			Dictionary<string, string> icons = new Dictionary<string, string>();
			Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>();
			var items = inventory.GetAllItems().Select(delegate(ItemData item)
			{
				string obj = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : item.m_shared.m_name);
				string text = obj + ":" + item.m_variant;
				if (!sprites.ContainsKey(text))
				{
					sprites[text] = item.GetIcon();
				}
				return new
				{
					prefab = obj,
					name = Localize(item.m_shared.m_name),
					description = Localize(item.m_shared.m_description),
					type = ((object)Unsafe.As<ItemType, ItemType>(ref item.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString(),
					stack = item.m_stack,
					maxStack = item.m_shared.m_maxStackSize,
					quality = item.m_quality,
					maxQuality = item.m_shared.m_maxQuality,
					durability = item.m_durability,
					maxDurability = item.GetMaxDurability(),
					weight = item.GetWeight(-1),
					equipped = item.m_equipped,
					x = item.m_gridPos.x,
					y = item.m_gridPos.y,
					variant = item.m_variant,
					crafterName = item.m_crafterName,
					crafterId = item.m_crafterID.ToString(),
					teleportable = item.m_shared.m_teleportable,
					iconKey = text
				};
			}).ToArray();
			var skills = (from skill in ((Character)player).GetSkills().GetSkillList()
				where skill.m_level > 0f
				orderby skill.m_level descending
				select new
				{
					name = ((object)Unsafe.As<SkillType, SkillType>(ref skill.m_info.m_skill)/*cast due to .constrained prefix*/).ToString(),
					level = skill.m_level
				}).ToArray();
			var snapshot = new
			{
				ok = true,
				status = "available",
				player = player.GetPlayerName(),
				capturedAt = DateTime.UtcNow.ToString("O"),
				character = new
				{
					id = player.GetPlayerID().ToString(),
					name = player.GetPlayerName(),
					biome = ((object)player.GetCurrentBiome()/*cast due to .constrained prefix*/).ToString(),
					health = ((Character)player).GetHealth(),
					maxHealth = ((Character)player).GetMaxHealth(),
					stamina = player.GetStamina(),
					maxStamina = ((Character)player).GetMaxStamina(),
					eitr = player.GetEitr(),
					maxEitr = ((Character)player).GetMaxEitr(),
					armor = ((Character)player).GetBodyArmor(),
					inventoryWidth = inventory.GetWidth(),
					inventoryHeight = inventory.GetHeight(),
					weight = inventory.GetTotalWeight(),
					skills = skills
				},
				items = items,
				icons = icons
			};
			_inventoryCapture = ((MonoBehaviour)this).StartCoroutine(ReplyWithIcons(requestId, snapshot, sprites, icons, _serverRpc));
		}

		private IEnumerator ReplyWithIcons(string requestId, object snapshot, Dictionary<string, Sprite> sprites, Dictionary<string, string> icons, ZRpc serverRpc)
		{
			yield return null;
			int renderedThisFrame = 0;
			foreach (KeyValuePair<string, Sprite> sprite in sprites)
			{
				if (serverRpc != _serverRpc || !_allowInventory.Value)
				{
					break;
				}
				if ((Object)(object)sprite.Value == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)sprite.Value).GetInstanceID();
				if (!_iconCache.TryGetValue(instanceID, out var value))
				{
					value = EncodeIcon(sprite.Value);
					if (_iconCache.Count >= 256)
					{
						_iconCache.Clear();
					}
					_iconCache[instanceID] = value;
					renderedThisFrame++;
				}
				if (!string.IsNullOrEmpty(value))
				{
					icons[sprite.Key] = value;
				}
				if (renderedThisFrame >= 2)
				{
					renderedThisFrame = 0;
					yield return null;
				}
			}
			try
			{
				if (serverRpc == _serverRpc)
				{
					if (_allowInventory.Value)
					{
						Reply(requestId, snapshot);
					}
					else
					{
						Reply(requestId, new
						{
							ok = false,
							status = "denied",
							error = "Inventory inspection was disabled by the player."
						});
					}
				}
			}
			finally
			{
				_inventoryCapture = null;
			}
		}

		private static string Localize(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return string.Empty;
			}
			try
			{
				object obj = LocalizationInstance?.GetValue(null) ?? LocalizationProperty?.GetValue(null, null);
				return (obj != null && LocalizeMethod != null) ? ((string)LocalizeMethod.Invoke(obj, new object[1] { value })) : value;
			}
			catch
			{
				return value;
			}
		}

		private string EncodeIcon(Sprite sprite)
		{
			//IL_0037: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sprite == (Object)null || (Object)(object)sprite.texture == (Object)null)
			{
				return null;
			}
			RenderTexture val = null;
			Texture2D val2 = null;
			RenderTexture active = RenderTexture.active;
			try
			{
				val = (RenderTexture.active = RenderTexture.GetTemporary(48, 48, 0, (RenderTextureFormat)0));
				GL.Clear(true, true, Color.clear);
				Rect textureRect = sprite.textureRect;
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(((Rect)(ref textureRect)).width / (float)((Texture)sprite.texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)sprite.texture).height);
				Vector2 val4 = default(Vector2);
				((Vector2)(ref val4))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)sprite.texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)sprite.texture).height);
				Graphics.Blit((Texture)(object)sprite.texture, val, val3, val4);
				val2 = new Texture2D(48, 48, (TextureFormat)4, false);
				val2.ReadPixels(new Rect(0f, 0f, 48f, 48f), 0, 0);
				val2.Apply();
				byte[] array = ImageConversion.EncodeToPNG(val2);
				return (array == null || array.Length == 0) ? null : ("data:image/png;base64," + Convert.ToBase64String(array));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Unable to encode inventory icon: " + ex.Message));
				return null;
			}
			finally
			{
				RenderTexture.active = active;
				if ((Object)(object)val2 != (Object)null)
				{
					Object.Destroy((Object)(object)val2);
				}
				if ((Object)(object)val != (Object)null)
				{
					RenderTexture.ReleaseTemporary(val);
				}
			}
		}

		private void Reply(string requestId, object payload)
		{
			InvokeServer("VSM_InventoryResponse", requestId, JsonConvert.SerializeObject(payload));
		}

		internal void SendEvent(string eventType, object data)
		{
			if (TelemetryEnabled)
			{
				InvokeServer("VSM_CompanionEvent", JsonConvert.SerializeObject((object)new { eventType, data }));
			}
		}

		private static void InvokeServer(string methodName, params object[] arguments)
		{
			ClientPlugin instance = Instance;
			if (instance != null)
			{
				ZRpc serverRpc = instance._serverRpc;
				if (serverRpc != null)
				{
					serverRpc.Invoke(methodName, arguments);
				}
			}
		}

		private static long ServerPeerId()
		{
			return (Instance?._serverPeer?.m_uid).GetValueOrDefault();
		}
	}
	internal sealed class DiscordActivityClient : IDisposable
	{
		private sealed class ActivityState
		{
			internal readonly string ApplicationId;

			internal readonly string ServerName;

			internal readonly string WorldName;

			internal readonly string Region;

			internal readonly string DetailsTemplate;

			internal readonly string StateTemplate;

			internal readonly string ImageUrl;

			internal readonly int Players;

			internal readonly int MaxPlayers;

			internal ActivityState(string applicationId, string serverName, string worldName, int players, int maxPlayers, string region, string detailsTemplate, string stateTemplate, string imageUrl)
			{
				ApplicationId = applicationId;
				ServerName = serverName;
				WorldName = worldName ?? "World";
				Players = Math.Max(0, players);
				MaxPlayers = Math.Max(1, maxPlayers);
				Region = region;
				DetailsTemplate = detailsTemplate ?? "{server}";
				StateTemplate = stateTemplate ?? "{region} · {players} players online";
				ImageUrl = ((Uri.TryCreate(imageUrl, UriKind.Absolute, out Uri result) && result.Scheme == Uri.UriSchemeHttps && imageUrl.Length <= 300) ? imageUrl : null);
			}

			internal static bool Same(ActivityState left, ActivityState right)
			{
				if (left != right)
				{
					if (left != null && right != null && left.ApplicationId == right.ApplicationId && left.ServerName == right.ServerName && left.WorldName == right.WorldName && left.Players == right.Players && left.MaxPlayers == right.MaxPlayers && left.Region == right.Region && left.DetailsTemplate == right.DetailsTemplate && left.StateTemplate == right.StateTemplate)
					{
						return left.ImageUrl == right.ImageUrl;
					}
					return false;
				}
				return true;
			}
		}

		private sealed class UnixSocketPath : EndPoint
		{
			private readonly string _path;

			public override AddressFamily AddressFamily => AddressFamily.Unix;

			internal UnixSocketPath(string path)
			{
				_path = path;
			}

			public override SocketAddress Serialize()
			{
				byte[] bytes = Encoding.UTF8.GetBytes(_path);
				if (bytes.Length >= 108)
				{
					throw new ArgumentException("Discord IPC path is too long.");
				}
				SocketAddress socketAddress = new SocketAddress(AddressFamily.Unix, bytes.Length + 3);
				for (int i = 0; i < bytes.Length; i++)
				{
					socketAddress[i + 2] = bytes[i];
				}
				return socketAddress;
			}
		}

		private readonly object _sync = new object();

		private readonly AutoResetEvent _changed = new AutoResetEvent(initialState: false);

		private readonly Thread _worker;

		private readonly string _pipePrefix;

		private Stream _activeStream;

		private ActivityState _desired;

		private bool _disposed;

		internal DiscordActivityClient(string pipePrefix = "discord-ipc-")
		{
			_pipePrefix = pipePrefix;
			_worker = new Thread(Run)
			{
				IsBackground = true,
				Name = "VSM Discord activity"
			};
			_worker.Start();
		}

		internal void SetActivity(string applicationId, string serverName, string worldName, int players, int maxPlayers, string region, string detailsTemplate, string stateTemplate, string imageUrl)
		{
			object obj;
			if (applicationId != null)
			{
				int length = applicationId.Length;
				if (length >= 17 && length <= 20 && applicationId.All((char character) => character >= '0' && character <= '9') && !string.IsNullOrWhiteSpace(serverName))
				{
					obj = new ActivityState(applicationId, serverName, worldName, players, maxPlayers, region, detailsTemplate, stateTemplate, imageUrl);
					goto IL_005a;
				}
			}
			obj = null;
			goto IL_005a;
			IL_005a:
			ActivityState activityState = (ActivityState)obj;
			lock (_sync)
			{
				if (_disposed || ActivityState.Same(_desired, activityState))
				{
					return;
				}
				_desired = activityState;
			}
			_changed.Set();
		}

		private void Run()
		{
			Stream stream = null;
			string text = null;
			ActivityState left = null;
			DateTime dateTime = DateTime.MinValue;
			while (true)
			{
				ActivityState desired;
				lock (_sync)
				{
					if (_disposed)
					{
						break;
					}
					desired = _desired;
					goto IL_0044;
				}
				IL_0044:
				try
				{
					if (stream != null && (desired == null || text != desired.ApplicationId))
					{
						SendActivity(stream, null);
						Close(stream);
						stream = null;
						text = null;
					}
					if (desired == null)
					{
						_changed.WaitOne(1000);
						continue;
					}
					if (stream != null)
					{
						goto IL_013c;
					}
					stream = Connect();
					if (stream == null)
					{
						_changed.WaitOne(5000);
						continue;
					}
					lock (_sync)
					{
						if (_disposed)
						{
							break;
						}
						_activeStream = stream;
						goto IL_00df;
					}
					IL_00df:
					SendFrame(stream, 0, new
					{
						v = 1,
						client_id = desired.ApplicationId
					});
					(int, JObject) tuple = ReadFrame(stream);
					if (tuple.Item1 != 1 || (string)tuple.Item2["evt"] != "READY")
					{
						throw new IOException("Discord rejected the IPC handshake.");
					}
					text = desired.ApplicationId;
					left = null;
					goto IL_013c;
					IL_013c:
					if (!ActivityState.Same(left, desired) || DateTime.UtcNow - dateTime > TimeSpan.FromSeconds(60.0))
					{
						SendActivity(stream, desired);
						left = desired;
						dateTime = DateTime.UtcNow;
					}
					_changed.WaitOne(1000);
					continue;
				}
				catch (Exception)
				{
					Close(stream);
					stream = null;
					text = null;
					lock (_sync)
					{
						if (_disposed)
						{
							break;
						}
					}
					_changed.WaitOne(5000);
					continue;
				}
			}
			if (stream != null)
			{
				try
				{
					SendActivity(stream, null);
				}
				catch
				{
				}
				Close(stream);
			}
		}

		private void Close(Stream stream)
		{
			stream?.Dispose();
			lock (_sync)
			{
				if (_activeStream == stream)
				{
					_activeStream = null;
				}
			}
		}

		private static void SendActivity(Stream stream, ActivityState activity)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			string text = Guid.NewGuid().ToString("N");
			JObject val = null;
			if (activity != null)
			{
				val = new JObject
				{
					["details"] = JToken.op_Implicit(RenderTemplate(activity.DetailsTemplate, activity)),
					["state"] = JToken.op_Implicit(RenderTemplate(activity.StateTemplate, activity))
				};
				if (!string.IsNullOrEmpty(activity.ImageUrl))
				{
					val["assets"] = (JToken)(object)JObject.FromObject((object)new
					{
						large_image = activity.ImageUrl,
						large_text = activity.ServerName
					});
				}
			}
			SendFrame(stream, 1, new
			{
				cmd = "SET_ACTIVITY",
				nonce = text,
				args = new
				{
					pid = Process.GetCurrentProcess().Id,
					activity = val
				}
			});
			for (int i = 0; i < 4; i++)
			{
				(int, JObject) tuple = ReadFrame(stream);
				if (tuple.Item1 == 3)
				{
					SendFrame(stream, 4, tuple.Item2);
					continue;
				}
				if (tuple.Item1 != 1)
				{
					throw new IOException("Discord closed the IPC connection.");
				}
				if (!((string)tuple.Item2["nonce"] != text))
				{
					if ((string)tuple.Item2["evt"] == "ERROR")
					{
						throw new IOException("Discord rejected the activity.");
					}
					return;
				}
			}
			throw new IOException("Discord did not acknowledge the activity.");
		}

		private static string RenderTemplate(string template, ActivityState activity)
		{
			string text = (template ?? "{server}").Replace("{server}", activity.ServerName).Replace("{world}", activity.WorldName);
			int players = activity.Players;
			string text2 = text.Replace("{players}", players.ToString());
			players = activity.MaxPlayers;
			string text3 = text2.Replace("{maxPlayers}", players.ToString()).Replace("{freeSlots}", Math.Max(0, activity.MaxPlayers - activity.Players).ToString()).Replace("{region}", string.IsNullOrWhiteSpace(activity.Region) ? "Exploring" : activity.Region)
				.Trim();
			if (text3.Length > 128)
			{
				text3 = text3.Substring(0, 128);
			}
			if (text3.Length >= 2)
			{
				return text3;
			}
			return "Valheim";
		}

		private Stream Connect()
		{
			for (int i = 0; i < 10; i++)
			{
				try
				{
					if (Environment.OSVersion.Platform == PlatformID.Win32NT)
					{
						NamedPipeClientStream namedPipeClientStream = new NamedPipeClientStream(".", _pipePrefix + i, PipeDirection.InOut);
						try
						{
							namedPipeClientStream.Connect(100);
							return namedPipeClientStream;
						}
						catch
						{
							namedPipeClientStream.Dispose();
							throw;
						}
					}
					foreach (string item in new string[5]
					{
						Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"),
						Environment.GetEnvironmentVariable("TMPDIR"),
						Environment.GetEnvironmentVariable("TMP"),
						Environment.GetEnvironmentVariable("TEMP"),
						"/tmp"
					}.Where((string value) => !string.IsNullOrWhiteSpace(value)).Distinct())
					{
						Socket socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP)
						{
							ReceiveTimeout = 3000,
							SendTimeout = 3000
						};
						try
						{
							socket.Connect(new UnixSocketPath(Path.Combine(item, _pipePrefix + i)));
							return new NetworkStream(socket, ownsSocket: true);
						}
						catch
						{
							socket.Dispose();
						}
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static void SendFrame(Stream stream, int opcode, object payload)
		{
			byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload));
			byte[] array = new byte[8 + bytes.Length];
			Buffer.BlockCopy(BitConverter.GetBytes(opcode), 0, array, 0, 4);
			Buffer.BlockCopy(BitConverter.GetBytes(bytes.Length), 0, array, 4, 4);
			Buffer.BlockCopy(bytes, 0, array, 8, bytes.Length);
			stream.Write(array, 0, array.Length);
		}

		private static (int Opcode, JObject Body) ReadFrame(Stream stream)
		{
			byte[] array = new byte[8];
			ReadExact(stream, array);
			int num = BitConverter.ToInt32(array, 4);
			if (num < 0 || num > 65536)
			{
				throw new InvalidDataException("Discord IPC frame is too large.");
			}
			byte[] bytes = new byte[num];
			ReadExact(stream, bytes);
			return (Opcode: BitConverter.ToInt32(array, 0), Body: JObject.Parse(Encoding.UTF8.GetString(bytes)));
		}

		private static void ReadExact(Stream stream, byte[] bytes)
		{
			int num;
			for (int i = 0; i < bytes.Length; i += num)
			{
				num = stream.Read(bytes, i, bytes.Length - i);
				if (num == 0)
				{
					throw new EndOfStreamException();
				}
			}
		}

		public void Dispose()
		{
			Stream activeStream;
			lock (_sync)
			{
				if (_disposed)
				{
					return;
				}
				_disposed = true;
				activeStream = _activeStream;
			}
			activeStream?.Dispose();
			_changed.Set();
			if (_worker.Join(3500))
			{
				_changed.Dispose();
			}
		}
	}
}