Decompiled source of SOTFEdit Companion v1.0.2

BepInEx/plugins/SOTFEdit_Companion/MessagePack.Annotations.dll

Decompiled 9 months ago
using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("2.5.108.51978")]
[assembly: AssemblyInformationalVersion("2.5.108+cb0ad5dd95")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("neuecc,aarnott")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Yoshifumi Kawai and contributors. All rights reserved.")]
[assembly: AssemblyDescription("Attributes and interfaces for .NET types serializable with MessagePack.")]
[assembly: AssemblyProduct("MessagePack.Annotations")]
[assembly: AssemblyTitle("MessagePack.Annotations")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/neuecc/MessagePack-CSharp")]
[assembly: AssemblyVersion("2.5.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
[GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.5.119.9565")]
[ExcludeFromCodeCoverage]
internal static class ThisAssembly
{
	internal const string AssemblyConfiguration = "Release";

	internal const string AssemblyFileVersion = "2.5.108.51978";

	internal const string AssemblyInformationalVersion = "2.5.108+cb0ad5dd95";

	internal const string AssemblyName = "MessagePack.Annotations";

	internal const string AssemblyTitle = "MessagePack.Annotations";

	internal const string AssemblyVersion = "2.5.0.0";

	internal static readonly DateTime GitCommitDate = new DateTime(638145736080000000L, DateTimeKind.Utc);

	internal const string GitCommitId = "cb0ad5dd955cb9b14ca63019938a6aada43ce822";

	internal const bool IsPrerelease = false;

	internal const bool IsPublicRelease = true;

	internal const string PublicKey = "0024000004800000940000000602000000240000525341310004000001000100293894d4e8ad2b53afbea4e949ef54c2a388b08b5ebd143c811da82f22aa20c839ed1c0b4da83e7195e8c1dbe1bf3934e4e8fd7fb93f893439106fbf055a97c7fac0f7f8c39e58e78371dc0e3825e5b9d7e2afff0372f03c4d67ff7df0dbfb58dcadeb1044840de152bf8270de7fc54255ace8efd026c16311760d1a2570c3e8";

	internal const string PublicKeyToken = "b4a0369545f0a1be";

	internal const string RootNamespace = "MessagePack";
}
namespace MessagePack
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
	public class MessagePackObjectAttribute : Attribute
	{
		public bool KeyAsPropertyName { get; private set; }

		public MessagePackObjectAttribute(bool keyAsPropertyName = false)
		{
			KeyAsPropertyName = keyAsPropertyName;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
	public class KeyAttribute : Attribute
	{
		public int? IntKey { get; private set; }

		public string? StringKey { get; private set; }

		public KeyAttribute(int x)
		{
			IntKey = x;
		}

		public KeyAttribute(string x)
		{
			StringKey = x ?? throw new ArgumentNullException("x");
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
	public class IgnoreMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
	public class UnionAttribute : Attribute
	{
		public int Key { get; private set; }

		public Type SubType { get; private set; }

		public UnionAttribute(int key, Type subType)
		{
			Key = key;
			SubType = subType ?? throw new ArgumentNullException("subType");
		}

		public UnionAttribute(int key, string subType)
		{
			Key = key;
			SubType = Type.GetType(subType, throwOnError: true);
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = true)]
	public class SerializationConstructorAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]
	public class MessagePackFormatterAttribute : Attribute
	{
		public Type FormatterType { get; private set; }

		public object?[]? Arguments { get; private set; }

		public MessagePackFormatterAttribute(Type formatterType)
		{
			FormatterType = formatterType ?? throw new ArgumentNullException("formatterType");
		}

		public MessagePackFormatterAttribute(Type formatterType, params object?[]? arguments)
		{
			FormatterType = formatterType ?? throw new ArgumentNullException("formatterType");
			Arguments = arguments;
		}
	}
	public interface IMessagePackSerializationCallbackReceiver
	{
		void OnBeforeSerialize();

		void OnAfterDeserialize();
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

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

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
}

BepInEx/plugins/SOTFEdit_Companion/MessagePack.dll

Decompiled 9 months ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Buffers.Text;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.ComponentModel;
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.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
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 MessagePack.Formatters;
using MessagePack.ImmutableCollection;
using MessagePack.Internal;
using MessagePack.LZ4;
using MessagePack.Resolvers;
using Microsoft.CodeAnalysis;
using Microsoft.NET.StringTools;
using Nerdbank.Streams;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("2.5.108.51978")]
[assembly: AssemblyInformationalVersion("2.5.108+cb0ad5dd95")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("neuecc,aarnott")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Yoshifumi Kawai and contributors. All rights reserved.")]
[assembly: AssemblyDescription("Extremely Fast MessagePack(MsgPack) Serializer for C# (.NET Framework, .NET 6, Unity, Xamarin).")]
[assembly: AssemblyProduct("MessagePack")]
[assembly: AssemblyTitle("MessagePack")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/neuecc/MessagePack-CSharp")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.5.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : 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;
		}
	}
}
[GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.5.119.9565")]
[ExcludeFromCodeCoverage]
internal static class ThisAssembly
{
	internal const string AssemblyConfiguration = "Release";

	internal const string AssemblyFileVersion = "2.5.108.51978";

	internal const string AssemblyInformationalVersion = "2.5.108+cb0ad5dd95";

	internal const string AssemblyName = "MessagePack";

	internal const string AssemblyTitle = "MessagePack";

	internal const string AssemblyVersion = "2.5.0.0";

	internal static readonly DateTime GitCommitDate = new DateTime(638145736080000000L, DateTimeKind.Utc);

	internal const string GitCommitId = "cb0ad5dd955cb9b14ca63019938a6aada43ce822";

	internal const bool IsPrerelease = false;

	internal const bool IsPublicRelease = true;

	internal const string PublicKey = "0024000004800000940000000602000000240000525341310004000001000100293894d4e8ad2b53afbea4e949ef54c2a388b08b5ebd143c811da82f22aa20c839ed1c0b4da83e7195e8c1dbe1bf3934e4e8fd7fb93f893439106fbf055a97c7fac0f7f8c39e58e78371dc0e3825e5b9d7e2afff0372f03c4d67ff7df0dbfb58dcadeb1044840de152bf8270de7fc54255ace8efd026c16311760d1a2570c3e8";

	internal const string PublicKeyToken = "b4a0369545f0a1be";

	internal const string RootNamespace = "MessagePack";
}
namespace Nerdbank.Streams
{
	[DebuggerDisplay("{DebuggerDisplay,nq}")]
	internal class Sequence<T> : IBufferWriter<T>, IDisposable
	{
		private class SequenceSegment : ReadOnlySequenceSegment<T>
		{
			internal static readonly SequenceSegment Empty = new SequenceSegment();

			private static readonly bool MayContainReferences = !typeof(T).GetTypeInfo().IsPrimitive;

			private T[]? array;

			internal int Start { get; private set; }

			internal int End { get; private set; }

			internal Memory<T> RemainingMemory => AvailableMemory.Slice(End);

			internal Span<T> RemainingSpan => AvailableMemory.Span.Slice(End);

			internal IMemoryOwner<T>? MemoryOwner { get; private set; }

			internal Memory<T> AvailableMemory
			{
				get
				{
					T[] array = this.array;
					if (array == null)
					{
						return MemoryOwner?.Memory ?? default(Memory<T>);
					}
					return array;
				}
			}

			internal int Length => checked(End - Start);

			internal int WritableBytes => checked(AvailableMemory.Length - End);

			internal new SequenceSegment? Next
			{
				get
				{
					return (SequenceSegment)base.Next;
				}
				set
				{
					base.Next = value;
				}
			}

			internal bool IsForeignMemory
			{
				get
				{
					if (array == null)
					{
						return MemoryOwner == null;
					}
					return false;
				}
			}

			internal void Assign(IMemoryOwner<T> memoryOwner)
			{
				MemoryOwner = memoryOwner;
				base.Memory = memoryOwner.Memory;
			}

			internal void Assign(T[] array)
			{
				this.array = array;
				base.Memory = array;
			}

			internal void AssignForeign(ReadOnlyMemory<T> memory)
			{
				base.Memory = memory;
				End = memory.Length;
			}

			internal void ResetMemory(ArrayPool<T>? arrayPool)
			{
				ClearReferences(Start, checked(End - Start));
				base.Memory = default(ReadOnlyMemory<T>);
				Next = null;
				base.RunningIndex = 0L;
				Start = 0;
				End = 0;
				if (array != null)
				{
					arrayPool.Return(array);
					array = null;
				}
				else
				{
					MemoryOwner?.Dispose();
					MemoryOwner = null;
				}
			}

			internal void SetNext(SequenceSegment segment)
			{
				Next = segment;
				checked
				{
					segment.RunningIndex = base.RunningIndex + Start + Length;
					if (!IsForeignMemory)
					{
						base.Memory = AvailableMemory.Slice(0, Start + Length);
					}
				}
			}

			internal void Advance(int count)
			{
				checked
				{
					Requires.Range(count >= 0 && End + count <= base.Memory.Length, "count");
					End += count;
				}
			}

			internal void AdvanceTo(int offset)
			{
				ClearReferences(Start, checked(offset - Start));
				Start = offset;
			}

			private void ClearReferences(int startIndex, int length)
			{
				if (MayContainReferences)
				{
					Span<T> span = AvailableMemory.Span;
					span = span.Slice(startIndex, length);
					span.Clear();
				}
			}
		}

		private const int MaximumAutoGrowSize = 32768;

		private static readonly int DefaultLengthFromArrayPool;

		private static readonly ReadOnlySequence<T> Empty;

		private readonly Stack<SequenceSegment> segmentPool = new Stack<SequenceSegment>();

		private readonly MemoryPool<T>? memoryPool;

		private readonly ArrayPool<T>? arrayPool;

		private SequenceSegment? first;

		private SequenceSegment? last;

		public int MinimumSpanLength { get; set; }

		public bool AutoIncreaseMinimumSpanLength { get; set; } = true;


		public ReadOnlySequence<T> AsReadOnlySequence => this;

		public long Length => AsReadOnlySequence.Length;

		private string DebuggerDisplay => $"Length: {AsReadOnlySequence.Length}";

		public Sequence()
			: this(ArrayPool<T>.Create())
		{
		}

		public Sequence(MemoryPool<T> memoryPool)
		{
			Requires.NotNull(memoryPool, "memoryPool");
			this.memoryPool = memoryPool;
		}

		public Sequence(ArrayPool<T> arrayPool)
		{
			Requires.NotNull(arrayPool, "arrayPool");
			this.arrayPool = arrayPool;
		}

		public static implicit operator ReadOnlySequence<T>(Sequence<T> sequence)
		{
			SequenceSegment sequenceSegment = sequence.first;
			if (sequenceSegment != null)
			{
				SequenceSegment sequenceSegment2 = sequence.last;
				if (sequenceSegment2 != null)
				{
					return new ReadOnlySequence<T>(sequenceSegment, sequenceSegment.Start, sequenceSegment2, sequenceSegment2.End);
				}
			}
			return Empty;
		}

		public void AdvanceTo(SequencePosition position)
		{
			SequenceSegment sequenceSegment = (SequenceSegment)position.GetObject();
			if (sequenceSegment != null && (sequenceSegment != SequenceSegment.Empty || Length != 0L))
			{
				int integer = position.GetInteger();
				SequenceSegment next = first;
				while (next != sequenceSegment && next != null)
				{
					next = next.Next;
				}
				Requires.Argument(next != null, "position", "Position does not represent a valid position in this sequence.");
				Requires.Argument(integer >= next.Start, "position", "Position must not be earlier than current position.");
				for (next = first; next != sequenceSegment; next = RecycleAndGetNext(next))
				{
				}
				sequenceSegment.AdvanceTo(integer);
				first = ((sequenceSegment.Length == 0) ? RecycleAndGetNext(sequenceSegment) : sequenceSegment);
				if (first == null)
				{
					last = null;
				}
			}
		}

		public void Advance(int count)
		{
			SequenceSegment? sequenceSegment = last;
			Verify.Operation(sequenceSegment != null, "Cannot advance before acquiring memory.");
			sequenceSegment.Advance(count);
			ConsiderMinimumSizeIncrease();
		}

		public Memory<T> GetMemory(int sizeHint)
		{
			return GetSegment(sizeHint).RemainingMemory;
		}

		public Span<T> GetSpan(int sizeHint)
		{
			return GetSegment(sizeHint).RemainingSpan;
		}

		public void Append(ReadOnlyMemory<T> memory)
		{
			if (memory.Length > 0)
			{
				SequenceSegment sequenceSegment = ((segmentPool.Count > 0) ? segmentPool.Pop() : new SequenceSegment());
				sequenceSegment.AssignForeign(memory);
				Append(sequenceSegment);
			}
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public void Dispose()
		{
			Reset();
		}

		public void Reset()
		{
			for (SequenceSegment sequenceSegment = first; sequenceSegment != null; sequenceSegment = RecycleAndGetNext(sequenceSegment))
			{
			}
			first = (last = null);
		}

		private SequenceSegment GetSegment(int sizeHint)
		{
			Requires.Range(sizeHint >= 0, "sizeHint");
			int? num = null;
			if (sizeHint == 0)
			{
				if (last == null || last.WritableBytes == 0)
				{
					num = -1;
				}
			}
			else if (last == null || last.WritableBytes < sizeHint)
			{
				num = Math.Max(MinimumSpanLength, sizeHint);
			}
			if (num.HasValue)
			{
				SequenceSegment sequenceSegment = ((segmentPool.Count > 0) ? segmentPool.Pop() : new SequenceSegment());
				if (arrayPool != null)
				{
					sequenceSegment.Assign(arrayPool.Rent((num.Value == -1) ? DefaultLengthFromArrayPool : num.Value));
				}
				else
				{
					sequenceSegment.Assign(memoryPool.Rent(num.Value));
				}
				Append(sequenceSegment);
			}
			return last;
		}

		private void Append(SequenceSegment segment)
		{
			if (last == null)
			{
				first = (last = segment);
				return;
			}
			if (last.Length > 0)
			{
				last.SetNext(segment);
			}
			else
			{
				SequenceSegment next = first;
				if (first != last)
				{
					while (next.Next != last)
					{
						next = next.Next;
					}
				}
				else
				{
					first = segment;
				}
				next.SetNext(segment);
				RecycleAndGetNext(last);
			}
			last = segment;
		}

		private SequenceSegment? RecycleAndGetNext(SequenceSegment segment)
		{
			SequenceSegment? next = segment.Next;
			segment.ResetMemory(arrayPool);
			segmentPool.Push(segment);
			return next;
		}

		private void ConsiderMinimumSizeIncrease()
		{
			checked
			{
				if (AutoIncreaseMinimumSpanLength && MinimumSpanLength < 32768)
				{
					int num = Math.Min(32768, (int)Math.Min(2147483647L, unchecked(Length / 2)));
					if (MinimumSpanLength < num)
					{
						MinimumSpanLength = num;
					}
				}
			}
		}

		static Sequence()
		{
			checked
			{
				DefaultLengthFromArrayPool = 1 + unchecked(4095 / Unsafe.SizeOf<T>());
				Empty = new ReadOnlySequence<T>(SequenceSegment.Empty, 0, SequenceSegment.Empty, 0);
			}
		}
	}
	internal static class Requires
	{
		[DebuggerStepThrough]
		public static void Range([DoesNotReturnIf(false)] bool condition, string parameterName, string? message = null)
		{
			if (!condition)
			{
				FailRange(parameterName, message);
			}
		}

		[DebuggerStepThrough]
		public static Exception FailRange(string parameterName, string? message = null)
		{
			if (string.IsNullOrEmpty(message))
			{
				throw new ArgumentOutOfRangeException(parameterName);
			}
			throw new ArgumentOutOfRangeException(parameterName, message);
		}

		[DebuggerStepThrough]
		public static T NotNull<T>([NotNull] T value, string parameterName) where T : class
		{
			if (value == null)
			{
				throw new ArgumentNullException(parameterName);
			}
			return value;
		}

		[DebuggerStepThrough]
		public static void Argument([DoesNotReturnIf(false)] bool condition, string parameterName, string message)
		{
			if (!condition)
			{
				throw new ArgumentException(message, parameterName);
			}
		}

		[DebuggerStepThrough]
		public static void Argument([DoesNotReturnIf(false)] bool condition, string parameterName, string message, object arg1)
		{
			if (!condition)
			{
				throw new ArgumentException(string.Format(message, arg1), parameterName);
			}
		}

		[DebuggerStepThrough]
		public static void Argument([DoesNotReturnIf(false)] bool condition, string parameterName, string message, object arg1, object arg2)
		{
			if (!condition)
			{
				throw new ArgumentException(string.Format(message, arg1, arg2), parameterName);
			}
		}

		[DebuggerStepThrough]
		public static void Argument([DoesNotReturnIf(false)] bool condition, string parameterName, string message, params object[] args)
		{
			if (!condition)
			{
				throw new ArgumentException(string.Format(message, args), parameterName);
			}
		}
	}
	internal static class Verify
	{
		[DebuggerStepThrough]
		internal static void Operation([DoesNotReturnIf(false)] bool condition, string message)
		{
			if (!condition)
			{
				throw new InvalidOperationException(message);
			}
		}
	}
}
namespace MessagePack
{
	public ref struct MessagePackReader
	{
		private SequenceReader<byte> reader;

		public CancellationToken CancellationToken { get; set; }

		public int Depth { get; set; }

		public ReadOnlySequence<byte> Sequence => reader.Sequence;

		public SequencePosition Position => reader.Position;

		public long Consumed => reader.Consumed;

		public bool End => reader.End;

		public bool IsNil => NextCode == 192;

		public MessagePackType NextMessagePackType => MessagePackCode.ToMessagePackType(NextCode);

		public byte NextCode
		{
			get
			{
				ThrowInsufficientBufferUnless(reader.TryPeek(out var value));
				return value;
			}
		}

		public byte ReadByte()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			checked
			{
				switch (value)
				{
				case 204:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value3));
					return value3;
				}
				case 208:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value2));
					return (byte)value2;
				}
				case 205:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ushort value4));
					return (byte)value4;
				}
				case 209:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out short value9));
					return (byte)value9;
				}
				case 206:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out uint value8));
					return (byte)value8;
				}
				case 210:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out int value7));
					return (byte)value7;
				}
				case 207:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ulong value6));
					return (byte)value6;
				}
				case 211:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out long value5));
					return (byte)value5;
				}
				case 224:
				case 225:
				case 226:
				case 227:
				case 228:
				case 229:
				case 230:
				case 231:
				case 232:
				case 233:
				case 234:
				case 235:
				case 236:
				case 237:
				case 238:
				case 239:
				case 240:
				case 241:
				case 242:
				case 243:
				case 244:
				case 245:
				case 246:
				case 247:
				case 248:
				case 249:
				case 250:
				case 251:
				case 252:
				case 253:
				case 254:
				case byte.MaxValue:
					return (byte)unchecked((sbyte)value);
				default:
					if (value >= 0 && value <= 127)
					{
						return value;
					}
					throw ThrowInvalidCode(value);
				}
			}
		}

		public ushort ReadUInt16()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			checked
			{
				switch (value)
				{
				case 204:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value3));
					return value3;
				}
				case 208:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value2));
					return (ushort)value2;
				}
				case 205:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ushort value4));
					return value4;
				}
				case 209:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out short value9));
					return (ushort)value9;
				}
				case 206:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out uint value8));
					return (ushort)value8;
				}
				case 210:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out int value7));
					return (ushort)value7;
				}
				case 207:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ulong value6));
					return (ushort)value6;
				}
				case 211:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out long value5));
					return (ushort)value5;
				}
				case 224:
				case 225:
				case 226:
				case 227:
				case 228:
				case 229:
				case 230:
				case 231:
				case 232:
				case 233:
				case 234:
				case 235:
				case 236:
				case 237:
				case 238:
				case 239:
				case 240:
				case 241:
				case 242:
				case 243:
				case 244:
				case 245:
				case 246:
				case 247:
				case 248:
				case 249:
				case 250:
				case 251:
				case 252:
				case 253:
				case 254:
				case byte.MaxValue:
					return (ushort)unchecked((sbyte)value);
				default:
					if (value >= 0 && value <= 127)
					{
						return value;
					}
					throw ThrowInvalidCode(value);
				}
			}
		}

		public uint ReadUInt32()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			checked
			{
				switch (value)
				{
				case 204:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value3));
					return value3;
				}
				case 208:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value2));
					return (uint)value2;
				}
				case 205:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ushort value4));
					return value4;
				}
				case 209:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out short value9));
					return (uint)value9;
				}
				case 206:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out uint value8));
					return value8;
				}
				case 210:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out int value7));
					return (uint)value7;
				}
				case 207:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ulong value6));
					return (uint)value6;
				}
				case 211:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out long value5));
					return (uint)value5;
				}
				case 224:
				case 225:
				case 226:
				case 227:
				case 228:
				case 229:
				case 230:
				case 231:
				case 232:
				case 233:
				case 234:
				case 235:
				case 236:
				case 237:
				case 238:
				case 239:
				case 240:
				case 241:
				case 242:
				case 243:
				case 244:
				case 245:
				case 246:
				case 247:
				case 248:
				case 249:
				case 250:
				case 251:
				case 252:
				case 253:
				case 254:
				case byte.MaxValue:
					return (uint)unchecked((sbyte)value);
				default:
					if (value >= 0 && value <= 127)
					{
						return value;
					}
					throw ThrowInvalidCode(value);
				}
			}
		}

		public ulong ReadUInt64()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			checked
			{
				switch (value)
				{
				case 204:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value3));
					return value3;
				}
				case 208:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value2));
					return (ulong)value2;
				}
				case 205:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ushort value4));
					return value4;
				}
				case 209:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out short value9));
					return (ulong)value9;
				}
				case 206:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out uint value8));
					return value8;
				}
				case 210:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out int value7));
					return (ulong)value7;
				}
				case 207:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ulong value6));
					return value6;
				}
				case 211:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out long value5));
					return (ulong)value5;
				}
				case 224:
				case 225:
				case 226:
				case 227:
				case 228:
				case 229:
				case 230:
				case 231:
				case 232:
				case 233:
				case 234:
				case 235:
				case 236:
				case 237:
				case 238:
				case 239:
				case 240:
				case 241:
				case 242:
				case 243:
				case 244:
				case 245:
				case 246:
				case 247:
				case 248:
				case 249:
				case 250:
				case 251:
				case 252:
				case 253:
				case 254:
				case byte.MaxValue:
					return (ulong)unchecked((sbyte)value);
				default:
					if (value >= 0 && value <= 127)
					{
						return value;
					}
					throw ThrowInvalidCode(value);
				}
			}
		}

		public sbyte ReadSByte()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			checked
			{
				switch (value)
				{
				case 204:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value3));
					return (sbyte)value3;
				}
				case 208:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value2));
					return value2;
				}
				case 205:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ushort value4));
					return (sbyte)value4;
				}
				case 209:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out short value9));
					return (sbyte)value9;
				}
				case 206:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out uint value8));
					return (sbyte)value8;
				}
				case 210:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out int value7));
					return (sbyte)value7;
				}
				case 207:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ulong value6));
					return (sbyte)value6;
				}
				case 211:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out long value5));
					return (sbyte)value5;
				}
				case 224:
				case 225:
				case 226:
				case 227:
				case 228:
				case 229:
				case 230:
				case 231:
				case 232:
				case 233:
				case 234:
				case 235:
				case 236:
				case 237:
				case 238:
				case 239:
				case 240:
				case 241:
				case 242:
				case 243:
				case 244:
				case 245:
				case 246:
				case 247:
				case 248:
				case 249:
				case 250:
				case 251:
				case 252:
				case 253:
				case 254:
				case byte.MaxValue:
					return unchecked((sbyte)value);
				default:
					if (value >= 0 && value <= 127)
					{
						return (sbyte)value;
					}
					throw ThrowInvalidCode(value);
				}
			}
		}

		public short ReadInt16()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			checked
			{
				switch (value)
				{
				case 204:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value3));
					return value3;
				}
				case 208:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value2));
					return value2;
				}
				case 205:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ushort value4));
					return (short)value4;
				}
				case 209:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out short value9));
					return value9;
				}
				case 206:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out uint value8));
					return (short)value8;
				}
				case 210:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out int value7));
					return (short)value7;
				}
				case 207:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ulong value6));
					return (short)value6;
				}
				case 211:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out long value5));
					return (short)value5;
				}
				case 224:
				case 225:
				case 226:
				case 227:
				case 228:
				case 229:
				case 230:
				case 231:
				case 232:
				case 233:
				case 234:
				case 235:
				case 236:
				case 237:
				case 238:
				case 239:
				case 240:
				case 241:
				case 242:
				case 243:
				case 244:
				case 245:
				case 246:
				case 247:
				case 248:
				case 249:
				case 250:
				case 251:
				case 252:
				case 253:
				case 254:
				case byte.MaxValue:
					return unchecked((sbyte)value);
				default:
					if (value >= 0 && value <= 127)
					{
						return value;
					}
					throw ThrowInvalidCode(value);
				}
			}
		}

		public int ReadInt32()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			checked
			{
				switch (value)
				{
				case 204:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value3));
					return value3;
				}
				case 208:
				{
					ThrowInsufficientBufferUnless(reader.TryRead(out var value2));
					return value2;
				}
				case 205:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ushort value4));
					return value4;
				}
				case 209:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out short value9));
					return value9;
				}
				case 206:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out uint value8));
					return (int)value8;
				}
				case 210:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out int value7));
					return value7;
				}
				case 207:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ulong value6));
					return (int)value6;
				}
				case 211:
				{
					ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out long value5));
					return (int)value5;
				}
				case 224:
				case 225:
				case 226:
				case 227:
				case 228:
				case 229:
				case 230:
				case 231:
				case 232:
				case 233:
				case 234:
				case 235:
				case 236:
				case 237:
				case 238:
				case 239:
				case 240:
				case 241:
				case 242:
				case 243:
				case 244:
				case 245:
				case 246:
				case 247:
				case 248:
				case 249:
				case 250:
				case 251:
				case 252:
				case 253:
				case 254:
				case byte.MaxValue:
					return unchecked((sbyte)value);
				default:
					if (value >= 0 && value <= 127)
					{
						return value;
					}
					throw ThrowInvalidCode(value);
				}
			}
		}

		public long ReadInt64()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			switch (value)
			{
			case 204:
			{
				ThrowInsufficientBufferUnless(reader.TryRead(out var value3));
				return value3;
			}
			case 208:
			{
				ThrowInsufficientBufferUnless(reader.TryRead(out var value2));
				return value2;
			}
			case 205:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ushort value4));
				return value4;
			}
			case 209:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out short value9));
				return value9;
			}
			case 206:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out uint value8));
				return value8;
			}
			case 210:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out int value7));
				return value7;
			}
			case 207:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ulong value6));
				return checked((long)value6);
			}
			case 211:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out long value5));
				return value5;
			}
			case 224:
			case 225:
			case 226:
			case 227:
			case 228:
			case 229:
			case 230:
			case 231:
			case 232:
			case 233:
			case 234:
			case 235:
			case 236:
			case 237:
			case 238:
			case 239:
			case 240:
			case 241:
			case 242:
			case 243:
			case 244:
			case 245:
			case 246:
			case 247:
			case 248:
			case 249:
			case 250:
			case 251:
			case 252:
			case 253:
			case 254:
			case byte.MaxValue:
				return (sbyte)value;
			default:
				if (value >= 0 && value <= 127)
				{
					return value;
				}
				throw ThrowInvalidCode(value);
			}
		}

		public MessagePackReader(ReadOnlyMemory<byte> memory)
		{
			this = default(MessagePackReader);
			reader = new SequenceReader<byte>(memory);
			Depth = 0;
		}

		public MessagePackReader(in ReadOnlySequence<byte> readOnlySequence)
		{
			this = default(MessagePackReader);
			reader = new SequenceReader<byte>(in readOnlySequence);
			Depth = 0;
		}

		public MessagePackReader Clone(in ReadOnlySequence<byte> readOnlySequence)
		{
			MessagePackReader result = new MessagePackReader(in readOnlySequence);
			result.CancellationToken = CancellationToken;
			result.Depth = Depth;
			return result;
		}

		public MessagePackReader CreatePeekReader()
		{
			return this;
		}

		public void Skip()
		{
			ThrowInsufficientBufferUnless(TrySkip());
		}

		internal bool TrySkip()
		{
			if (reader.Remaining == 0L)
			{
				return false;
			}
			byte nextCode = NextCode;
			int length;
			switch (nextCode)
			{
			case 192:
			case 194:
			case 195:
				return reader.TryAdvance(1L);
			case 204:
			case 208:
				return reader.TryAdvance(2L);
			case 205:
			case 209:
				return reader.TryAdvance(3L);
			case 202:
			case 206:
			case 210:
				return reader.TryAdvance(5L);
			case 203:
			case 207:
			case 211:
				return reader.TryAdvance(9L);
			case 222:
			case 223:
				return TrySkipNextMap();
			case 220:
			case 221:
				return TrySkipNextArray();
			case 217:
			case 218:
			case 219:
				if (TryGetStringLengthInBytes(out length))
				{
					return reader.TryAdvance(length);
				}
				return false;
			case 196:
			case 197:
			case 198:
				if (TryGetBytesLength(out length))
				{
					return reader.TryAdvance(length);
				}
				return false;
			case 199:
			case 200:
			case 201:
			case 212:
			case 213:
			case 214:
			case 215:
			case 216:
			{
				if (TryReadExtensionFormatHeader(out var extensionHeader))
				{
					return reader.TryAdvance(extensionHeader.Length);
				}
				return false;
			}
			default:
				if (nextCode < 0 || nextCode > 127)
				{
					break;
				}
				goto case 224;
			case 224:
			case 225:
			case 226:
			case 227:
			case 228:
			case 229:
			case 230:
			case 231:
			case 232:
			case 233:
			case 234:
			case 235:
			case 236:
			case 237:
			case 238:
			case 239:
			case 240:
			case 241:
			case 242:
			case 243:
			case 244:
			case 245:
			case 246:
			case 247:
			case 248:
			case 249:
			case 250:
			case 251:
			case 252:
			case 253:
			case 254:
			case byte.MaxValue:
				return reader.TryAdvance(1L);
			}
			if (nextCode >= 128 && nextCode <= 143)
			{
				return TrySkipNextMap();
			}
			if (nextCode >= 144 && nextCode <= 159)
			{
				return TrySkipNextArray();
			}
			if (nextCode >= 160 && nextCode <= 191)
			{
				if (TryGetStringLengthInBytes(out length))
				{
					return reader.TryAdvance(length);
				}
				return false;
			}
			throw ThrowInvalidCode(nextCode);
		}

		public Nil ReadNil()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			if (value != 192)
			{
				throw ThrowInvalidCode(value);
			}
			return Nil.Default;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool TryReadNil()
		{
			if (NextCode == 192)
			{
				reader.Advance(1L);
				return true;
			}
			return false;
		}

		public ReadOnlySequence<byte> ReadRaw(long length)
		{
			try
			{
				ReadOnlySequence<byte> result = reader.Sequence.Slice(reader.Position, length);
				reader.Advance(length);
				return result;
			}
			catch (ArgumentOutOfRangeException innerException)
			{
				throw ThrowNotEnoughBytesException(innerException);
			}
		}

		public ReadOnlySequence<byte> ReadRaw()
		{
			SequencePosition position = Position;
			Skip();
			return Sequence.Slice(position, Position);
		}

		public int ReadArrayHeader()
		{
			ThrowInsufficientBufferUnless(TryReadArrayHeader(out var count));
			ThrowInsufficientBufferUnless(reader.Remaining >= count);
			return count;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool TryReadArrayHeader(out int count)
		{
			count = -1;
			if (!reader.TryRead(out var value))
			{
				return false;
			}
			switch (value)
			{
			case 220:
			{
				if (!reader.TryReadBigEndian(out short value3))
				{
					return false;
				}
				count = (ushort)value3;
				break;
			}
			case 221:
			{
				if (!reader.TryReadBigEndian(out int value2))
				{
					return false;
				}
				count = value2;
				break;
			}
			case 144:
			case 145:
			case 146:
			case 147:
			case 148:
			case 149:
			case 150:
			case 151:
			case 152:
			case 153:
			case 154:
			case 155:
			case 156:
			case 157:
			case 158:
			case 159:
				count = value & 0xF;
				break;
			default:
				throw ThrowInvalidCode(value);
			}
			return true;
		}

		public int ReadMapHeader()
		{
			ThrowInsufficientBufferUnless(TryReadMapHeader(out var count));
			ThrowInsufficientBufferUnless(reader.Remaining >= checked(count * 2));
			return count;
		}

		public bool TryReadMapHeader(out int count)
		{
			count = -1;
			if (!reader.TryRead(out var value))
			{
				return false;
			}
			switch (value)
			{
			case 222:
			{
				if (!reader.TryReadBigEndian(out short value3))
				{
					return false;
				}
				count = (ushort)value3;
				break;
			}
			case 223:
			{
				if (!reader.TryReadBigEndian(out int value2))
				{
					return false;
				}
				count = value2;
				break;
			}
			case 128:
			case 129:
			case 130:
			case 131:
			case 132:
			case 133:
			case 134:
			case 135:
			case 136:
			case 137:
			case 138:
			case 139:
			case 140:
			case 141:
			case 142:
			case 143:
				count = checked((byte)(value & 0xF));
				break;
			default:
				throw ThrowInvalidCode(value);
			}
			return true;
		}

		public bool ReadBoolean()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			return value switch
			{
				195 => true, 
				194 => false, 
				_ => throw ThrowInvalidCode(value), 
			};
		}

		public char ReadChar()
		{
			return (char)ReadUInt16();
		}

		public float ReadSingle()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			switch (value)
			{
			case 202:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out float value3));
				return value3;
			}
			case 203:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out double value2));
				return (float)value2;
			}
			case 208:
			{
				ThrowInsufficientBufferUnless(reader.TryRead(out var value4));
				return value4;
			}
			case 209:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out short value11));
				return value11;
			}
			case 210:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out int value10));
				return value10;
			}
			case 211:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out long value9));
				return value9;
			}
			case 204:
			{
				ThrowInsufficientBufferUnless(reader.TryRead(out var value8));
				return (int)value8;
			}
			case 205:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ushort value7));
				return (int)value7;
			}
			case 206:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out uint value6));
				return value6;
			}
			case 207:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out ulong value5));
				return value5;
			}
			case 224:
			case 225:
			case 226:
			case 227:
			case 228:
			case 229:
			case 230:
			case 231:
			case 232:
			case 233:
			case 234:
			case 235:
			case 236:
			case 237:
			case 238:
			case 239:
			case 240:
			case 241:
			case 242:
			case 243:
			case 244:
			case 245:
			case 246:
			case 247:
			case 248:
			case 249:
			case 250:
			case 251:
			case 252:
			case 253:
			case 254:
			case byte.MaxValue:
				return (sbyte)value;
			default:
				if (value >= 0 && value <= 127)
				{
					return (int)value;
				}
				throw ThrowInvalidCode(value);
			}
		}

		public double ReadDouble()
		{
			ThrowInsufficientBufferUnless(reader.TryRead(out var value));
			byte value4;
			short value7;
			int value6;
			long value5;
			switch (value)
			{
			case 203:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out double value3));
				return value3;
			}
			case 202:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out float value2));
				return value2;
			}
			case 208:
				ThrowInsufficientBufferUnless(reader.TryRead(out value4));
				return (sbyte)value4;
			case 209:
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value7));
				return value7;
			case 210:
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value6));
				return value6;
			case 211:
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value5));
				return value5;
			case 204:
				ThrowInsufficientBufferUnless(reader.TryRead(out value4));
				return (int)value4;
			case 205:
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value7));
				return (int)(ushort)value7;
			case 206:
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value6));
				return (uint)value6;
			case 207:
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value5));
				return (ulong)value5;
			case 224:
			case 225:
			case 226:
			case 227:
			case 228:
			case 229:
			case 230:
			case 231:
			case 232:
			case 233:
			case 234:
			case 235:
			case 236:
			case 237:
			case 238:
			case 239:
			case 240:
			case 241:
			case 242:
			case 243:
			case 244:
			case 245:
			case 246:
			case 247:
			case 248:
			case 249:
			case 250:
			case 251:
			case 252:
			case 253:
			case 254:
			case byte.MaxValue:
				return (sbyte)value;
			default:
				if (value >= 0 && value <= 127)
				{
					return (int)value;
				}
				throw ThrowInvalidCode(value);
			}
		}

		public DateTime ReadDateTime()
		{
			return ReadDateTime(ReadExtensionFormatHeader());
		}

		public DateTime ReadDateTime(ExtensionHeader header)
		{
			if (header.TypeCode != -1)
			{
				throw new MessagePackSerializationException($"Extension TypeCode is invalid. typeCode: {header.TypeCode}");
			}
			int value;
			long value2;
			switch (header.Length)
			{
			case 4u:
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value));
				return DateTimeConstants.UnixEpoch.AddSeconds((uint)value);
			case 8u:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value2));
				long num2 = value2;
				long num;
				checked
				{
					num = (long)(unchecked((ulong)num2) >> 34);
				}
				ulong num3 = (ulong)num2 & 0x3FFFFFFFFuL;
				return DateTimeConstants.UnixEpoch.AddSeconds(num3).AddTicks(num / 100);
			}
			case 12u:
			{
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value));
				long num = (uint)value;
				ThrowInsufficientBufferUnless(reader.TryReadBigEndian(out value2));
				return DateTimeConstants.UnixEpoch.AddSeconds(value2).AddTicks(num / 100);
			}
			default:
				throw new MessagePackSerializationException($"Length of extension was {header.Length}. Either 4 or 8 were expected.");
			}
		}

		public ReadOnlySequence<byte>? ReadBytes()
		{
			if (TryReadNil())
			{
				return null;
			}
			int bytesLength = GetBytesLength();
			ThrowInsufficientBufferUnless(reader.Remaining >= bytesLength);
			ReadOnlySequence<byte> value = reader.Sequence.Slice(reader.Position, bytesLength);
			reader.Advance(bytesLength);
			return value;
		}

		public ReadOnlySequence<byte>? ReadStringSequence()
		{
			if (TryReadNil())
			{
				return null;
			}
			int stringLengthInBytes = GetStringLengthInBytes();
			ThrowInsufficientBufferUnless(reader.Remaining >= stringLengthInBytes);
			ReadOnlySequence<byte> value = reader.Sequence.Slice(reader.Position, stringLengthInBytes);
			reader.Advance(stringLengthInBytes);
			return value;
		}

		public bool TryReadStringSpan(out ReadOnlySpan<byte> span)
		{
			if (IsNil)
			{
				span = default(ReadOnlySpan<byte>);
				return false;
			}
			long consumed = reader.Consumed;
			int stringLengthInBytes = GetStringLengthInBytes();
			ThrowInsufficientBufferUnless(reader.Remaining >= stringLengthInBytes);
			checked
			{
				int num = reader.CurrentSpanIndex + stringLengthInBytes;
				ReadOnlySpan<byte> currentSpan = reader.CurrentSpan;
				if (num <= currentSpan.Length)
				{
					currentSpan = reader.CurrentSpan;
					span = currentSpan.Slice(reader.CurrentSpanIndex, stringLengthInBytes);
					reader.Advance(stringLengthInBytes);
					return true;
				}
				reader.Rewind(reader.Consumed - consumed);
				span = default(ReadOnlySpan<byte>);
				return false;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public string? ReadString()
		{
			if (TryReadNil())
			{
				return null;
			}
			int stringLengthInBytes = GetStringLengthInBytes();
			ReadOnlySpan<byte> unreadSpan = reader.UnreadSpan;
			if (unreadSpan.Length >= stringLengthInBytes)
			{
				string @string = StringEncoding.UTF8.GetString(unreadSpan.Slice(0, stringLengthInBytes));
				reader.Advance(stringLengthInBytes);
				return @string;
			}
			return ReadStringSlow(stringLengthInBytes);
		}

		public ExtensionHeader ReadExtensionFormatHeader()
		{
			ThrowInsufficientBufferUnless(TryReadExtensionFormatHeader(out var extensionHeader));
			ThrowInsufficientBufferUnless(reader.Remaining >= extensionHeader.Length);
			return extensionHeader;
		}

		public bool TryReadExtensionFormatHeader(out ExtensionHeader extensionHeader)
		{
			extensionHeader = default(ExtensionHeader);
			if (!reader.TryRead(out var value))
			{
				return false;
			}
			uint length;
			switch (value)
			{
			case 212:
				length = 1u;
				break;
			case 213:
				length = 2u;
				break;
			case 214:
				length = 4u;
				break;
			case 215:
				length = 8u;
				break;
			case 216:
				length = 16u;
				break;
			case 199:
			{
				if (!reader.TryRead(out var value4))
				{
					return false;
				}
				length = value4;
				break;
			}
			case 200:
			{
				if (!reader.TryReadBigEndian(out short value3))
				{
					return false;
				}
				length = (ushort)value3;
				break;
			}
			case 201:
			{
				if (!reader.TryReadBigEndian(out int value2))
				{
					return false;
				}
				length = (uint)value2;
				break;
			}
			default:
				throw ThrowInvalidCode(value);
			}
			if (!reader.TryRead(out var value5))
			{
				return false;
			}
			extensionHeader = new ExtensionHeader((sbyte)value5, length);
			return true;
		}

		public ExtensionResult ReadExtensionFormat()
		{
			ExtensionHeader extensionHeader = ReadExtensionFormatHeader();
			try
			{
				ReadOnlySequence<byte> data = reader.Sequence.Slice(reader.Position, extensionHeader.Length);
				reader.Advance(extensionHeader.Length);
				return new ExtensionResult(extensionHeader.TypeCode, data);
			}
			catch (ArgumentOutOfRangeException innerException)
			{
				throw ThrowNotEnoughBytesException(innerException);
			}
		}

		private static EndOfStreamException ThrowNotEnoughBytesException()
		{
			throw new EndOfStreamException();
		}

		private static EndOfStreamException ThrowNotEnoughBytesException(Exception innerException)
		{
			throw new EndOfStreamException(new EndOfStreamException().Message, innerException);
		}

		[DoesNotReturn]
		private static Exception ThrowInvalidCode(byte code)
		{
			throw new MessagePackSerializationException($"Unexpected msgpack code {code} ({MessagePackCode.ToFormatName(code)}) encountered.");
		}

		private static void ThrowInsufficientBufferUnless(bool condition)
		{
			if (!condition)
			{
				ThrowNotEnoughBytesException();
			}
		}

		private int GetBytesLength()
		{
			ThrowInsufficientBufferUnless(TryGetBytesLength(out var length));
			return length;
		}

		private bool TryGetBytesLength(out int length)
		{
			if (!reader.TryRead(out var value))
			{
				length = 0;
				return false;
			}
			switch (value)
			{
			case 196:
			{
				if (reader.TryRead(out var value2))
				{
					length = value2;
					return true;
				}
				break;
			}
			case 197:
			case 218:
			{
				if (reader.TryReadBigEndian(out short value3))
				{
					length = (ushort)value3;
					return true;
				}
				break;
			}
			case 198:
			case 219:
				if (reader.TryReadBigEndian(out length))
				{
					return true;
				}
				break;
			case 160:
			case 161:
			case 162:
			case 163:
			case 164:
			case 165:
			case 166:
			case 167:
			case 168:
			case 169:
			case 170:
			case 171:
			case 172:
			case 173:
			case 174:
			case 175:
			case 176:
			case 177:
			case 178:
			case 179:
			case 180:
			case 181:
			case 182:
			case 183:
			case 184:
			case 185:
			case 186:
			case 187:
			case 188:
			case 189:
			case 190:
			case 191:
				length = value & 0x1F;
				return true;
			default:
				throw ThrowInvalidCode(value);
			}
			length = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private bool TryGetStringLengthInBytes(out int length)
		{
			if (!reader.TryRead(out var value))
			{
				length = 0;
				return false;
			}
			if (value >= 160 && value <= 191)
			{
				length = value & 0x1F;
				return true;
			}
			return TryGetStringLengthInBytesSlow(value, out length);
		}

		private int GetStringLengthInBytes()
		{
			ThrowInsufficientBufferUnless(TryGetStringLengthInBytes(out var length));
			return length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private bool TryGetStringLengthInBytesSlow(byte code, out int length)
		{
			switch (code)
			{
			case 217:
			{
				if (reader.TryRead(out var value2))
				{
					length = value2;
					return true;
				}
				break;
			}
			case 218:
			{
				if (reader.TryReadBigEndian(out short value3))
				{
					length = (ushort)value3;
					return true;
				}
				break;
			}
			case 219:
			{
				if (reader.TryReadBigEndian(out int value))
				{
					length = value;
					return true;
				}
				break;
			}
			case 160:
			case 161:
			case 162:
			case 163:
			case 164:
			case 165:
			case 166:
			case 167:
			case 168:
			case 169:
			case 170:
			case 171:
			case 172:
			case 173:
			case 174:
			case 175:
			case 176:
			case 177:
			case 178:
			case 179:
			case 180:
			case 181:
			case 182:
			case 183:
			case 184:
			case 185:
			case 186:
			case 187:
			case 188:
			case 189:
			case 190:
			case 191:
				length = code & 0x1F;
				return true;
			default:
				throw ThrowInvalidCode(code);
			}
			length = 0;
			return false;
		}

		private string ReadStringSlow(int byteLength)
		{
			ThrowInsufficientBufferUnless(reader.Remaining >= byteLength);
			int maxCharCount = StringEncoding.UTF8.GetMaxCharCount(byteLength);
			char[] array = ArrayPool<char>.Shared.Rent(maxCharCount);
			Decoder decoder = StringEncoding.UTF8.GetDecoder();
			int num = byteLength;
			int num2 = 0;
			checked
			{
				while (num > 0)
				{
					int num3 = Math.Min(num, reader.UnreadSpan.Length);
					num -= num3;
					bool flush = num == 0;
					num2 += decoder.GetChars(reader.UnreadSpan.Slice(0, num3), array.AsSpan(num2), flush);
					reader.Advance(num3);
				}
				string result = new string(array, 0, num2);
				ArrayPool<char>.Shared.Return(array);
				return result;
			}
		}

		private bool TrySkipNextArray()
		{
			if (TryReadArrayHeader(out var count))
			{
				return TrySkip(count);
			}
			return false;
		}

		private bool TrySkipNextMap()
		{
			if (TryReadMapHeader(out var count))
			{
				return TrySkip(checked(count * 2));
			}
			return false;
		}

		private bool TrySkip(int count)
		{
			for (int i = 0; i < count; i = checked(i + 1))
			{
				if (!TrySkip())
				{
					return false;
				}
			}
			return true;
		}
	}
	public static class MessagePackSerializer
	{
		public static class Typeless
		{
			public static MessagePackSerializerOptions DefaultOptions { get; set; } = TypelessContractlessStandardResolver.Options;


			public static void Serialize(ref MessagePackWriter writer, object? obj, MessagePackSerializerOptions? options = null)
			{
				MessagePackSerializer.Serialize(ref writer, obj, options ?? DefaultOptions);
			}

			public static void Serialize(IBufferWriter<byte> writer, object? obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
			{
				MessagePackSerializer.Serialize(writer, obj, options ?? DefaultOptions, cancellationToken);
			}

			public static byte[] Serialize(object? obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
			{
				return MessagePackSerializer.Serialize(obj, options ?? DefaultOptions, cancellationToken);
			}

			public static void Serialize(Stream stream, object? obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
			{
				MessagePackSerializer.Serialize(stream, obj, options ?? DefaultOptions, cancellationToken);
			}

			public static Task SerializeAsync(Stream stream, object? obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
			{
				return MessagePackSerializer.SerializeAsync(stream, obj, options ?? DefaultOptions, cancellationToken);
			}

			public static object? Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions? options = null)
			{
				return Deserialize<object>(ref reader, options ?? DefaultOptions);
			}

			public static object? Deserialize(in ReadOnlySequence<byte> byteSequence, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
			{
				return Deserialize<object>(in byteSequence, options ?? DefaultOptions, cancellationToken);
			}

			public static object? Deserialize(Stream stream, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
			{
				return Deserialize<object>(stream, options ?? DefaultOptions, cancellationToken);
			}

			public static object? Deserialize(Memory<byte> bytes, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
			{
				return Deserialize<object>(bytes, options ?? DefaultOptions, cancellationToken);
			}

			public static ValueTask<object?> DeserializeAsync(Stream stream, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
			{
				return DeserializeAsync<object>(stream, options ?? DefaultOptions, cancellationToken);
			}
		}

		private delegate int LZ4Transform(ReadOnlySpan<byte> input, Span<byte> output);

		private static class PrimitiveChecker<T>
		{
			public static readonly bool IsMessagePackFixedSizePrimitive;

			static PrimitiveChecker()
			{
				IsMessagePackFixedSizePrimitive = IsMessagePackFixedSizePrimitiveTypeHelper(typeof(T));
			}
		}

		private class CompiledMethods
		{
			internal delegate void MessagePackWriterSerialize(ref MessagePackWriter writer, object? value, MessagePackSerializerOptions? options);

			internal delegate object? MessagePackReaderDeserialize(ref MessagePackReader reader, MessagePackSerializerOptions? options);

			private const bool PreferInterpretation = false;

			internal readonly Func<object?, MessagePackSerializerOptions?, CancellationToken, byte[]> Serialize_T_Options;

			internal readonly Action<Stream, object?, MessagePackSerializerOptions?, CancellationToken> Serialize_Stream_T_Options_CancellationToken;

			internal readonly Func<Stream, object?, MessagePackSerializerOptions?, CancellationToken, Task> SerializeAsync_Stream_T_Options_CancellationToken;

			internal readonly MessagePackWriterSerialize Serialize_MessagePackWriter_T_Options;

			internal readonly Action<IBufferWriter<byte>, object?, MessagePackSerializerOptions?, CancellationToken> Serialize_IBufferWriter_T_Options_CancellationToken;

			internal readonly MessagePackReaderDeserialize Deserialize_MessagePackReader_Options;

			internal readonly Func<Stream, MessagePackSerializerOptions?, CancellationToken, object?> Deserialize_Stream_Options_CancellationToken;

			internal readonly Func<Stream, MessagePackSerializerOptions?, CancellationToken, ValueTask<object?>> DeserializeAsync_Stream_Options_CancellationToken;

			internal readonly Func<ReadOnlyMemory<byte>, MessagePackSerializerOptions?, CancellationToken, object?> Deserialize_ReadOnlyMemory_Options;

			internal readonly Func<ReadOnlySequence<byte>, MessagePackSerializerOptions?, CancellationToken, object?> Deserialize_ReadOnlySequence_Options_CancellationToken;

			internal CompiledMethods(Type type)
			{
				TypeInfo typeInfo = type.GetTypeInfo();
				MethodInfo method = GetMethod("Serialize", type, new Type[3]
				{
					null,
					typeof(MessagePackSerializerOptions),
					typeof(CancellationToken)
				});
				ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "obj");
				ParameterExpression parameterExpression2 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options");
				ParameterExpression parameterExpression3 = Expression.Parameter(typeof(CancellationToken), "cancellationToken");
				Serialize_T_Options = Expression.Lambda<Func<object, MessagePackSerializerOptions, CancellationToken, byte[]>>(Expression.Call(null, method, typeInfo.IsValueType ? Expression.Unbox(parameterExpression, type) : Expression.Convert(parameterExpression, type), parameterExpression2, parameterExpression3), new ParameterExpression[3] { parameterExpression, parameterExpression2, parameterExpression3 }).Compile(preferInterpretation: false);
				MethodInfo method2 = GetMethod("Serialize", type, new Type[4]
				{
					typeof(Stream),
					null,
					typeof(MessagePackSerializerOptions),
					typeof(CancellationToken)
				});
				ParameterExpression parameterExpression4 = Expression.Parameter(typeof(Stream), "stream");
				ParameterExpression parameterExpression5 = Expression.Parameter(typeof(object), "obj");
				ParameterExpression parameterExpression6 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options");
				ParameterExpression parameterExpression7 = Expression.Parameter(typeof(CancellationToken), "cancellationToken");
				Action<Stream, object, MessagePackSerializerOptions, CancellationToken> serialize_Stream_T_Options_CancellationToken = Expression.Lambda<Action<Stream, object, MessagePackSerializerOptions, CancellationToken>>(Expression.Call(null, method2, parameterExpression4, typeInfo.IsValueType ? Expression.Unbox(parameterExpression5, type) : Expression.Convert(parameterExpression5, type), parameterExpression6, parameterExpression7), new ParameterExpression[4] { parameterExpression4, parameterExpression5, parameterExpression6, parameterExpression7 }).Compile(preferInterpretation: false);
				Serialize_Stream_T_Options_CancellationToken = serialize_Stream_T_Options_CancellationToken;
				MethodInfo method3 = GetMethod("SerializeAsync", type, new Type[4]
				{
					typeof(Stream),
					null,
					typeof(MessagePackSerializerOptions),
					typeof(CancellationToken)
				});
				ParameterExpression parameterExpression8 = Expression.Parameter(typeof(Stream), "stream");
				ParameterExpression parameterExpression9 = Expression.Parameter(typeof(object), "obj");
				ParameterExpression parameterExpression10 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options");
				ParameterExpression parameterExpression11 = Expression.Parameter(typeof(CancellationToken), "cancellationToken");
				Func<Stream, object, MessagePackSerializerOptions, CancellationToken, Task> serializeAsync_Stream_T_Options_CancellationToken = Expression.Lambda<Func<Stream, object, MessagePackSerializerOptions, CancellationToken, Task>>(Expression.Call(null, method3, parameterExpression8, typeInfo.IsValueType ? Expression.Unbox(parameterExpression9, type) : Expression.Convert(parameterExpression9, type), parameterExpression10, parameterExpression11), new ParameterExpression[4] { parameterExpression8, parameterExpression9, parameterExpression10, parameterExpression11 }).Compile(preferInterpretation: false);
				SerializeAsync_Stream_T_Options_CancellationToken = serializeAsync_Stream_T_Options_CancellationToken;
				MethodInfo method4 = GetMethod("Serialize", type, new Type[4]
				{
					typeof(IBufferWriter<byte>),
					null,
					typeof(MessagePackSerializerOptions),
					typeof(CancellationToken)
				});
				ParameterExpression parameterExpression12 = Expression.Parameter(typeof(IBufferWriter<byte>), "writer");
				ParameterExpression parameterExpression13 = Expression.Parameter(typeof(object), "obj");
				ParameterExpression parameterExpression14 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options");
				ParameterExpression parameterExpression15 = Expression.Parameter(typeof(CancellationToken), "cancellationToken");
				Action<IBufferWriter<byte>, object, MessagePackSerializerOptions, CancellationToken> serialize_IBufferWriter_T_Options_CancellationToken = Expression.Lambda<Action<IBufferWriter<byte>, object, MessagePackSerializerOptions, CancellationToken>>(Expression.Call(null, method4, parameterExpression12, typeInfo.IsValueType ? Expression.Unbox(parameterExpression13, type) : Expression.Convert(parameterExpression13, type), parameterExpression14, parameterExpression15), new ParameterExpression[4] { parameterExpression12, parameterExpression13, parameterExpression14, parameterExpression15 }).Compile(preferInterpretation: false);
				Serialize_IBufferWriter_T_Options_CancellationToken = serialize_IBufferWriter_T_Options_CancellationToken;
				MethodInfo method5 = GetMethod("SerializeSemiGeneric", type, new Type[3]
				{
					typeof(MessagePackWriter).MakeByRefType(),
					typeof(object),
					typeof(MessagePackSerializerOptions)
				});
				Serialize_MessagePackWriter_T_Options = (MessagePackWriterSerialize)method5.CreateDelegate(typeof(MessagePackWriterSerialize));
				MethodInfo method6 = GetMethod("DeserializeSemiGeneric", type, new Type[2]
				{
					typeof(MessagePackReader).MakeByRefType(),
					typeof(MessagePackSerializerOptions)
				});
				Deserialize_MessagePackReader_Options = (MessagePackReaderDeserialize)method6.CreateDelegate(typeof(MessagePackReaderDeserialize));
				MethodInfo method7 = GetMethod("Deserialize", type, new Type[3]
				{
					typeof(Stream),
					typeof(MessagePackSerializerOptions),
					typeof(CancellationToken)
				});
				ParameterExpression parameterExpression16 = Expression.Parameter(typeof(Stream), "stream");
				ParameterExpression parameterExpression17 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options");
				ParameterExpression parameterExpression18 = Expression.Parameter(typeof(CancellationToken), "cancellationToken");
				Func<Stream, MessagePackSerializerOptions, CancellationToken, object> deserialize_Stream_Options_CancellationToken = Expression.Lambda<Func<Stream, MessagePackSerializerOptions, CancellationToken, object>>(Expression.Convert(Expression.Call(null, method7, parameterExpression16, parameterExpression17, parameterExpression18), typeof(object)), new ParameterExpression[3] { parameterExpression16, parameterExpression17, parameterExpression18 }).Compile(preferInterpretation: false);
				Deserialize_Stream_Options_CancellationToken = deserialize_Stream_Options_CancellationToken;
				MethodInfo method8 = GetMethod("DeserializeObjectAsync", type, new Type[3]
				{
					typeof(Stream),
					typeof(MessagePackSerializerOptions),
					typeof(CancellationToken)
				});
				ParameterExpression parameterExpression19 = Expression.Parameter(typeof(Stream), "stream");
				ParameterExpression parameterExpression20 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options");
				ParameterExpression parameterExpression21 = Expression.Parameter(typeof(CancellationToken), "cancellationToken");
				Func<Stream, MessagePackSerializerOptions, CancellationToken, ValueTask<object>> deserializeAsync_Stream_Options_CancellationToken = Expression.Lambda<Func<Stream, MessagePackSerializerOptions, CancellationToken, ValueTask<object>>>(Expression.Convert(Expression.Call(null, method8, parameterExpression19, parameterExpression20, parameterExpression21), typeof(ValueTask<object>)), new ParameterExpression[3] { parameterExpression19, parameterExpression20, parameterExpression21 }).Compile(preferInterpretation: false);
				DeserializeAsync_Stream_Options_CancellationToken = deserializeAsync_Stream_Options_CancellationToken;
				MethodInfo method9 = GetMethod("Deserialize", type, new Type[3]
				{
					typeof(ReadOnlyMemory<byte>),
					typeof(MessagePackSerializerOptions),
					typeof(CancellationToken)
				});
				ParameterExpression parameterExpression22 = Expression.Parameter(typeof(ReadOnlyMemory<byte>), "bytes");
				ParameterExpression parameterExpression23 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options");
				ParameterExpression parameterExpression24 = Expression.Parameter(typeof(CancellationToken), "cancellationToken");
				Func<ReadOnlyMemory<byte>, MessagePackSerializerOptions, CancellationToken, object> deserialize_ReadOnlyMemory_Options = Expression.Lambda<Func<ReadOnlyMemory<byte>, MessagePackSerializerOptions, CancellationToken, object>>(Expression.Convert(Expression.Call(null, method9, parameterExpression22, parameterExpression23, parameterExpression24), typeof(object)), new ParameterExpression[3] { parameterExpression22, parameterExpression23, parameterExpression24 }).Compile(preferInterpretation: false);
				Deserialize_ReadOnlyMemory_Options = deserialize_ReadOnlyMemory_Options;
				MethodInfo method10 = GetMethod("Deserialize", type, new Type[3]
				{
					typeof(ReadOnlySequence<byte>).MakeByRefType(),
					typeof(MessagePackSerializerOptions),
					typeof(CancellationToken)
				});
				ParameterExpression parameterExpression25 = Expression.Parameter(typeof(ReadOnlySequence<byte>), "bytes");
				ParameterExpression parameterExpression26 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options");
				ParameterExpression parameterExpression27 = Expression.Parameter(typeof(CancellationToken), "cancellationToken");
				Func<ReadOnlySequence<byte>, MessagePackSerializerOptions, CancellationToken, object> deserialize_ReadOnlySequence_Options_CancellationToken = Expression.Lambda<Func<ReadOnlySequence<byte>, MessagePackSerializerOptions, CancellationToken, object>>(Expression.Convert(Expression.Call(null, method10, parameterExpression25, parameterExpression26, parameterExpression27), typeof(object)), new ParameterExpression[3] { parameterExpression25, parameterExpression26, parameterExpression27 }).Compile(preferInterpretation: false);
				Deserialize_ReadOnlySequence_Options_CancellationToken = deserialize_ReadOnlySequence_Options_CancellationToken;
			}

			private static void ThrowRefStructNotSupported()
			{
				throw new NotSupportedException("MessagePackWriter/Reader overload is not supported in MessagePackSerializer.NonGenerics.");
			}

			private static MethodInfo GetMethod(string methodName, Type type, Type?[] parameters)
			{
				string methodName2 = methodName;
				Type?[] parameters2 = parameters;
				return typeof(MessagePackSerializer).GetRuntimeMethods().Single(delegate(MethodInfo x)
				{
					if (methodName2 != x.Name)
					{
						return false;
					}
					ParameterInfo[] parameters3 = x.GetParameters();
					if (parameters3.Length != parameters2.Length)
					{
						return false;
					}
					for (int i = 0; i < parameters3.Length; i = checked(i + 1))
					{
						if ((!(parameters2[i] == null) || !parameters3[i].ParameterType.IsGenericParameter) && parameters3[i].ParameterType != parameters2[i])
						{
							return false;
						}
					}
					return true;
				}).MakeGenericMethod(type);
			}
		}

		private static MessagePackSerializerOptions? defaultOptions;

		[ThreadStatic]
		private static byte[]? scratchArray;

		private static readonly LZ4Transform LZ4CodecEncode;

		private static readonly LZ4Transform LZ4CodecDecode;

		private static readonly Func<Type, CompiledMethods> CreateCompiledMethods;

		private static readonly ThreadsafeTypeKeyHashTable<CompiledMethods> Serializes;

		public static MessagePackSerializerOptions DefaultOptions
		{
			get
			{
				return defaultOptions ?? (defaultOptions = MessagePackSerializerOptions.Standard);
			}
			set
			{
				defaultOptions = value;
			}
		}

		public static void Serialize<T>(IBufferWriter<byte> writer, T value, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			MessagePackWriter messagePackWriter = new MessagePackWriter(writer);
			messagePackWriter.CancellationToken = cancellationToken;
			MessagePackWriter writer2 = messagePackWriter;
			Serialize(ref writer2, value, options);
			writer2.Flush();
		}

		public static void Serialize<T>(ref MessagePackWriter writer, T value, MessagePackSerializerOptions? options = null)
		{
			options = options ?? DefaultOptions;
			bool oldSpec = writer.OldSpec;
			if (options.OldSpec.HasValue)
			{
				writer.OldSpec = options.OldSpec.Value;
			}
			try
			{
				if (options.Compression.IsCompression() && !PrimitiveChecker<T>.IsMessagePackFixedSizePrimitive)
				{
					using (SequencePool.Rental rental = options.SequencePool.Rent())
					{
						Sequence<byte> value2 = rental.Value;
						MessagePackWriter writer2 = writer.Clone(value2);
						options.Resolver.GetFormatterWithVerify<T>().Serialize(ref writer2, value, options);
						writer2.Flush();
						ReadOnlySequence<byte> msgpackUncompressedData = value2;
						ToLZ4BinaryCore(in msgpackUncompressedData, ref writer, options.Compression, options.CompressionMinLength);
						return;
					}
				}
				options.Resolver.GetFormatterWithVerify<T>().Serialize(ref writer, value, options);
			}
			catch (Exception inner)
			{
				throw new MessagePackSerializationException("Failed to serialize " + typeof(T).FullName + " value.", inner);
			}
			finally
			{
				writer.OldSpec = oldSpec;
			}
		}

		public static byte[] Serialize<T>(T value, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			byte[] array = scratchArray;
			if (array == null)
			{
				array = (scratchArray = new byte[65536]);
			}
			options = options ?? DefaultOptions;
			MessagePackWriter messagePackWriter = new MessagePackWriter(options.SequencePool, array);
			messagePackWriter.CancellationToken = cancellationToken;
			MessagePackWriter writer = messagePackWriter;
			Serialize(ref writer, value, options);
			return writer.FlushAndGetArray();
		}

		public static void Serialize<T>(Stream stream, T value, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			options = options ?? DefaultOptions;
			cancellationToken.ThrowIfCancellationRequested();
			using SequencePool.Rental rental = options.SequencePool.Rent();
			Serialize(rental.Value, value, options, cancellationToken);
			try
			{
				ReadOnlySequence<byte>.Enumerator enumerator = rental.Value.AsReadOnlySequence.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ReadOnlyMemory<byte> current = enumerator.Current;
					cancellationToken.ThrowIfCancellationRequested();
					stream.Write(current.Span);
				}
			}
			catch (Exception inner)
			{
				throw new MessagePackSerializationException("Error occurred while writing the serialized data to the stream.", inner);
			}
		}

		public static async Task SerializeAsync<T>(Stream stream, T value, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			options = options ?? DefaultOptions;
			cancellationToken.ThrowIfCancellationRequested();
			using SequencePool.Rental sequenceRental = options.SequencePool.Rent();
			Serialize(sequenceRental.Value, value, options, cancellationToken);
			try
			{
				ReadOnlySequence<byte>.Enumerator enumerator = sequenceRental.Value.AsReadOnlySequence.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ReadOnlyMemory<byte> current = enumerator.Current;
					cancellationToken.ThrowIfCancellationRequested();
					await stream.WriteAsync(current, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				}
			}
			catch (Exception inner)
			{
				throw new MessagePackSerializationException("Error occurred while writing the serialized data to the stream.", inner);
			}
		}

		public static T Deserialize<T>(in ReadOnlySequence<byte> byteSequence, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			MessagePackReader messagePackReader = new MessagePackReader(in byteSequence);
			messagePackReader.CancellationToken = cancellationToken;
			MessagePackReader reader = messagePackReader;
			return Deserialize<T>(ref reader, options);
		}

		public static T Deserialize<T>(ref MessagePackReader reader, MessagePackSerializerOptions? options = null)
		{
			options = options ?? DefaultOptions;
			try
			{
				if (options.Compression.IsCompression())
				{
					using (SequencePool.Rental rental = options.SequencePool.Rent())
					{
						Sequence<byte> value = rental.Value;
						if (TryDecompress(ref reader, value))
						{
							ReadOnlySequence<byte> readOnlySequence = value.AsReadOnlySequence;
							MessagePackReader reader2 = reader.Clone(in readOnlySequence);
							return options.Resolver.GetFormatterWithVerify<T>().Deserialize(ref reader2, options);
						}
						return options.Resolver.GetFormatterWithVerify<T>().Deserialize(ref reader, options);
					}
				}
				return options.Resolver.GetFormatterWithVerify<T>().Deserialize(ref reader, options);
			}
			catch (Exception inner)
			{
				throw new MessagePackSerializationException("Failed to deserialize " + typeof(T).FullName + " value.", inner);
			}
		}

		public static T Deserialize<T>(ReadOnlyMemory<byte> buffer, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			MessagePackReader messagePackReader = new MessagePackReader(buffer);
			messagePackReader.CancellationToken = cancellationToken;
			MessagePackReader reader = messagePackReader;
			return Deserialize<T>(ref reader, options);
		}

		public static T Deserialize<T>(ReadOnlyMemory<byte> buffer, out int bytesRead, CancellationToken cancellationToken = default(CancellationToken))
		{
			return Deserialize<T>(buffer, null, out bytesRead, cancellationToken);
		}

		public static T Deserialize<T>(ReadOnlyMemory<byte> buffer, MessagePackSerializerOptions? options, out int bytesRead, CancellationToken cancellationToken = default(CancellationToken))
		{
			MessagePackReader messagePackReader = new MessagePackReader(buffer);
			messagePackReader.CancellationToken = cancellationToken;
			MessagePackReader reader = messagePackReader;
			T result = Deserialize<T>(ref reader, options);
			bytesRead = buffer.Slice(0, checked((int)reader.Consumed)).Length;
			return result;
		}

		public static T Deserialize<T>(Stream stream, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			options = options ?? DefaultOptions;
			if (TryDeserializeFromMemoryStream<T>(stream, options, cancellationToken, out var result))
			{
				return result;
			}
			using SequencePool.Rental rental = options.SequencePool.Rent();
			Sequence<byte> value = rental.Value;
			try
			{
				int num;
				do
				{
					cancellationToken.ThrowIfCancellationRequested();
					Span<byte> span = value.GetSpan(stream.CanSeek ? checked((int)Math.Min(options.SuggestedContiguousMemorySize, stream.Length - stream.Position)) : 0);
					num = stream.Read(span);
					value.Advance(num);
				}
				while (num > 0);
			}
			catch (Exception inner)
			{
				throw new MessagePackSerializationException("Error occurred while reading from the stream.", inner);
			}
			return DeserializeFromSequenceAndRewindStreamIfPossible<T>(stream, options, value, cancellationToken);
		}

		public static async ValueTask<T> DeserializeAsync<T>(Stream stream, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			if (options == null)
			{
				options = DefaultOptions;
			}
			if (TryDeserializeFromMemoryStream<T>(stream, options, cancellationToken, out var result))
			{
				return result;
			}
			using SequencePool.Rental sequenceRental = options.SequencePool.Rent();
			Sequence<byte> sequence = sequenceRental.Value;
			try
			{
				int num;
				do
				{
					Memory<byte> memory = sequence.GetMemory(stream.CanSeek ? checked((int)Math.Min(options.SuggestedContiguousMemorySize, stream.Length - stream.Position)) : 0);
					num = await stream.ReadAsync(memory, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
					sequence.Advance(num);
				}
				while (num > 0);
			}
			catch (Exception inner)
			{
				throw new MessagePackSerializationException("Error occurred while reading from the stream.", inner);
			}
			return DeserializeFromSequenceAndRewindStreamIfPossible<T>(stream, options, sequence, cancellationToken);
		}

		private static bool TryDeserializeFromMemoryStream<T>(Stream stream, MessagePackSerializerOptions options, CancellationToken cancellationToken, [MaybeNullWhen(false)] out T result)
		{
			cancellationToken.ThrowIfCancellationRequested();
			if (stream is MemoryStream memoryStream && memoryStream.TryGetBuffer(out var buffer))
			{
				result = Deserialize<T>(buffer.AsMemory(checked((int)memoryStream.Position)), options, out var bytesRead, cancellationToken);
				memoryStream.Seek(bytesRead, SeekOrigin.Current);
				return true;
			}
			result = default(T);
			return false;
		}

		private static T DeserializeFromSequenceAndRewindStreamIfPossible<T>(Stream streamToRewind, MessagePackSerializerOptions? options, ReadOnlySequence<byte> sequence, CancellationToken cancellationToken)
		{
			if (streamToRewind == null)
			{
				throw new ArgumentNullException("streamToRewind");
			}
			MessagePackReader messagePackReader = new MessagePackReader(in sequence);
			messagePackReader.CancellationToken = cancellationToken;
			MessagePackReader reader = messagePackReader;
			T result = Deserialize<T>(ref reader, options);
			checked
			{
				if (streamToRewind.CanSeek && !reader.End)
				{
					int num = (int)reader.Sequence.Slice(reader.Position).Length;
					streamToRewind.Seek(-num, SeekOrigin.Current);
				}
				return result;
			}
		}

		private static int LZ4Operation(in ReadOnlySequence<byte> input, Span<byte> output, LZ4Transform lz4Operation)
		{
			byte[] array = null;
			checked
			{
				ReadOnlySpan<byte> input2;
				if (input.IsSingleSegment)
				{
					input2 = input.First.Span;
				}
				else
				{
					array = ArrayPool<byte>.Shared.Rent((int)input.Length);
					BuffersExtensions.CopyTo(in input, array);
					input2 = array.AsSpan(0, (int)input.Length);
				}
				try
				{
					return lz4Operation(input2, output);
				}
				finally
				{
					if (array != null)
					{
						ArrayPool<byte>.Shared.Return(array);
					}
				}
			}
		}

		private static bool TryDecompress(ref MessagePackReader reader, IBufferWriter<byte> writer)
		{
			checked
			{
				if (!reader.End)
				{
					Span<byte> span;
					if (reader.NextMessagePackType == MessagePackType.Extension && reader.CreatePeekReader().ReadExtensionFormatHeader().TypeCode == 99)
					{
						ReadOnlySequence<byte> readOnlySequence = reader.ReadExtensionFormat().Data;
						MessagePackReader messagePackReader = new MessagePackReader(in readOnlySequence);
						int num = messagePackReader.ReadInt32();
						readOnlySequence = messagePackReader.Sequence;
						ReadOnlySequence<byte> input = readOnlySequence.Slice(messagePackReader.Position);
						span = writer.GetSpan(num);
						Span<byte> output = span.Slice(0, num);
						int count = LZ4Operation(in input, output, LZ4CodecDecode);
						writer.Advance(count);
						return true;
					}
					if (reader.NextMessagePackType == MessagePackType.Array)
					{
						MessagePackReader messagePackReader2 = reader.CreatePeekReader();
						int num2 = messagePackReader2.ReadArrayHeader();
						if (num2 != 0 && messagePackReader2.NextMessagePackType == MessagePackType.Extension && messagePackReader2.ReadExtensionFormatHeader().TypeCode == 98)
						{
							reader = messagePackReader2;
							int num3 = num2 - 1;
							int[] array = ArrayPool<int>.Shared.Rent(num3);
							try
							{
								for (int i = 0; i < num3; i++)
								{
									array[i] = reader.ReadInt32();
								}
								for (int j = 0; j < num3; j++)
								{
									int num4 = array[j];
									ReadOnlySequence<byte> input2 = reader.ReadBytes() ?? throw MessagePackSerializationException.ThrowUnexpectedNilWhileDeserializing<ReadOnlySequence<byte>>();
									span = writer.GetSpan(num4);
									Span<byte> output2 = span.Slice(0, num4);
									int count2 = LZ4Operation(in input2, output2, LZ4CodecDecode);
									writer.Advance(count2);
								}
								return true;
							}
							finally
							{
								ArrayPool<int>.Shared.Return(array);
							}
						}
					}
				}
				return false;
			}
		}

		private static void ToLZ4BinaryCore(in ReadOnlySequence<byte> msgpackUncompressedData, ref MessagePackWriter writer, MessagePackCompression compression, int minCompressionSize)
		{
			if (msgpackUncompressedData.Length < minCompressionSize)
			{
				writer.WriteRaw(in msgpackUncompressedData);
				return;
			}
			checked
			{
				switch (compression)
				{
				case MessagePackCompression.Lz4Block:
				{
					int minimumLength = LZ4Codec.MaximumOutputLength((int)msgpackUncompressedData.Length);
					byte[] array = ArrayPool<byte>.Shared.Rent(minimumLength);
					try
					{
						int num5 = LZ4Operation(in msgpackUncompressedData, array, LZ4CodecEncode);
						writer.WriteExtensionFormatHeader(new ExtensionHeader(99, 5 + (uint)num5));
						writer.WriteInt32((int)msgpackUncompressedData.Length);
						writer.WriteRaw(array.AsSpan(0, num5));
						break;
					}
					finally
					{
						ArrayPool<byte>.Shared.Return(array);
					}
				}
				case MessagePackCompression.Lz4BlockArray:
				{
					int num = 0;
					int num2 = 0;
					ReadOnlySequence<byte>.Enumerator enumerator = msgpackUncompressedData.GetEnumerator();
					while (enumerator.MoveNext())
					{
						ReadOnlyMemory<byte> current = enumerator.Current;
						num++;
						num2 += GetUInt32WriteSize((uint)current.Length);
					}
					writer.WriteArrayHeader(num + 1);
					writer.WriteExtensionFormatHeader(new ExtensionHeader(98, num2));
					enumerator = msgpackUncompressedData.GetEnumerator();
					while (enumerator.MoveNext())
					{
						writer.Write(enumerator.Current.Length);
					}
					enumerator = msgpackUncompressedData.GetEnumerator();
					while (enumerator.MoveNext())
					{
						ReadOnlyMemory<byte> current2 = enumerator.Current;
						int num3 = LZ4Codec.MaximumOutputLength(current2.Length);
						Span<byte> span = writer.GetSpan(num3 + 5);
						int num4 = LZ4Codec.Encode(current2.Span, span.Slice(5, span.Length - 5));
						WriteBin32Header((uint)num4, span);
						writer.Advance(num4 + 5);
					}
					break;
				}
				default:
					throw new ArgumentException("Invalid MessagePackCompression Code. Code:" + compression);
				}
			}
		}

		private static int GetUInt32WriteSize(uint value)
		{
			if (value <= 127)
			{
				return 1;
			}
			if (value <= 255)
			{
				return 2;
			}
			if (value <= 65535)
			{
				return 3;
			}
			return 5;
		}

		private static void WriteBin32Header(uint value, Span<byte> span)
		{
			span[0] = 198;
			span[4] = (byte)value;
			span[3] = (byte)(value >> 8);
			span[2] = (byte)(value >> 16);
			span[1] = (byte)(value >> 24);
		}

		private static bool IsMessagePackFixedSizePrimitiveTypeHelper(Type type)
		{
			if (!(type == typeof(short)) && !(type == typeof(int)) && !(type == typeof(long)) && !(type == typeof(ushort)) && !(type == typeof(uint)) && !(type == typeof(ulong)) && !(type == typeof(float)) && !(type == typeof(double)) && !(type == typeof(bool)) && !(type == typeof(byte)) && !(type == typeof(sbyte)))
			{
				return type == typeof(char);
			}
			return true;
		}

		public static void SerializeToJson<T>(TextWriter textWriter, T obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			options = options ?? DefaultOptions;
			using SequencePool.Rental rental = options.SequencePool.Rent();
			MessagePackWriter messagePackWriter = new MessagePackWriter(rental.Value);
			messagePackWriter.CancellationToken = cancellationToken;
			MessagePackWriter writer = messagePackWriter;
			Serialize(ref writer, obj, options);
			writer.Flush();
			ReadOnlySequence<byte> readOnlySequence = rental.Value;
			MessagePackReader messagePackReader = new MessagePackReader(in readOnlySequence);
			messagePackReader.CancellationToken = cancellationToken;
			MessagePackReader reader = messagePackReader;
			ConvertToJson(ref reader, textWriter, options);
		}

		public static string SerializeToJson<T>(T obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			StringWriter stringWriter = new StringWriter();
			SerializeToJson(stringWriter, obj, options, cancellationToken);
			return stringWriter.ToString();
		}

		public static string ConvertToJson(ReadOnlyMemory<byte> bytes, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			ReadOnlySequence<byte> bytes2 = new ReadOnlySequence<byte>(bytes);
			return ConvertToJson(in bytes2, options, cancellationToken);
		}

		public static string ConvertToJson(in ReadOnlySequence<byte> bytes, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			StringWriter stringWriter = new StringWriter();
			MessagePackReader messagePackReader = new MessagePackReader(in bytes);
			messagePackReader.CancellationToken = cancellationToken;
			MessagePackReader reader = messagePackReader;
			ConvertToJson(ref reader, stringWriter, options);
			return stringWriter.ToString();
		}

		public static void ConvertToJson(ref MessagePackReader reader, TextWriter jsonWriter, MessagePackSerializerOptions? options = null)
		{
			if (reader.End)
			{
				return;
			}
			options = options ?? DefaultOptions;
			try
			{
				if (options.Compression.IsCompression())
				{
					using (SequencePool.Rental rental = options.SequencePool.Rent())
					{
						if (TryDecompress(ref reader, rental.Value))
						{
							ReadOnlySequence<byte> readOnlySequence = rental.Value;
							MessagePackReader messagePackReader = new MessagePackReader(in readOnlySequence);
							messagePackReader.CancellationToken = reader.CancellationToken;
							MessagePackReader reader2 = messagePackReader;
							if (!reader2.End)
							{
								ToJsonCore(ref reader2, jsonWriter, options);
							}
						}
						else
						{
							ToJsonCore(ref reader, jsonWriter, options);
						}
						return;
					}
				}
				ToJsonCore(ref reader, jsonWriter, options);
			}
			catch (Exception inner)
			{
				throw new MessagePackSerializationException("Error occurred while translating msgpack to JSON.", inner);
			}
		}

		public static void ConvertFromJson(string str, ref MessagePackWriter writer, MessagePackSerializerOptions? options = null)
		{
			using StringReader reader = new StringReader(str);
			ConvertFromJson(reader, ref writer, options);
		}

		public static byte[] ConvertFromJson(string str, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			options = options ?? DefaultOptions;
			using SequencePool.Rental rental = options.SequencePool.Rent();
			MessagePackWriter messagePackWriter = new MessagePackWriter(rental.Value);
			messagePackWriter.CancellationToken = cancellationToken;
			MessagePackWriter writer = messagePackWriter;
			using (StringReader reader = new StringReader(str))
			{
				ConvertFromJson(reader, ref writer, options);
			}
			writer.Flush();
			ReadOnlySequence<byte> sequence = rental.Value.AsReadOnlySequence;
			return BuffersExtensions.ToArray(in sequence);
		}

		public static void ConvertFromJson(TextReader reader, ref MessagePackWriter writer, MessagePackSerializerOptions? options = null)
		{
			options = options ?? DefaultOptions;
			if (options.Compression.IsCompression())
			{
				using (SequencePool.Rental rental = options.SequencePool.Rent())
				{
					MessagePackWriter writer2 = writer.Clone(rental.Value);
					using (TinyJsonReader jr = new TinyJsonReader(reader, disposeInnerReader: false))
					{
						FromJsonCore(jr, ref writer2, options);
					}
					writer2.Flush();
					ReadOnlySequence<byte> msgpackUncompressedData = rental.Value;
					ToLZ4BinaryCore(in msgpackUncompressedData, ref writer, options.Compression, options.CompressionMinLength);
					return;
				}
			}
			using TinyJsonReader jr2 = new TinyJsonReader(reader, disposeInnerReader: false);
			FromJsonCore(jr2, ref writer, options);
		}

		private static uint FromJsonCore(TinyJsonReader jr, ref MessagePackWriter writer, MessagePackSerializerOptions options)
		{
			uint num = 0u;
			checked
			{
				while (jr.Read())
				{
					switch (jr.TokenType)
					{
					case TinyJsonToken.StartObject:
					{
						using (SequencePool.Rental rental2 = options.SequencePool.Rent())
						{
							MessagePackWriter writer3 = writer.Clone(rental2.Value);
							uint num2 = FromJsonCore(jr, ref writer3, options);
							writer3.Flush();
							num2 = unchecked(num2 / 2);
							writer.WriteMapHeader(num2);
							ReadOnlySequence<byte> rawMessagePackBlock = rental2.Value;
							writer.WriteRaw(in rawMessagePackBlock);
						}
						num++;
						break;
					}
					case TinyJsonToken.EndObject:
						return num;
					case TinyJsonToken.StartArray:
					{
						using (SequencePool.Rental rental = options.SequencePool.Rent())
						{
							MessagePackWriter writer2 = writer.Clone(rental.Value);
							uint count = FromJsonCore(jr, ref writer2, options);
							writer2.Flush();
							writer.WriteArrayHeader(count);
							ReadOnlySequence<byte> rawMessagePackBlock = rental.Value;
							writer.WriteRaw(in rawMessagePackBlock);
						}
						num++;
						break;
					}
					case TinyJsonToken.EndArray:
						return num;
					case TinyJsonToken.Number:
						switch (jr.ValueType)
						{
						case ValueType.Double:
							writer.Write(jr.DoubleValue);
							break;
						case ValueType.Long:
							writer.Write(jr.LongValue);
							break;
						case ValueType.ULong:
							writer.Write(jr.ULongValue);
							break;
						case ValueType.Decimal:
							DecimalFormatter.Instance.Serialize(ref writer, jr.DecimalValue, options);
							break;
						}
						num++;
						break;
					case TinyJsonToken.String:
						writer.Write(jr.StringValue);
						num++;
						break;
					case TinyJsonToken.True:
						writer.Write(value: true);
						num++;
						break;
					case TinyJsonToken.False:
						writer.Write(value: false);
						num++;
						break;
					case TinyJsonToken.Null:
						writer.WriteNil();
						num++;
						break;
					}
				}
				return num;
			}
		}

		private static void ToJsonCore(ref MessagePackReader reader, TextWriter writer, MessagePackSerializerOptions options)
		{
			checked
			{
				switch (reader.NextMessagePackType)
				{
				case MessagePackType.Integer:
					if (MessagePackCode.IsSignedInteger(reader.NextCode))
					{
						writer.Write(reader.ReadInt64().ToString(CultureInfo.InvariantCulture));
					}
					else
					{
						writer.Write(reader.ReadUInt64().ToString(CultureInfo.InvariantCulture));
					}
					break;
				case MessagePackType.Boolean:
					writer.Write(reader.ReadBoolean() ? "true" : "false");
					break;
				case MessagePackType.Float:
					if (reader.NextCode == 202)
					{
						writer.Write(reader.ReadSingle().ToString(CultureInfo.InvariantCulture));
					}
					else
					{
						writer.Write(reader.ReadDouble().ToString(CultureInfo.InvariantCulture));
					}
					break;
				case MessagePackType.String:
					WriteJsonString(reader.ReadString(), writer);
					break;
				case MessagePackType.Binary:
				{
					ArraySegment<byte> arraySegment = ByteArraySegmentFormatter.Instance.Deserialize(ref reader, options);
					writer.Write("\"" + Convert.ToBase64String(arraySegment.Array ?? Array.Empty<byte>(), arraySegment.Offset, arraySegment.Count) + "\"");
					break;
				}
				case MessagePackType.Array:
				{
					int num2 = reader.ReadArrayHeader();
					options.Security.DepthStep(ref reader);
					try
					{
						writer.Write("[");
						for (int i = 0; i < num2; i++)
						{
							ToJsonCore(ref reader, writer, options);
							if (i != num2 - 1)
							{
								writer.Write(",");
							}
						}
						writer.Write("]");
						break;
					}
					finally
					{
						reader.Depth--;
					}
				}
				case MessagePackType.Map:
				{
					int num3 = reader.ReadMapHeader();
					options.Security.DepthStep(ref reader);
					try
					{
						writer.Write("{");
						for (int j = 0; j < num3; j++)
						{
							MessagePackType nextMessagePackType2 = reader.NextMessagePackType;
							if (nextMessagePackType2 == MessagePackType.String || nextMessagePackType2 == MessagePackType.Binary)
							{
								ToJsonCore(ref reader, writer, options);
							}
							else
							{
								writer.Write("\"");
								ToJsonCore(ref reader, writer, options);
								writer.Write("\"");
							}
							writer.Write(":");
							ToJsonCore(ref reader, writer, options);
							if (j != num3 - 1)
							{
								writer.Write(",");
							}
						}
						writer.Write("}");
						break;
					}
					finally
					{
						reader.Depth--;
					}
				}
				case MessagePackType.Extension:
				{
					ExtensionHeader header = reader.ReadExtensionFormatHeader();
					if (header.TypeCode == -1)
					{
						DateTime dateTime = reader.ReadDateTime(header);
						writer.Write("\"");
						writer.Write(dateTime.ToString("o", CultureInfo.InvariantCulture));
						writer.Write("\"");
					}
					else if (header.TypeCode == 100)
					{
						StringBuilder stringBuilder = new StringBuilder();
						StringBuilder stringBuilder2 = new StringBuilder();
						SequencePosition position = reader.Position;
						ToJsonCore(ref reader, new StringWriter(stringBuilder2), options);
						int num = (int)reader.Sequence.Slice(position, reader.Position).Length;
						if (header.Length > num)
						{
							MessagePackType nextMessagePackType = reader.NextMessagePackType;
							if (nextMessagePackType != MessagePackType.Array && nextMessagePackType != MessagePackType.Map)
							{
								stringBuilder.Append("{");
							}
							ToJsonCore(ref reader, new StringWriter(stringBuilder), options);
							if (nextMessagePackType != MessagePackType.Array)
							{
								stringBuilder2.Insert(0, "\"$type\":");
							}
							if (nextMessagePackType != MessagePackType.Array && nextMessagePackType != MessagePackType.Map)
							{
								stringBuilder.Append("}");
							}
							if (stringBuilder.Length > 2)
							{
								stringBuilder2.Append(",");
							}
							stringBuilder.Insert(1, stringBuilder2.ToString());
							writer.Write(stringBuilder.ToString());
						}
						else
						{
							writer.Write("{\"$type\":" + stringBuilder2.ToString() + "}");
						}
					}
					else
					{
						ReadOnlySequence<byte> sequence = reader.ReadRaw(header.Length);
						writer.Write("[");
						writer.Write(header.TypeCode);
						writer.Write(",");
						writer.Write("\"");
						writer.Write(Convert.ToBase64String(BuffersExtensions.ToArray(in sequence)));
						writer.Write("\"");
						writer.Write("]");
					}
					break;
				}
				case MessagePackType.Nil:
					reader.Skip();
					writer.Write("null");
					break;
				default:
					throw new MessagePackSerializationException($"code is invalid. code: {reader.NextCode} format: {MessagePackCode.ToFormatName(reader.NextCode)}");
				}
			}
		}

		private static void WriteJsonString(string value, TextWriter builder)
		{
			builder.Write('"');
			int length = value.Length;
			for (int i = 0; i < length; i = checked(i + 1))
			{
				char c = value[i];
				switch (c)
				{
				case '"':
					builder.Write("\\\"");
					break;
				case '\\':
					builder.Write("\\\\");
					break;
				case '\b':
					builder.Write("\\b");
					break;
				case '\f':
					builder.Write("\\f");
					break;
				case '\n':
					builder.Write("\\n");
					break;
				case '\r':
					builder.Write("\\r");
					break;
				case '\t':
					builder.Write("\\t");
					break;
				default:
					builder.Write(c);
					break;
				}
			}
			builder.Write('"');
		}

		static MessagePackSerializer()
		{
			LZ4CodecEncode = LZ4Codec.Encode;
			LZ4CodecDecode = LZ4Codec.Decode;
			Serializes = new ThreadsafeTypeKeyHashTable<CompiledMethods>(64);
			CreateCompiledMethods = (Type t) => new CompiledMethods(t);
		}

		public static void Serialize(Type type, ref MessagePackWriter writer, object? obj, MessagePackSerializerOptions? options = null)
		{
			GetOrAdd(type).Serialize_MessagePackWriter_T_Options(ref writer, obj, options);
		}

		public static void Serialize(Type type, IBufferWriter<byte> writer, object? obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			GetOrAdd(type).Serialize_IBufferWriter_T_Options_CancellationToken(writer, obj, options, cancellationToken);
		}

		public static byte[] Serialize(Type type, object? obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			return GetOrAdd(type).Serialize_T_Options(obj, options, cancellationToken);
		}

		public static void Serialize(Type type, Stream stream, object? obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			GetOrAdd(type).Serialize_Stream_T_Options_CancellationToken(stream, obj, options, cancellationToken);
		}

		public static Task SerializeAsync(Type type, Stream stream, object? obj, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			return GetOrAdd(type).SerializeAsync_Stream_T_Options_CancellationToken(stream, obj, options, cancellationToken);
		}

		public static object? Deserialize(Type type, ref MessagePackReader reader, MessagePackSerializerOptions? options = null)
		{
			return GetOrAdd(type).Deserialize_MessagePackReader_Options(ref reader, options);
		}

		public static object? Deserialize(Type type, Stream stream, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			return GetOrAdd(type).Deserialize_Stream_Options_CancellationToken(stream, options, cancellationToken);
		}

		public static ValueTask<object?> DeserializeAsync(Type type, Stream stream, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			return GetOrAdd(type).DeserializeAsync_Stream_Options_CancellationToken(stream, options, cancellationToken);
		}

		public static object? Deserialize(Type type, ReadOnlyMemory<byte> bytes, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			return GetOrAdd(type).Deserialize_ReadOnlyMemory_Options(bytes, options, cancellationToken);
		}

		public static object? Deserialize(Type type, ReadOnlySequence<byte> bytes, MessagePackSerializerOptions? options = null, CancellationToken cancellationToken = default(CancellationToken))
		{
			return GetOrAdd(type).Deserialize_ReadOnlySequence_Options_CancellationToken(bytes, options, cancellationToken);
		}

		private static void SerializeSemiGeneric<T>(ref MessagePackWriter writer, object valueObject, MessagePackSerializerOptions? options = null)
		{
			Serialize(ref writer, (T)valueObject, options);
		}

		private static object? DeserializeSemiGeneric<T>(ref MessagePackReader reader, MessagePackSerializerOptions? options = null)
		{
			return Deserialize<T>(ref reader, options);
		}

		private static async ValueTask<object?> DeserializeObjectAsync<T>(Stream stream, MessagePackSerializerOptions options, CancellationToken cancellationToken)
		{
			return await DeserializeAsync<T>(stream, options, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		private static CompiledMethods GetOrAdd(Type type)
		{
			return Serializes.GetOrAdd(type, CreateCompiledMethods);
		}
	}
	public class MessagePackStreamReader : IDisposable
	{
		private readonly Stream stream;

		private readonly bool leaveOpen;

		private SequencePool.Rental sequenceRental;

		private SequencePosition? endOfLastMessage;

		public ReadOnlySequence<byte> RemainingBytes
		{
			get
			{
				if (!endOfLastMessage.HasValue)
				{
					return ReadData.AsReadOnlySequence;
				}
				return ReadData.AsReadOnlySequence.Slice(endOfLastMessage.Value);
			}
		}

		private Sequence<byte> ReadData => sequenceRental.Value;

		public async ValueTask<int> ReadArrayHeaderAsync(CancellationToken cancellationToken)
		{
			RecycleLastMessage();
			cancellationToken.ThrowIfCancellationRequested();
			int length;
			while (!TryReadArrayHeader(out length))
			{
				if (!(await TryReadMoreDataAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					throw new EndOfStreamException("The stream ended before a map header could be found.");
				}
			}
			return length;
		}

		public async IAsyncEnumerable<ReadOnlySequence<byte>> ReadArrayAsync([EnumeratorCancellation] CancellationToken cancellationToken)
		{
			RecycleLastMessage();
			cancellationToken.ThrowIfCancellationRequested();
			int length;
			while (!TryReadArrayHeader(out length))
			{
				if (!(await TryReadMoreDataAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					throw new EndOfStreamException("The stream ended before an array header could be found.");
				}
			}
			for (int i = 0; i < length; i = checked(i + 1))
			{
				ReadOnlySequence<byte>? readOnlySequence = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				if (!readOnlySequence.HasValue)
				{
					throw new EndOfStreamException("Stream ended before all elements were read.");
				}
				yield return readOnlySequence.Value;
			}
		}

		private bool TryReadArrayHeader(out int length)
		{
			if (ReadData.Length > 0)
			{
				ReadOnlySequence<byte> readOnlySequence = ReadData;
				MessagePackReader messagePackReader = new MessagePackReader(in readOnlySequence);
				if (messagePackReader.TryReadArrayHeader(out length))
				{
					endOfLastMessage = messagePackReader.Position;
					return true;
				}
			}
			length = 0;
			return false;
		}

		public async ValueTask<int> ReadMapHeaderAsync(CancellationToken cancellationToken)
		{
			RecycleLastMessage();
			cancellationToken.ThrowIfCancellationRequested();
			int count;
			while (!TryReadMapHeader(out count))
			{
				if (!(await TryReadMoreDataAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					throw new EndOfStreamException("The stream ended before a map header could be found.");
				}
			}
			return count;
		}

		private bool TryReadMapHeader(out int count)
		{
			if (ReadData.Length > 0)
			{
				ReadOnlySequence<byte> readOnlySequence = ReadData;
				MessagePackReader messagePackReader = new MessagePackReader(in readOnlySequence);
				if (messagePackReader.TryReadMapHeader(out count))
				{
					endOfLastMessage = messagePackReader.Position;
					return true;
				}
			}
			count = 0;
			return false;
		}

		public MessagePackStreamReader(Stream stream)
			: this(stream, leaveOpen: false)
		{
		}

		public MessagePackStreamReader(Stream stream, bool leaveOpen)
			: this(stream, leaveOpen, SequencePool.Shared)
		{
		}

		public MessagePackStreamReader(Stream stream, bool leaveOpen, SequencePool sequencePool)
		{
			if (sequencePool == null)
			{
				throw new ArgumentNullException("sequencePool");
			}
			this.stream = stream ?? throw new ArgumentNullException("stream");
			this.leaveOpen = leaveOpen;
			sequenceRental = sequencePool.Rent();
		}

		public async ValueTask<ReadOnlySequence<byte>?> ReadAsync(CancellationToken cancellationToken)
		{
			RecycleLastMessage();
			do
			{
				cancellationToken.ThrowIfCancellationRequested();
				if (TryReadNextMessage(out var completeMessage))
				{
					return completeMessage;
				}
			}
			while (await TryReadMoreDataAsync(cancellationToken)

BepInEx/plugins/SOTFEdit_Companion/SOTFEdit.Companion.Shared.dll

Decompiled 9 months ago
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using MessagePack;
using MessagePack.Formatters;
using MessagePack.Formatters.SOTFEdit.Companion.Shared;
using MessagePack.Formatters.SOTFEdit.Companion.Shared.Messages;
using MessagePack.Internal;
using MessagePack.Resolvers;
using Microsoft.CodeAnalysis;
using SOTFEdit.Companion.Shared;
using SOTFEdit.Companion.Shared.Messages;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SOTFEdit.Companion.Shared")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b51329a2329d8ee3c0696ee45aeca38967302463")]
[assembly: AssemblyProduct("SOTFEdit.Companion.Shared")]
[assembly: AssemblyTitle("SOTFEdit.Companion.Shared")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace MessagePack.Formatters.SOTFEdit.Companion.Shared
{
	public sealed class CharacterTargetFormatter : IMessagePackFormatter<CharacterTarget>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CharacterTarget value, MessagePackSerializerOptions options)
		{
			((MessagePackWriter)(ref writer)).Write((int)value);
		}

		public CharacterTarget Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			return (CharacterTarget)((MessagePackReader)(ref reader)).ReadInt32();
		}
	}
	public sealed class PoiGroupTypeFormatter : IMessagePackFormatter<PoiGroupType>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, PoiGroupType value, MessagePackSerializerOptions options)
		{
			((MessagePackWriter)(ref writer)).Write((int)value);
		}

		public PoiGroupType Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			return (PoiGroupType)((MessagePackReader)(ref reader)).ReadInt32();
		}
	}
}
namespace MessagePack.Formatters.SOTFEdit.Companion.Shared.Messages
{
	public sealed class ICompanionMessageFormatter : IMessagePackFormatter<ICompanionMessage>, IMessagePackFormatter
	{
		private readonly Dictionary<RuntimeTypeHandle, KeyValuePair<int, int>> typeToKeyAndJumpMap;

		private readonly Dictionary<int, int> keyToJumpMap;

		public ICompanionMessageFormatter()
		{
			typeToKeyAndJumpMap = new Dictionary<RuntimeTypeHandle, KeyValuePair<int, int>>(10, RuntimeTypeHandleEqualityComparer.Default)
			{
				{
					typeof(CompanionPosMessage).TypeHandle,
					new KeyValuePair<int, int>(0, 0)
				},
				{
					typeof(CompanionPosCollectionMessage).TypeHandle,
					new KeyValuePair<int, int>(1, 1)
				},
				{
					typeof(CompanionTeleportMessage).TypeHandle,
					new KeyValuePair<int, int>(2, 2)
				},
				{
					typeof(CompanionAddPoiMessage).TypeHandle,
					new KeyValuePair<int, int>(3, 3)
				},
				{
					typeof(CompanionPoiListMessage).TypeHandle,
					new KeyValuePair<int, int>(4, 4)
				},
				{
					typeof(CompanionPoiMessage).TypeHandle,
					new KeyValuePair<int, int>(5, 5)
				},
				{
					typeof(CompanionDumpScenesMessage).TypeHandle,
					new KeyValuePair<int, int>(6, 6)
				},
				{
					typeof(CompanionRequestPoiUpdateMessage).TypeHandle,
					new KeyValuePair<int, int>(7, 7)
				},
				{
					typeof(CompanionNetworkPlayerUpdateMessage).TypeHandle,
					new KeyValuePair<int, int>(8, 8)
				},
				{
					typeof(CompanionSettingsMessage).TypeHandle,
					new KeyValuePair<int, int>(9, 9)
				}
			};
			keyToJumpMap = new Dictionary<int, int>(10)
			{
				{ 0, 0 },
				{ 1, 1 },
				{ 2, 2 },
				{ 3, 3 },
				{ 4, 4 },
				{ 5, 5 },
				{ 6, 6 },
				{ 7, 7 },
				{ 8, 8 },
				{ 9, 9 }
			};
		}

		public void Serialize(ref MessagePackWriter writer, ICompanionMessage value, MessagePackSerializerOptions options)
		{
			if (value != null && typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out var value2))
			{
				((MessagePackWriter)(ref writer)).WriteArrayHeader(2);
				((MessagePackWriter)(ref writer)).WriteInt32(value2.Key);
				switch (value2.Value)
				{
				case 0:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionPosMessage>(options.Resolver).Serialize(ref writer, (CompanionPosMessage)value, options);
					break;
				case 1:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionPosCollectionMessage>(options.Resolver).Serialize(ref writer, (CompanionPosCollectionMessage)value, options);
					break;
				case 2:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionTeleportMessage>(options.Resolver).Serialize(ref writer, (CompanionTeleportMessage)value, options);
					break;
				case 3:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionAddPoiMessage>(options.Resolver).Serialize(ref writer, (CompanionAddPoiMessage)value, options);
					break;
				case 4:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionPoiListMessage>(options.Resolver).Serialize(ref writer, (CompanionPoiListMessage)value, options);
					break;
				case 5:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionPoiMessage>(options.Resolver).Serialize(ref writer, (CompanionPoiMessage)value, options);
					break;
				case 6:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionDumpScenesMessage>(options.Resolver).Serialize(ref writer, (CompanionDumpScenesMessage)value, options);
					break;
				case 7:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionRequestPoiUpdateMessage>(options.Resolver).Serialize(ref writer, (CompanionRequestPoiUpdateMessage)value, options);
					break;
				case 8:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionNetworkPlayerUpdateMessage>(options.Resolver).Serialize(ref writer, (CompanionNetworkPlayerUpdateMessage)value, options);
					break;
				case 9:
					FormatterResolverExtensions.GetFormatterWithVerify<CompanionSettingsMessage>(options.Resolver).Serialize(ref writer, (CompanionSettingsMessage)value, options);
					break;
				}
			}
			else
			{
				((MessagePackWriter)(ref writer)).WriteNil();
			}
		}

		public ICompanionMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			if (((MessagePackReader)(ref reader)).ReadArrayHeader() != 2)
			{
				throw new InvalidOperationException("Invalid Union data was detected. Type:global::SOTFEdit.Companion.Shared.Messages.ICompanionMessage");
			}
			options.Security.DepthStep(ref reader);
			int value = ((MessagePackReader)(ref reader)).ReadInt32();
			if (!keyToJumpMap.TryGetValue(value, out value))
			{
				value = -1;
			}
			ICompanionMessage result = null;
			switch (value)
			{
			case 0:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionPosMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			case 1:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionPosCollectionMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			case 2:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionTeleportMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			case 3:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionAddPoiMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			case 4:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionPoiListMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			case 5:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionPoiMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			case 6:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionDumpScenesMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			case 7:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionRequestPoiUpdateMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			case 8:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionNetworkPlayerUpdateMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			case 9:
				result = FormatterResolverExtensions.GetFormatterWithVerify<CompanionSettingsMessage>(options.Resolver).Deserialize(ref reader, options);
				break;
			default:
				((MessagePackReader)(ref reader)).Skip();
				break;
			}
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return result;
		}
	}
	public sealed class CompanionAddPoiMessageFormatter : IMessagePackFormatter<CompanionAddPoiMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionAddPoiMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
				return;
			}
			IFormatterResolver resolver = options.Resolver;
			((MessagePackWriter)(ref writer)).WriteArrayHeader(7);
			FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Serialize(ref writer, value.Title, options);
			FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Serialize(ref writer, value.Description, options);
			((MessagePackWriter)(ref writer)).Write(value.Screenshot);
			((MessagePackWriter)(ref writer)).Write(value.X);
			((MessagePackWriter)(ref writer)).Write(value.Y);
			((MessagePackWriter)(ref writer)).Write(value.Z);
			((MessagePackWriter)(ref writer)).Write(value.AreaMask);
		}

		public CompanionAddPoiMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			options.Security.DepthStep(ref reader);
			IFormatterResolver resolver = options.Resolver;
			int num = ((MessagePackReader)(ref reader)).ReadArrayHeader();
			CompanionAddPoiMessage companionAddPoiMessage = new CompanionAddPoiMessage();
			for (int i = 0; i < num; i++)
			{
				switch (i)
				{
				case 0:
					companionAddPoiMessage.Title = FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Deserialize(ref reader, options);
					break;
				case 1:
					companionAddPoiMessage.Description = FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Deserialize(ref reader, options);
					break;
				case 2:
				{
					ReadOnlySequence<byte>? readOnlySequence = ((MessagePackReader)(ref reader)).ReadBytes();
					companionAddPoiMessage.Screenshot = CodeGenHelpers.GetArrayFromNullableSequence(ref readOnlySequence);
					break;
				}
				case 3:
					companionAddPoiMessage.X = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 4:
					companionAddPoiMessage.Y = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 5:
					companionAddPoiMessage.Z = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 6:
					companionAddPoiMessage.AreaMask = ((MessagePackReader)(ref reader)).ReadInt32();
					break;
				default:
					((MessagePackReader)(ref reader)).Skip();
					break;
				}
			}
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return companionAddPoiMessage;
		}
	}
	public sealed class CompanionDumpScenesMessageFormatter : IMessagePackFormatter<CompanionDumpScenesMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionDumpScenesMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
			}
			else
			{
				((MessagePackWriter)(ref writer)).WriteArrayHeader(0);
			}
		}

		public CompanionDumpScenesMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			((MessagePackReader)(ref reader)).Skip();
			return new CompanionDumpScenesMessage();
		}
	}
	public sealed class CompanionNetworkPlayerUpdateMessageFormatter : IMessagePackFormatter<CompanionNetworkPlayerUpdateMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionNetworkPlayerUpdateMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
				return;
			}
			IFormatterResolver resolver = options.Resolver;
			((MessagePackWriter)(ref writer)).WriteArrayHeader(2);
			FormatterResolverExtensions.GetFormatterWithVerify<HashSet<int>>(resolver).Serialize(ref writer, value.Added, options);
			FormatterResolverExtensions.GetFormatterWithVerify<HashSet<int>>(resolver).Serialize(ref writer, value.Deleted, options);
		}

		public CompanionNetworkPlayerUpdateMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			options.Security.DepthStep(ref reader);
			IFormatterResolver resolver = options.Resolver;
			int num = ((MessagePackReader)(ref reader)).ReadArrayHeader();
			CompanionNetworkPlayerUpdateMessage companionNetworkPlayerUpdateMessage = new CompanionNetworkPlayerUpdateMessage();
			for (int i = 0; i < num; i++)
			{
				switch (i)
				{
				case 0:
					companionNetworkPlayerUpdateMessage.Added = FormatterResolverExtensions.GetFormatterWithVerify<HashSet<int>>(resolver).Deserialize(ref reader, options);
					break;
				case 1:
					companionNetworkPlayerUpdateMessage.Deleted = FormatterResolverExtensions.GetFormatterWithVerify<HashSet<int>>(resolver).Deserialize(ref reader, options);
					break;
				default:
					((MessagePackReader)(ref reader)).Skip();
					break;
				}
			}
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return companionNetworkPlayerUpdateMessage;
		}
	}
	public sealed class CompanionPoiListMessageFormatter : IMessagePackFormatter<CompanionPoiListMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionPoiListMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
				return;
			}
			IFormatterResolver resolver = options.Resolver;
			((MessagePackWriter)(ref writer)).WriteArrayHeader(2);
			FormatterResolverExtensions.GetFormatterWithVerify<PoiGroupType>(resolver).Serialize(ref writer, value.Type, options);
			FormatterResolverExtensions.GetFormatterWithVerify<List<CompanionPoiMessage>>(resolver).Serialize(ref writer, value.Pois, options);
		}

		public CompanionPoiListMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			options.Security.DepthStep(ref reader);
			IFormatterResolver resolver = options.Resolver;
			int num = ((MessagePackReader)(ref reader)).ReadArrayHeader();
			PoiGroupType type = PoiGroupType.Generic;
			List<CompanionPoiMessage> pois = null;
			for (int i = 0; i < num; i++)
			{
				switch (i)
				{
				case 0:
					type = FormatterResolverExtensions.GetFormatterWithVerify<PoiGroupType>(resolver).Deserialize(ref reader, options);
					break;
				case 1:
					pois = FormatterResolverExtensions.GetFormatterWithVerify<List<CompanionPoiMessage>>(resolver).Deserialize(ref reader, options);
					break;
				default:
					((MessagePackReader)(ref reader)).Skip();
					break;
				}
			}
			CompanionPoiListMessage result = new CompanionPoiListMessage(type, pois);
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return result;
		}
	}
	public sealed class CompanionPoiMessageFormatter : IMessagePackFormatter<CompanionPoiMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionPoiMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
				return;
			}
			IFormatterResolver resolver = options.Resolver;
			((MessagePackWriter)(ref writer)).WriteArrayHeader(7);
			FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Serialize(ref writer, value.Title, options);
			FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Serialize(ref writer, value.Description, options);
			((MessagePackWriter)(ref writer)).Write(value.X);
			((MessagePackWriter)(ref writer)).Write(value.Y);
			((MessagePackWriter)(ref writer)).Write(value.Z);
			((MessagePackWriter)(ref writer)).Write(value.AreaMask);
			FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Serialize(ref writer, value.ScreenshotPath, options);
		}

		public CompanionPoiMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			options.Security.DepthStep(ref reader);
			IFormatterResolver resolver = options.Resolver;
			int num = ((MessagePackReader)(ref reader)).ReadArrayHeader();
			string title = null;
			string description = null;
			float x = 0f;
			float y = 0f;
			float z = 0f;
			int areaMask = 0;
			string screenshotPath = null;
			for (int i = 0; i < num; i++)
			{
				switch (i)
				{
				case 0:
					title = FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Deserialize(ref reader, options);
					break;
				case 1:
					description = FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Deserialize(ref reader, options);
					break;
				case 2:
					x = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 3:
					y = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 4:
					z = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 5:
					areaMask = ((MessagePackReader)(ref reader)).ReadInt32();
					break;
				case 6:
					screenshotPath = FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Deserialize(ref reader, options);
					break;
				default:
					((MessagePackReader)(ref reader)).Skip();
					break;
				}
			}
			CompanionPoiMessage result = new CompanionPoiMessage(title, description, x, y, z, areaMask, screenshotPath);
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return result;
		}
	}
	public sealed class CompanionPosCollectionMessageFormatter : IMessagePackFormatter<CompanionPosCollectionMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionPosCollectionMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
				return;
			}
			IFormatterResolver resolver = options.Resolver;
			((MessagePackWriter)(ref writer)).WriteArrayHeader(1);
			FormatterResolverExtensions.GetFormatterWithVerify<List<CompanionPosMessage>>(resolver).Serialize(ref writer, value.Positions, options);
		}

		public CompanionPosCollectionMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			options.Security.DepthStep(ref reader);
			IFormatterResolver resolver = options.Resolver;
			int num = ((MessagePackReader)(ref reader)).ReadArrayHeader();
			CompanionPosCollectionMessage companionPosCollectionMessage = new CompanionPosCollectionMessage();
			for (int i = 0; i < num; i++)
			{
				if (i == 0)
				{
					companionPosCollectionMessage.Positions = FormatterResolverExtensions.GetFormatterWithVerify<List<CompanionPosMessage>>(resolver).Deserialize(ref reader, options);
				}
				else
				{
					((MessagePackReader)(ref reader)).Skip();
				}
			}
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return companionPosCollectionMessage;
		}
	}
	public sealed class CompanionPosMessageFormatter : IMessagePackFormatter<CompanionPosMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionPosMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
				return;
			}
			IFormatterResolver resolver = options.Resolver;
			((MessagePackWriter)(ref writer)).WriteArrayHeader(8);
			FormatterResolverExtensions.GetFormatterWithVerify<CharacterTarget>(resolver).Serialize(ref writer, value.Target, options);
			((MessagePackWriter)(ref writer)).Write(value.X);
			((MessagePackWriter)(ref writer)).Write(value.Y);
			((MessagePackWriter)(ref writer)).Write(value.Z);
			((MessagePackWriter)(ref writer)).Write(value.Rotation);
			((MessagePackWriter)(ref writer)).Write(value.Mask);
			((MessagePackWriter)(ref writer)).Write(value.InstanceId);
			FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Serialize(ref writer, value.Name, options);
		}

		public CompanionPosMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			options.Security.DepthStep(ref reader);
			IFormatterResolver resolver = options.Resolver;
			int num = ((MessagePackReader)(ref reader)).ReadArrayHeader();
			CompanionPosMessage companionPosMessage = new CompanionPosMessage();
			for (int i = 0; i < num; i++)
			{
				switch (i)
				{
				case 0:
					companionPosMessage.Target = FormatterResolverExtensions.GetFormatterWithVerify<CharacterTarget>(resolver).Deserialize(ref reader, options);
					break;
				case 1:
					companionPosMessage.X = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 2:
					companionPosMessage.Y = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 3:
					companionPosMessage.Z = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 4:
					companionPosMessage.Rotation = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 5:
					companionPosMessage.Mask = ((MessagePackReader)(ref reader)).ReadInt32();
					break;
				case 6:
					companionPosMessage.InstanceId = ((MessagePackReader)(ref reader)).ReadInt32();
					break;
				case 7:
					companionPosMessage.Name = FormatterResolverExtensions.GetFormatterWithVerify<string>(resolver).Deserialize(ref reader, options);
					break;
				default:
					((MessagePackReader)(ref reader)).Skip();
					break;
				}
			}
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return companionPosMessage;
		}
	}
	public sealed class CompanionRequestPoiUpdateMessageFormatter : IMessagePackFormatter<CompanionRequestPoiUpdateMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionRequestPoiUpdateMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
				return;
			}
			IFormatterResolver resolver = options.Resolver;
			((MessagePackWriter)(ref writer)).WriteArrayHeader(1);
			FormatterResolverExtensions.GetFormatterWithVerify<PoiGroupType>(resolver).Serialize(ref writer, value.Type, options);
		}

		public CompanionRequestPoiUpdateMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			options.Security.DepthStep(ref reader);
			IFormatterResolver resolver = options.Resolver;
			int num = ((MessagePackReader)(ref reader)).ReadArrayHeader();
			CompanionRequestPoiUpdateMessage companionRequestPoiUpdateMessage = new CompanionRequestPoiUpdateMessage();
			for (int i = 0; i < num; i++)
			{
				if (i == 0)
				{
					companionRequestPoiUpdateMessage.Type = FormatterResolverExtensions.GetFormatterWithVerify<PoiGroupType>(resolver).Deserialize(ref reader, options);
				}
				else
				{
					((MessagePackReader)(ref reader)).Skip();
				}
			}
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return companionRequestPoiUpdateMessage;
		}
	}
	public sealed class CompanionSettingsMessageFormatter : IMessagePackFormatter<CompanionSettingsMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionSettingsMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
				return;
			}
			IFormatterResolver resolver = options.Resolver;
			((MessagePackWriter)(ref writer)).WriteArrayHeader(1);
			FormatterResolverExtensions.GetFormatterWithVerify<decimal>(resolver).Serialize(ref writer, value.PositionUpdateFrequency, options);
		}

		public CompanionSettingsMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			options.Security.DepthStep(ref reader);
			IFormatterResolver resolver = options.Resolver;
			int num = ((MessagePackReader)(ref reader)).ReadArrayHeader();
			CompanionSettingsMessage companionSettingsMessage = new CompanionSettingsMessage();
			for (int i = 0; i < num; i++)
			{
				if (i == 0)
				{
					companionSettingsMessage.PositionUpdateFrequency = FormatterResolverExtensions.GetFormatterWithVerify<decimal>(resolver).Deserialize(ref reader, options);
				}
				else
				{
					((MessagePackReader)(ref reader)).Skip();
				}
			}
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return companionSettingsMessage;
		}
	}
	public sealed class CompanionTeleportMessageFormatter : IMessagePackFormatter<CompanionTeleportMessage>, IMessagePackFormatter
	{
		public void Serialize(ref MessagePackWriter writer, CompanionTeleportMessage value, MessagePackSerializerOptions options)
		{
			if (value == null)
			{
				((MessagePackWriter)(ref writer)).WriteNil();
				return;
			}
			IFormatterResolver resolver = options.Resolver;
			((MessagePackWriter)(ref writer)).WriteArrayHeader(6);
			FormatterResolverExtensions.GetFormatterWithVerify<CharacterTarget>(resolver).Serialize(ref writer, value.Target, options);
			((MessagePackWriter)(ref writer)).Write(value.X);
			((MessagePackWriter)(ref writer)).Write(value.Y);
			((MessagePackWriter)(ref writer)).Write(value.Z);
			((MessagePackWriter)(ref writer)).Write(value.AreaMask);
			((MessagePackWriter)(ref writer)).Write(value.GraphMask);
		}

		public CompanionTeleportMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
		{
			if (((MessagePackReader)(ref reader)).TryReadNil())
			{
				return null;
			}
			options.Security.DepthStep(ref reader);
			IFormatterResolver resolver = options.Resolver;
			int num = ((MessagePackReader)(ref reader)).ReadArrayHeader();
			CompanionTeleportMessage companionTeleportMessage = new CompanionTeleportMessage();
			for (int i = 0; i < num; i++)
			{
				switch (i)
				{
				case 0:
					companionTeleportMessage.Target = FormatterResolverExtensions.GetFormatterWithVerify<CharacterTarget>(resolver).Deserialize(ref reader, options);
					break;
				case 1:
					companionTeleportMessage.X = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 2:
					companionTeleportMessage.Y = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 3:
					companionTeleportMessage.Z = ((MessagePackReader)(ref reader)).ReadSingle();
					break;
				case 4:
					companionTeleportMessage.AreaMask = ((MessagePackReader)(ref reader)).ReadInt32();
					break;
				case 5:
					companionTeleportMessage.GraphMask = ((MessagePackReader)(ref reader)).ReadInt32();
					break;
				default:
					((MessagePackReader)(ref reader)).Skip();
					break;
				}
			}
			int depth = ((MessagePackReader)(ref reader)).Depth;
			((MessagePackReader)(ref reader)).Depth = depth - 1;
			return companionTeleportMessage;
		}
	}
}
namespace MessagePack.Resolvers
{
	public class GeneratedResolver : IFormatterResolver
	{
		private static class FormatterCache<T>
		{
			internal static readonly IMessagePackFormatter<T> Formatter;

			static FormatterCache()
			{
				object formatter = GeneratedResolverGetFormatterHelper.GetFormatter(typeof(T));
				if (formatter != null)
				{
					Formatter = (IMessagePackFormatter<T>)formatter;
				}
			}
		}

		public static readonly IFormatterResolver Instance = (IFormatterResolver)(object)new GeneratedResolver();

		private GeneratedResolver()
		{
		}

		public IMessagePackFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.Formatter;
		}
	}
	internal static class GeneratedResolverGetFormatterHelper
	{
		private static readonly Dictionary<Type, int> lookup;

		static GeneratedResolverGetFormatterHelper()
		{
			lookup = new Dictionary<Type, int>(16)
			{
				{
					typeof(HashSet<int>),
					0
				},
				{
					typeof(List<CompanionPoiMessage>),
					1
				},
				{
					typeof(List<CompanionPosMessage>),
					2
				},
				{
					typeof(CharacterTarget),
					3
				},
				{
					typeof(PoiGroupType),
					4
				},
				{
					typeof(ICompanionMessage),
					5
				},
				{
					typeof(CompanionAddPoiMessage),
					6
				},
				{
					typeof(CompanionDumpScenesMessage),
					7
				},
				{
					typeof(CompanionNetworkPlayerUpdateMessage),
					8
				},
				{
					typeof(CompanionPoiListMessage),
					9
				},
				{
					typeof(CompanionPoiMessage),
					10
				},
				{
					typeof(CompanionPosCollectionMessage),
					11
				},
				{
					typeof(CompanionPosMessage),
					12
				},
				{
					typeof(CompanionRequestPoiUpdateMessage),
					13
				},
				{
					typeof(CompanionSettingsMessage),
					14
				},
				{
					typeof(CompanionTeleportMessage),
					15
				}
			};
		}

		internal static object GetFormatter(Type t)
		{
			if (!lookup.TryGetValue(t, out var value))
			{
				return null;
			}
			return value switch
			{
				0 => new HashSetFormatter<int>(), 
				1 => new ListFormatter<CompanionPoiMessage>(), 
				2 => new ListFormatter<CompanionPosMessage>(), 
				3 => new CharacterTargetFormatter(), 
				4 => new PoiGroupTypeFormatter(), 
				5 => new ICompanionMessageFormatter(), 
				6 => new CompanionAddPoiMessageFormatter(), 
				7 => new CompanionDumpScenesMessageFormatter(), 
				8 => new CompanionNetworkPlayerUpdateMessageFormatter(), 
				9 => new CompanionPoiListMessageFormatter(), 
				10 => new CompanionPoiMessageFormatter(), 
				11 => new CompanionPosCollectionMessageFormatter(), 
				12 => new CompanionPosMessageFormatter(), 
				13 => new CompanionRequestPoiUpdateMessageFormatter(), 
				14 => new CompanionSettingsMessageFormatter(), 
				15 => new CompanionTeleportMessageFormatter(), 
				_ => null, 
			};
		}
	}
}
namespace SOTFEdit.Companion.Shared
{
	public enum CharacterTarget
	{
		Player,
		Kelvin,
		Virginia,
		NetworkPlayer
	}
	public static class MessagePackInitializer
	{
		private static bool _initialized;

		public static void Initialize()
		{
			if (!_initialized)
			{
				StaticCompositeResolver.Instance.Register((IFormatterResolver[])(object)new IFormatterResolver[2]
				{
					GeneratedResolver.Instance,
					(IFormatterResolver)StandardResolver.Instance
				});
				MessagePackSerializer.DefaultOptions = MessagePackSerializerOptions.Standard.WithResolver((IFormatterResolver)(object)StaticCompositeResolver.Instance);
				_initialized = true;
			}
		}
	}
	public enum PoiGroupType
	{
		Generic,
		Custom,
		Items,
		Actors,
		WorldItems,
		Bunkers,
		Printers,
		Laptops,
		Caves,
		Camps,
		Villages,
		Helicopters,
		Info,
		Doors,
		Crates,
		Supply,
		Ammo,
		CannibalVillages,
		Ponds,
		Lakes,
		Structures,
		ZipLines,
		Player,
		Followers
	}
	public static class PoiGroupTypeUtils
	{
		public static PoiGroupType[] GetSupportedCompanionPoiGroupTypes()
		{
			return (from e in Enum.GetValues<PoiGroupType>().Where(delegate(PoiGroupType e)
				{
					switch (e)
					{
					case PoiGroupType.Custom:
					case PoiGroupType.Items:
					case PoiGroupType.WorldItems:
					case PoiGroupType.Bunkers:
					case PoiGroupType.Printers:
					case PoiGroupType.Laptops:
					case PoiGroupType.Caves:
					case PoiGroupType.Villages:
					case PoiGroupType.Helicopters:
					case PoiGroupType.Doors:
					case PoiGroupType.Lakes:
						return true;
					default:
						return false;
					}
				})
				orderby e.ToString()
				select e).ToArray();
		}
	}
}
namespace SOTFEdit.Companion.Shared.Messages
{
	[MessagePackObject(false)]
	public class CompanionAddPoiMessage : ICompanionMessage
	{
		[Key(0)]
		public string Title { get; set; }

		[Key(1)]
		public string Description { get; set; }

		[Key(2)]
		public byte[] Screenshot { get; set; }

		[Key(3)]
		public float X { get; set; }

		[Key(4)]
		public float Y { get; set; }

		[Key(5)]
		public float Z { get; set; }

		[Key(6)]
		public int AreaMask { get; set; }
	}
	[MessagePackObject(false)]
	public record CompanionDumpScenesMessage : ICompanionMessage;
	[MessagePackObject(false)]
	public class CompanionNetworkPlayerUpdateMessage : ICompanionMessage
	{
		[Key(0)]
		public HashSet<int>? Added { get; set; }

		[Key(1)]
		public HashSet<int>? Deleted { get; set; }
	}
	[MessagePackObject(false)]
	public class CompanionPoiListMessage : ICompanionMessage
	{
		[Key(0)]
		public PoiGroupType Type { get; }

		[Key(1)]
		public List<CompanionPoiMessage> Pois { get; }

		public CompanionPoiListMessage(PoiGroupType type, List<CompanionPoiMessage> pois)
		{
			Type = type;
			Pois = pois;
		}
	}
	[MessagePackObject(false)]
	public class CompanionPoiMessage : ICompanionMessage
	{
		[Key(0)]
		public string Title { get; init; }

		[Key(1)]
		public string? Description { get; init; }

		[Key(2)]
		public float X { get; init; }

		[Key(3)]
		public float Y { get; init; }

		[Key(4)]
		public float Z { get; init; }

		[Key(5)]
		public int AreaMask { get; init; }

		[Key(6)]
		public string? ScreenshotPath { get; init; }

		public CompanionPoiMessage(string title, string? description, float x, float y, float z, int areaMask, string? screenshotPath)
		{
			Title = title;
			Description = description;
			X = x;
			Y = y;
			Z = z;
			AreaMask = areaMask;
			ScreenshotPath = screenshotPath;
		}
	}
	[MessagePackObject(false)]
	public class CompanionPosCollectionMessage : ICompanionMessage
	{
		[Key(0)]
		public List<CompanionPosMessage> Positions { get; set; }
	}
	[MessagePackObject(false)]
	public record CompanionPosMessage : ICompanionMessage
	{
		[Key(0)]
		public CharacterTarget Target { get; set; }

		[Key(1)]
		public float X { get; set; }

		[Key(2)]
		public float Y { get; set; }

		[Key(3)]
		public float Z { get; set; }

		[Key(4)]
		public float Rotation { get; set; }

		[Key(5)]
		public int Mask { get; set; }

		[Key(6)]
		public int InstanceId { get; set; }

		[Key(7)]
		public string? Name { get; set; }
	}
	[MessagePackObject(false)]
	public class CompanionRequestPoiUpdateMessage : ICompanionMessage
	{
		[Key(0)]
		public PoiGroupType Type { get; set; }
	}
	[MessagePackObject(false)]
	public class CompanionSettingsMessage : ICompanionMessage
	{
		[Key(0)]
		public decimal PositionUpdateFrequency { get; set; }
	}
	[MessagePackObject(false)]
	public record CompanionTeleportMessage : ICompanionMessage
	{
		[Key(0)]
		public CharacterTarget Target { get; set; }

		[Key(1)]
		public float X { get; set; }

		[Key(2)]
		public float Y { get; set; }

		[Key(3)]
		public float Z { get; set; }

		[Key(4)]
		public int AreaMask { get; set; }

		[Key(5)]
		public int GraphMask { get; set; }
	}
	[Union(0, typeof(CompanionPosMessage))]
	[Union(1, typeof(CompanionPosCollectionMessage))]
	[Union(2, typeof(CompanionTeleportMessage))]
	[Union(3, typeof(CompanionAddPoiMessage))]
	[Union(4, typeof(CompanionPoiListMessage))]
	[Union(5, typeof(CompanionPoiMessage))]
	[Union(6, typeof(CompanionDumpScenesMessage))]
	[Union(7, typeof(CompanionRequestPoiUpdateMessage))]
	[Union(8, typeof(CompanionNetworkPlayerUpdateMessage))]
	[Union(9, typeof(CompanionSettingsMessage))]
	public interface ICompanionMessage
	{
	}
}

BepInEx/plugins/SOTFEdit_Companion/SOTFEdit_Companion.dll

Decompiled 9 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using Endnight.Utilities;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Concurrent;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.IO;
using MessagePack;
using Microsoft.CodeAnalysis;
using Pathfinding;
using SOTFEdit.Companion.Shared;
using SOTFEdit.Companion.Shared.Messages;
using SOTFEdit_Companion.Behaviors;
using SOTFEdit_Companion.Connection;
using SOTFEdit_Companion.Dialogs;
using SOTFEdit_Companion.Infrastructure;
using SOTFEdit_Companion.Models;
using SOTFEdit_Companion.NetworkPlayer;
using Sons.Ai.Vail;
using Sons.Areas;
using Sons.Gui;
using Sons.Input;
using Sons.Multiplayer.Client;
using TheForest.Utils;
using UnityEngine;
using UnityEngine.Networking;
using WatsonWebsocket;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SOTFEdit_Companion")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("SOTFEdit Companion")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+5b186d9fee3ead6ec9d857c8ae16fba8e01b5e4e")]
[assembly: AssemblyProduct("SOTFEdit_Companion")]
[assembly: AssemblyTitle("SOTFEdit_Companion")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SOTFEdit_Companion
{
	public static class CompanionPoiStorage
	{
		private static List<CompanionPoiMessage> _companionPois = new List<CompanionPoiMessage>();

		private static List<CompanionPoiMessage> _filteredPois = new List<CompanionPoiMessage>();

		private static PoiGroupType? _currentType;

		private static string _lastFilter;

		public static void Replace(PoiGroupType poiGroupType, IEnumerable<CompanionPoiMessage> newPois)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			_currentType = poiGroupType;
			List<CompanionPoiMessage> list = new List<CompanionPoiMessage>();
			list.AddRange(newPois);
			_companionPois = list;
			_lastFilter = null;
		}

		public static IEnumerable<CompanionPoiMessage> GetAllFiltered(string filter)
		{
			if (filter != _lastFilter)
			{
				_filteredPois = _companionPois.Where((CompanionPoiMessage poi) => FilterDescription(filter, poi.Description) || FilterTitle(filter, poi.Title)).ToList();
			}
			return _filteredPois;
		}

		public static void Add(CompanionPoiMessage companionPoi)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (_currentType == (PoiGroupType?)1)
			{
				_companionPois.Add(companionPoi);
				_lastFilter = null;
			}
		}

		private static bool FilterTitle(string filter, string title)
		{
			return title.Contains(filter, StringComparison.InvariantCultureIgnoreCase);
		}

		private static bool FilterDescription(string filter, string description)
		{
			return description?.Contains(filter, StringComparison.InvariantCultureIgnoreCase) ?? false;
		}
	}
	[BepInPlugin("SOTFEdit_Companion", "SOTFEdit_Companion", "1.0.0")]
	public class SotfEditCompanionPlugin : BasePlugin
	{
		public static readonly ManualLogSource Logger = new ManualLogSource("SotfEditCompanionPlugin");

		public override void Load()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_006c: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			Logger.Sources.Add((ILogSource)(object)Logger);
			ClassInjector.RegisterTypeInIl2Cpp<UnityMainThreadDispatcher>();
			ClassInjector.RegisterTypeInIl2Cpp<AddCoordsDialog>();
			ClassInjector.RegisterTypeInIl2Cpp<ShowCoordsDialog>();
			ClassInjector.RegisterTypeInIl2Cpp<SotfEditPlayerHandler>();
			ClassInjector.RegisterTypeInIl2Cpp<SotfEditFollowerHandler>();
			ClassInjector.RegisterTypeInIl2Cpp<SotfEditCompanionGameObject>();
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("SOTFEdit_Companion");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
			}
			Logger.LogInfo(val);
			GameObject val2 = new GameObject("SOTFEdit_Companion")
			{
				hideFlags = (HideFlags)61
			};
			val2.AddComponent<SotfEditCompanionGameObject>();
			Object.DontDestroyOnLoad((Object)val2);
		}
	}
	public static class SotfEditPluginInfo
	{
		public const string PluginGuid = "SOTFEdit_Companion";

		public const string PluginName = "SOTFEdit_Companion";

		public const string PluginVersion = "1.0.0";
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "SOTFEdit_Companion";

		public const string PLUGIN_NAME = "SOTFEdit_Companion";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}
namespace SOTFEdit_Companion.NetworkPlayer
{
	public class NetworkPlayerHandler
	{
		private readonly PlayerLocation _location;

		private CoopPlayerRemoteSetup _remoteSetup;

		public string Name { get; private set; }

		public int InstanceId { get; }

		public Vector3? LastPosition { get; private set; }

		public int LastMask { get; private set; }

		public float LastRotation { get; private set; }

		public NetworkPlayerHandler(PlayerLocation location)
		{
			InstanceId = ((Object)location).GetInstanceID();
			RefreshName((Component)(object)location);
			_location = location;
		}

		private void RefreshName(Component location)
		{
			_remoteSetup = location.gameObject.GetComponent<CoopPlayerRemoteSetup>();
			Name = (((Object)(object)_remoteSetup == (Object)null) ? null : _remoteSetup._cachedPlayerName);
		}

		public bool IsValid()
		{
			return BehaviourUtils.IsValid((Behaviour)(object)_location);
		}

		public void Refresh()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (BehaviourUtils.IsValid((Behaviour)(object)_location))
			{
				Transform transform = ((Component)_location).transform;
				LastPosition = transform.position;
				Quaternion rotation = transform.rotation;
				LastRotation = ((Quaternion)(ref rotation)).eulerAngles.y;
				LastMask = _location.AreaMask;
				RefreshName((Component)(object)_location);
			}
		}
	}
	public static class NetworkPlayerManager
	{
		public static readonly ConcurrentDictionary<int, NetworkPlayerHandler> NetworkPlayerHandlers = new ConcurrentDictionary<int, NetworkPlayerHandler>();

		public static bool ForceNetworkPlayerBroadcast { get; set; }

		public static void ReportNetworkPlayerLocations(List<PlayerLocation> newLocations)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Expected O, but got Unknown
			//IL_01f7: Expected O, but got Unknown
			HashSet<int> hashSet = new HashSet<int>();
			HashSet<int> hashSet2 = new HashSet<int>();
			bool flag = default(bool);
			foreach (PlayerLocation item in newLocations.Where((PlayerLocation newLocation) => NetworkPlayerHandlers.TryAdd(((Object)newLocation).GetInstanceID(), new NetworkPlayerHandler(newLocation))))
			{
				hashSet.Add(((Object)item).GetInstanceID());
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Added Network Player: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((Object)item).GetInstanceID());
				}
				SotfEditCompanionPlugin.Logger.LogInfo(val);
			}
			foreach (KeyValuePair<int, NetworkPlayerHandler> item2 in NetworkPlayerHandlers.Where((KeyValuePair<int, NetworkPlayerHandler> kvp) => !kvp.Value.IsValid()))
			{
				hashSet2.Add(item2.Key);
			}
			hashSet2.ExceptWith(newLocations.Select((PlayerLocation loc) => ((Object)loc).GetInstanceID()));
			foreach (int item3 in hashSet2)
			{
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Removed Network Player");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item3);
				}
				SotfEditCompanionPlugin.Logger.LogInfo(val);
				NetworkPlayerHandlers.Remove(item3, out var _);
			}
			if (ForceNetworkPlayerBroadcast)
			{
				ForceNetworkPlayerBroadcast = false;
				SotfEditCompanionPlugin.Logger.LogInfo((object)"Forced Network Player Broadcast");
				ConnectionHandler.Instance.BroadcastAsync(MessagePackSerializer.Serialize<ICompanionMessage>((ICompanionMessage)new CompanionNetworkPlayerUpdateMessage
				{
					Added = NetworkPlayerHandlers.Select((KeyValuePair<int, NetworkPlayerHandler> handler) => handler.Key).ToHashSet()
				}, (MessagePackSerializerOptions)null, default(CancellationToken)));
			}
			else if (hashSet.Count > 0 || hashSet2.Count > 0)
			{
				ConnectionHandler.Instance.BroadcastAsync(MessagePackSerializer.Serialize<ICompanionMessage>((ICompanionMessage)new CompanionNetworkPlayerUpdateMessage
				{
					Added = hashSet,
					Deleted = hashSet2
				}, (MessagePackSerializerOptions)null, default(CancellationToken)));
			}
		}
	}
}
namespace SOTFEdit_Companion.Models
{
	public static class Configuration
	{
		private static readonly ConfigFile ConfigFile;

		public static ConfigEntry<int> ListenPort { get; }

		public static ConfigEntry<string> ListenAddress { get; }

		public static ConfigEntry<KeyCode> TeleportKey { get; }

		public static ConfigEntry<KeyCode> CustomPoiKey { get; }

		static Configuration()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			ConfigFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "SOTFEdit_Companion.cfg"), true);
			ListenAddress = ConfigFile.Bind<string>("TCP", "ListenAddress", "127.0.0.1", "Local Server IP or address");
			ListenPort = ConfigFile.Bind<int>("TCP", "ListenPort", 35321, "Local Server Port");
			TeleportKey = ConfigFile.Bind<KeyCode>("Hotkeys", "Teleport", (KeyCode)289, "Hotkey used to teleport to the points of interest");
			CustomPoiKey = ConfigFile.Bind<KeyCode>("Hotkeys", "CustomPoi", (KeyCode)290, "Hotkey used to create custom points of interest");
		}
	}
	public class FollowerState
	{
		public int LastMask = 1;

		public Vector3 LastPosition;

		public float LastRotation;

		public void UpdateLocation(VailActor actor)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (BehaviourUtils.IsValid((Behaviour)(object)actor))
			{
				LastPosition = actor.Position();
				Quaternion val = actor.Rotation();
				LastRotation = ((Quaternion)(ref val)).eulerAngles.y;
				LastMask = actor.GetNavGraphMask().value;
			}
		}
	}
}
namespace SOTFEdit_Companion.Infrastructure
{
	public static class Actions
	{
		public static Action TeleportPlayer(float x, float y, float z, int areaMask)
		{
			return Action.op_Implicit((Action)delegate
			{
				TeleportPlayerInternal(x, y, z, areaMask);
			});
		}

		private static void TeleportPlayerInternal(float x, float y, float z, int areaMask)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!ValidateTeleportation())
			{
				return;
			}
			LocalPlayer.TeleportTo(new Vector3(x, y, z));
			if (PlayerLocation.GetLocalPlayerAreaMask() != areaMask)
			{
				PlayerLocation.SetLocalPlayerAreaMask(areaMask);
				AreaMask val = (AreaMask)areaMask;
				if (AreaMaskExtensions.IsCaveOrBunkerArea(val))
				{
					CaveEntranceManager.OnCaveEnter(val);
				}
				else
				{
					CaveEntranceManager.OnCaveExit(val);
				}
			}
		}

		public static Action TeleportKelvin(float x, float y, float z, int areaMask, int graphMask)
		{
			return Action.op_Implicit((Action)delegate
			{
				TeleportActor(SotfEditFollowerHandler.Instance.kelvinActor, x, y, z, areaMask, graphMask);
			});
		}

		public static Action TeleportVirginia(float x, float y, float z, int areaMask, int graphMask)
		{
			return Action.op_Implicit((Action)delegate
			{
				TeleportActor(SotfEditFollowerHandler.Instance.virginiaActor, x, y, z, areaMask, graphMask);
			});
		}

		private static void TeleportActor(VailActor follower, float x, float y, float z, int areaMask, int graphMask)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (!ValidateTeleportation() || !BehaviourUtils.IsValid((Behaviour)(object)follower))
			{
				if ((Object)(object)follower != (Object)null)
				{
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(51, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Actor ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(follower.UniqueId);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" can not be teleported because it is inactive");
					}
					SotfEditCompanionPlugin.Logger.LogWarning(val);
				}
				else
				{
					SotfEditCompanionPlugin.Logger.LogWarning((object)"Actor can not be teleported because it is null");
				}
			}
			else
			{
				follower.SetPositionAndRotation(new Vector3(x, y, z), follower.Rotation(), false);
				if (follower.GetNavGraphMask().value != graphMask)
				{
					follower.SetNavGraphMask(new GraphMask(graphMask));
				}
			}
		}

		private static bool ValidateTeleportation()
		{
			if (SotfEditCompanionGameObject.IsPlayerAvailable())
			{
				return true;
			}
			SotfEditCompanionPlugin.Logger.LogWarning((object)"Teleportation not possible, player is not in game");
			return false;
		}
	}
	public static class Coroutines
	{
		public static IEnumerator FindActors(SotfEditFollowerHandler followerHandler)
		{
			return CollectionExtensions.WrapToIl2Cpp(FindActorsInternal(followerHandler));
		}

		public static IEnumerator CollectAndSendPositions(SotfEditCompanionGameObject gameObject)
		{
			return CollectionExtensions.WrapToIl2Cpp(CollectAndSendPositionsInternal(gameObject));
		}

		public static IEnumerator FindPlayers(SotfEditPlayerHandler playerHandler)
		{
			return CollectionExtensions.WrapToIl2Cpp(FindPlayersInternal(playerHandler));
		}

		private static IEnumerator FindPlayersInternal(SotfEditPlayerHandler playerHandler)
		{
			bool flag = default(bool);
			while (true)
			{
				if (SotfEditCompanionGameObject.IsPlayerAvailable())
				{
					List<PlayerLocation> players = PlayerLocation._players;
					List<PlayerLocation> list = new List<PlayerLocation>();
					Enumerator<PlayerLocation> enumerator = players.GetEnumerator();
					while (enumerator.MoveNext())
					{
						PlayerLocation current = enumerator.Current;
						if (!BehaviourUtils.IsValid((Behaviour)(object)current))
						{
							BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Player ");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)current).name);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not active");
							}
							SotfEditCompanionPlugin.Logger.LogInfo(val);
						}
						else if (current.IsLocalPlayer)
						{
							if (!BehaviourUtils.IsValid((Behaviour)(object)playerHandler.playerLocation))
							{
								playerHandler.playerLocation = current;
								SotfEditCompanionPlugin.Logger.LogInfo((object)"Player found");
							}
						}
						else
						{
							list.Add(current);
						}
					}
					NetworkPlayerManager.ReportNetworkPlayerLocations(list);
				}
				yield return (object)new WaitForSeconds(5f);
			}
		}

		private static IEnumerator CollectAndSendPositionsInternal(SotfEditCompanionGameObject gameObject)
		{
			while (true)
			{
				if (!SotfEditCompanionGameObject.IsPaused() && SotfEditCompanionGameObject.IsPlayerAvailable())
				{
					SotfEditPlayerHandler playerHandler = gameObject.playerHandler;
					playerHandler.RefreshLocation();
					Vector3 lastPosition = playerHandler.lastPosition;
					List<CompanionPosMessage> list = new List<CompanionPosMessage>
					{
						new CompanionPosMessage
						{
							Target = (CharacterTarget)0,
							Mask = playerHandler.lastMask,
							Rotation = playerHandler.lastRotation,
							X = lastPosition.x,
							Y = lastPosition.y,
							Z = lastPosition.z
						}
					};
					SotfEditFollowerHandler followerHandler = gameObject.followerHandler;
					followerHandler.RefreshLocations();
					if (!followerHandler.MustFindKelvin())
					{
						FollowerState kelvinState = followerHandler.KelvinState;
						Vector3 lastPosition2 = kelvinState.LastPosition;
						list.Add(BuildFollowerCompanionPosMessage((CharacterTarget)1, kelvinState, lastPosition2));
					}
					if (!followerHandler.MustFindVirginia())
					{
						FollowerState virginiaState = followerHandler.VirginiaState;
						Vector3 lastPosition3 = virginiaState.LastPosition;
						list.Add(BuildFollowerCompanionPosMessage((CharacterTarget)2, virginiaState, lastPosition3));
					}
					list.AddRange(CollectPositionsFromNetworkPlayers());
					byte[] data = MessagePackSerializer.Serialize<ICompanionMessage>((ICompanionMessage)new CompanionPosCollectionMessage
					{
						Positions = list
					}, (MessagePackSerializerOptions)null, default(CancellationToken));
					gameObject.ConnectionHandler.BroadcastAsync(data);
				}
				yield return (object)new WaitForSeconds(gameObject.timeBetweenUpdates);
			}
		}

		private static IEnumerable<CompanionPosMessage> CollectPositionsFromNetworkPlayers()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			List<CompanionPosMessage> list = new List<CompanionPosMessage>();
			foreach (NetworkPlayerHandler value in NetworkPlayerManager.NetworkPlayerHandlers.Values)
			{
				if (value.IsValid())
				{
					value.Refresh();
					Vector3? lastPosition = value.LastPosition;
					if (lastPosition.HasValue)
					{
						Vector3 valueOrDefault = lastPosition.GetValueOrDefault();
						list.Add(new CompanionPosMessage
						{
							Target = (CharacterTarget)3,
							Mask = value.LastMask,
							Rotation = value.LastRotation,
							X = valueOrDefault.x,
							Y = valueOrDefault.y,
							Z = valueOrDefault.z,
							InstanceId = value.InstanceId,
							Name = (value.Name ?? "???")
						});
					}
				}
			}
			return list;
		}

		private static CompanionPosMessage BuildFollowerCompanionPosMessage(CharacterTarget target, FollowerState state, Vector3 lastKelvinPos)
		{
			//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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			return new CompanionPosMessage
			{
				Target = target,
				Mask = state.LastMask,
				Rotation = state.LastRotation,
				X = lastKelvinPos.x,
				Y = lastKelvinPos.y,
				Z = lastKelvinPos.z
			};
		}

		private static IEnumerator FindActorsInternal(SotfEditFollowerHandler followerHandler)
		{
			while (true)
			{
				bool num = SotfEditCompanionGameObject.IsPlayerAvailable();
				VailWorldSimulation instance = VailWorldSimulation._instance;
				if (num && (Object)(object)instance != (Object)null && !instance.IsDisabled)
				{
					if (followerHandler.MustFindKelvin())
					{
						followerHandler.kelvinActor = null;
						VailActor val = VailActorManager.FindActiveActor((VailActorTypeId)9);
						if (BehaviourUtils.IsValid((Behaviour)(object)val))
						{
							SotfEditCompanionPlugin.Logger.LogInfo((object)"Kelvin found");
							followerHandler.kelvinActor = val;
						}
					}
					if (followerHandler.MustFindVirginia())
					{
						VailActor val2 = VailActorManager.FindActiveActor((VailActorTypeId)10);
						if (BehaviourUtils.IsValid((Behaviour)(object)val2))
						{
							SotfEditCompanionPlugin.Logger.LogInfo((object)"Virginia found");
							followerHandler.virginiaActor = val2;
						}
					}
				}
				yield return (object)new WaitForSeconds(5f);
			}
		}

		public static IEnumerator WrapAction(Action action)
		{
			return CollectionExtensions.WrapToIl2Cpp(WrapActionInternal(action));
		}

		private static IEnumerator WrapActionInternal(Action action)
		{
			action.Invoke();
			yield return null;
		}

		public static IEnumerator AddPoi(string title, string description)
		{
			return CollectionExtensions.WrapToIl2Cpp(AddPoiInternal(title, description));
		}

		private static IEnumerator AddPoiInternal(string title, string description)
		{
			UiManager.SetShowHud(false);
			yield return (object)new WaitForEndOfFrame();
			Texture2D obj = ScreenCapture.CaptureScreenshotAsTexture();
			UiManager.SetShowHud(true);
			Il2CppStructArray<byte> val = ImageConversion.EncodeToJPG(obj, 90);
			SotfEditPlayerHandler instance = SotfEditPlayerHandler.Instance;
			Vector3 lastPosition = instance.lastPosition;
			byte[] data = MessagePackSerializer.Serialize<ICompanionMessage>((ICompanionMessage)new CompanionAddPoiMessage
			{
				Title = title,
				Description = description,
				Screenshot = Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)val),
				X = lastPosition.x,
				Y = lastPosition.y,
				Z = lastPosition.z,
				AreaMask = instance.lastMask
			}, (MessagePackSerializerOptions)null, default(CancellationToken));
			ConnectionHandler.Instance.BroadcastAsync(data);
		}

		public static IEnumerator LoadImage(string path, ConcurrentDictionary<string, Texture2D> imageCache)
		{
			imageCache[path] = null;
			return CollectionExtensions.WrapToIl2Cpp(LoadImageInternal(path, imageCache));
		}

		private static IEnumerator LoadImageInternal(string path, ConcurrentDictionary<string, Texture2D> imageCache)
		{
			if (string.IsNullOrEmpty(path))
			{
				yield break;
			}
			if (path.StartsWith("http") || path.StartsWith("https"))
			{
				UnityWebRequest request = UnityWebRequest.Get(path);
				yield return request.SendWebRequest();
				if ((int)request.result == 1)
				{
					Texture2D val = new Texture2D(2, 2);
					ImageConversion.LoadImage(val, request.downloadHandler.data);
					imageCache[path] = val;
				}
			}
			else
			{
				try
				{
					if (File.Exists(path))
					{
						Texture2D val2 = new Texture2D(2, 2);
						ImageConversion.LoadImage(val2, File.ReadAllBytes(path));
						imageCache[path] = val2;
					}
				}
				catch (Exception)
				{
				}
			}
			yield return null;
		}
	}
	public static class Inputs
	{
		public static void ToggleInputs(bool showDialog)
		{
			InputSystem.SetState((InputState)0, showDialog);
			Cursor.lockState = (CursorLockMode)((!showDialog) ? 1 : 0);
			Cursor.visible = showDialog;
		}
	}
}
namespace SOTFEdit_Companion.Dialogs
{
	public class AddCoordsDialog : MonoBehaviour
	{
		private const string DisclaimerText = "Please enter the title and optionally a description for the POI";

		private const string TitleText = "Title: ";

		private const string DescriptionText = "Description: ";

		private readonly Vector2 _dialogSize = new Vector2(400f, 130f);

		private string _description = "";

		private Rect _dialogRect;

		private bool _displayDialog;

		private GUIStyle _greenButtonStyle;

		private GUIStyle _labelStyle;

		private GUIStyle _redButtonStyle;

		private string _title = "";

		private void Awake()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			_dialogRect = new Rect(((float)Screen.width - _dialogSize.x) / 2f, ((float)Screen.height - _dialogSize.y) / 2f, _dialogSize.x, _dialogSize.y);
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(Configuration.CustomPoiKey.Value))
			{
				ShowDialog();
			}
		}

		private void OnGUI()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (_displayDialog)
			{
				CreateStyles();
				GUI.backgroundColor = Color.black;
				_dialogRect = GUI.Window(9998, _dialogRect, WindowFunction.op_Implicit((Action<int>)DialogWindow), "Add a POI");
			}
		}

		private void CreateStyles()
		{
			//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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			if (_labelStyle == null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label);
				val.normal.textColor = Color.white;
				_labelStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.button);
				val2.normal.textColor = Color.white;
				GUIStyle val3 = val2;
				GUIStyle val4 = new GUIStyle(val3);
				val4.normal.background = MakeTex(2, 2, Color.green);
				_greenButtonStyle = val4;
				GUIStyle val5 = new GUIStyle(val3);
				val5.normal.background = MakeTex(2, 2, Color.red);
				_redButtonStyle = val5;
			}
		}

		public void DialogWindow(int windowID)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.TextField("Please enter the title and optionally a description for the POI", _labelStyle, Array.Empty<GUILayoutOption>());
			_title = CreateTextField("Title: ", _title);
			_description = CreateTextField("Description: ", _description);
			GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
			if (GUILayout.Button("OK", _greenButtonStyle, (Il2CppReferenceArray<GUILayoutOption>)null))
			{
				string title = _title;
				string description = _description;
				CloseDialog();
				UnityMainThreadDispatcher.Enqueue(Coroutines.AddPoi(title, description));
			}
			if (GUILayout.Button("Cancel", _redButtonStyle, (Il2CppReferenceArray<GUILayoutOption>)null))
			{
				CloseDialog();
			}
			GUILayout.EndHorizontal();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
		}

		private string CreateTextField(string label, string value)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
			GUILayout.Label(label, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(_labelStyle.CalcSize(new GUIContent(label)).x) });
			value = GUILayout.TextField(value, (Il2CppReferenceArray<GUILayoutOption>)null);
			GUILayout.EndHorizontal();
			return value;
		}

		private void CloseDialog()
		{
			_title = "";
			_description = "";
			_displayDialog = false;
			Inputs.ToggleInputs(showDialog: false);
		}

		private static Texture2D MakeTex(int width, int height, Color col)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = col;
			}
			Texture2D val = new Texture2D(width, height);
			val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
			val.Apply();
			return val;
		}

		private void ShowDialog()
		{
			if ((_displayDialog || (SotfEditCompanionGameObject.IsPlayerAvailable() && !SotfEditCompanionGameObject.IsPaused() && !SotfEditCompanionGameObject.IsInInventory())) && ConnectionHandler.Instance.HasConnections)
			{
				_displayDialog = !_displayDialog;
				Inputs.ToggleInputs(_displayDialog);
			}
		}
	}
	public class ShowCoordsDialog : MonoBehaviour
	{
		private static readonly PoiGroupType[] SupportedPoiGroupTypes = PoiGroupTypeUtils.GetSupportedCompanionPoiGroupTypes();

		private readonly Vector2 _dialogSize = new Vector2(600f, 800f);

		private readonly ConcurrentDictionary<string, Texture2D> _imageCache = new ConcurrentDictionary<string, Texture2D>();

		private GUIStyle _descriptionStyle;

		private Rect _dialogRect;

		private bool _displayDialog;

		private Vector2 _dropdownPosition;

		private string _filter = "";

		private GUIStyle _redButtonStyle;

		private Vector2 _scrollPosition;

		private bool _showDropdown;

		private GUIStyle _titleStyle;

		private void Awake()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			_dialogRect = new Rect(((float)Screen.width - _dialogSize.x) / 2f, ((float)Screen.height - _dialogSize.y) / 2f, _dialogSize.x, _dialogSize.y);
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(Configuration.TeleportKey.Value))
			{
				ShowDialog();
			}
		}

		private void OnGUI()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (_displayDialog)
			{
				CreateStyles();
				GUI.backgroundColor = Color.black;
				_dialogRect = GUI.Window(9999, _dialogRect, WindowFunction.op_Implicit((Action<int>)DialogWindow), "Custom POIs");
				if (_showDropdown)
				{
					float num = (float)SupportedPoiGroupTypes.Length * 20f;
					Rect val = default(Rect);
					((Rect)(ref val))..ctor(_dropdownPosition.x, _dropdownPosition.y, 100f, num);
					GUI.Window(9997, val, WindowFunction.op_Implicit((Action<int>)DropdownWindow), "Categories");
				}
			}
		}

		public void DialogWindow(int windowID)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
			GUILayout.Label("Filter: ", _titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			_filter = GUILayout.TextField(_filter, (Il2CppReferenceArray<GUILayoutOption>)null);
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
			if (GUILayout.Button("Categories", (Il2CppReferenceArray<GUILayoutOption>)null))
			{
				_showDropdown = !_showDropdown;
				_dropdownPosition = GUIUtility.GUIToScreenPoint(Event.current.mousePosition);
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			_scrollPosition = GUILayout.BeginScrollView(_scrollPosition, Array.Empty<GUILayoutOption>());
			Texture2D val = default(Texture2D);
			foreach (CompanionPoiMessage item in CompanionPoiStorage.GetAllFiltered(_filter))
			{
				GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
				int num = 150;
				if (!string.IsNullOrEmpty(item.ScreenshotPath))
				{
					if (_imageCache.TryGetValue(item.ScreenshotPath, ref val))
					{
						num = (int)(((Object)(object)val == (Object)null) ? 113f : (200f * ((float)((Texture)val).height / (float)((Texture)val).width)));
						GUILayout.Box((Texture)(object)val, (GUILayoutOption[])(object)new GUILayoutOption[3]
						{
							GUILayout.Width(200f),
							GUILayout.Height((float)num),
							GUILayout.ExpandHeight(false)
						});
					}
					else
					{
						((MonoBehaviour)this).StartCoroutine(Coroutines.LoadImage(item.ScreenshotPath, _imageCache));
						GUILayout.Label("Loading...", (GUILayoutOption[])(object)new GUILayoutOption[3]
						{
							GUILayout.Width(300f),
							GUILayout.Height(150f),
							GUILayout.ExpandHeight(false)
						});
					}
				}
				else
				{
					GUILayout.Box("", (GUILayoutOption[])(object)new GUILayoutOption[3]
					{
						GUILayout.Width(300f),
						GUILayout.Height(150f),
						GUILayout.ExpandHeight(false)
					});
				}
				GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.ExpandWidth(true),
					GUILayout.Height((float)num)
				});
				GUILayout.FlexibleSpace();
				GUILayout.Label(item.Title, _titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(false) });
				GUILayout.Label(item.Description ?? "", _descriptionStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.ExpandHeight(false),
					GUILayout.ExpandWidth(false)
				});
				GUILayout.FlexibleSpace();
				GUILayout.EndVertical();
				GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Height((float)num),
					GUILayout.ExpandWidth(false)
				});
				GUILayout.FlexibleSpace();
				if (GUILayout.Button("Teleport", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.ExpandWidth(false),
					GUILayout.ExpandHeight(false)
				}))
				{
					SotfEditPlayerHandler.TeleportTo(item.X, item.Y, item.Z, item.AreaMask);
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndVertical();
				GUILayout.EndHorizontal();
				GUILayout.Space(10f);
			}
			GUILayout.EndScrollView();
			GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
			if (GUILayout.Button("Cancel", _redButtonStyle, (Il2CppReferenceArray<GUILayoutOption>)null))
			{
				CloseDialog();
			}
			GUILayout.EndHorizontal();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
		}

		private void DropdownWindow(int windowID)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			PoiGroupType[] supportedPoiGroupTypes = SupportedPoiGroupTypes;
			for (int i = 0; i < supportedPoiGroupTypes.Length; i++)
			{
				PoiGroupType type = supportedPoiGroupTypes[i];
				if (GUILayout.Button(((object)(PoiGroupType)(ref type)).ToString(), (Il2CppReferenceArray<GUILayoutOption>)null))
				{
					_scrollPosition = default(Vector2);
					_filter = "";
					ConnectionHandler.Instance.SendToFirstClientAsync(MessagePackSerializer.Serialize<ICompanionMessage>((ICompanionMessage)new CompanionRequestPoiUpdateMessage
					{
						Type = type
					}, (MessagePackSerializerOptions)null, default(CancellationToken)));
					_showDropdown = false;
				}
			}
		}

		private void CreateStyles()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_002b: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			if (_redButtonStyle == null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.button);
				val.normal.textColor = Color.white;
				GUIStyle val2 = val;
				GUIStyle val3 = new GUIStyle(val2);
				val3.normal.background = MakeTex(2, 2, Color.red);
				_redButtonStyle = val3;
				_descriptionStyle = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true
				};
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true
				};
				val4.normal.textColor = Color.green;
				_titleStyle = val4;
			}
		}

		private void CloseDialog()
		{
			_showDropdown = false;
			_displayDialog = false;
			Inputs.ToggleInputs(showDialog: false);
		}

		private static Texture2D MakeTex(int width, int height, Color col)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = col;
			}
			Texture2D val = new Texture2D(width, height);
			val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
			val.Apply();
			return val;
		}

		private void ShowDialog()
		{
			if ((_displayDialog || (SotfEditCompanionGameObject.IsPlayerAvailable() && !SotfEditCompanionGameObject.IsPaused() && !SotfEditCompanionGameObject.IsInInventory())) && ConnectionHandler.Instance.HasConnections)
			{
				_displayDialog = !_displayDialog;
				Inputs.ToggleInputs(_displayDialog);
			}
		}
	}
}
namespace SOTFEdit_Companion.Connection
{
	public class ConnectionHandler
	{
		public delegate void EventHandler();

		private WatsonWsServer _server;

		public static ConnectionHandler Instance { get; private set; }

		public bool HasConnections { get; private set; }

		public event EventHandler OnNoConnectionsOpen;

		public event EventHandler OnConnected;

		public ConnectionHandler()
		{
			Instance = this;
		}

		public void Initialize()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (_server == null)
			{
				MessagePackInitializer.Initialize();
				_server = new WatsonWsServer(Configuration.ListenAddress.Value, Configuration.ListenPort.Value, false);
				_server.ClientConnected += OnClientConnected;
				_server.ClientDisconnected += OnClientDisconnected;
				_server.MessageReceived += MessageHandler.OnMessageReceived;
			}
		}

		private void OnClientDisconnected(object sender, DisconnectionEventArgs e)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Client ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((object)e.Client).ToString());
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" disconnected");
			}
			SotfEditCompanionPlugin.Logger.LogInfo(val);
			if (!_server.ListClients().Any())
			{
				HasConnections = false;
				val = new BepInExInfoLogInterpolatedStringHandler(29, 0, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("All clients have disconnected");
				}
				SotfEditCompanionPlugin.Logger.LogInfo(val);
				this.OnNoConnectionsOpen?.Invoke();
			}
		}

		private void OnClientConnected(object sender, ConnectionEventArgs e)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Client ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((object)e.Client).ToString());
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" connected");
			}
			SotfEditCompanionPlugin.Logger.LogInfo(val);
			HasConnections = true;
			this.OnConnected?.Invoke();
		}

		public void Start()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			_server.Start();
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Listening for SOTFEdit connection at ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Configuration.ListenAddress.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(":");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Configuration.ListenPort.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("...");
			}
			SotfEditCompanionPlugin.Logger.LogInfo(val);
		}

		public void Shutdown()
		{
			if (_server.IsListening)
			{
				_server.Stop();
			}
		}

		public void SendToFirstClientAsync(byte[] data)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			WatsonWsServer server = _server;
			if (server == null || !server.IsListening)
			{
				return;
			}
			ClientMetadata val = _server.ListClients().FirstOrDefault();
			if (val == null)
			{
				return;
			}
			try
			{
				_server.SendAsync(val.Guid, data, WebSocketMessageType.Binary, default(CancellationToken));
			}
			catch (Exception ex)
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(46, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("An exception occured while sending a message: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				SotfEditCompanionPlugin.Logger.LogError(val2);
			}
		}

		public void BroadcastAsync(byte[] data)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			WatsonWsServer server = _server;
			if (server == null || !server.IsListening)
			{
				return;
			}
			bool flag = default(bool);
			foreach (ClientMetadata item in _server.ListClients())
			{
				try
				{
					_server.SendAsync(item.Guid, data, WebSocketMessageType.Binary, default(CancellationToken));
				}
				catch (Exception ex)
				{
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(46, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("An exception occured while sending a message: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					SotfEditCompanionPlugin.Logger.LogError(val);
				}
			}
		}
	}
	public static class MessageHandler
	{
		public static void OnMessageReceived(object sender, MessageReceivedEventArgs e)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			try
			{
				ICompanionMessage val = MessagePackSerializer.Deserialize<ICompanionMessage>((ReadOnlyMemory<byte>)e.Data, (MessagePackSerializerOptions)null, default(CancellationToken));
				CompanionTeleportMessage val2 = (CompanionTeleportMessage)(object)((val is CompanionTeleportMessage) ? val : null);
				if (val2 == null)
				{
					CompanionPoiListMessage val3 = (CompanionPoiListMessage)(object)((val is CompanionPoiListMessage) ? val : null);
					if (val3 == null)
					{
						CompanionPoiMessage val4 = (CompanionPoiMessage)(object)((val is CompanionPoiMessage) ? val : null);
						if (val4 == null)
						{
							CompanionSettingsMessage val5 = (CompanionSettingsMessage)(object)((val is CompanionSettingsMessage) ? val : null);
							if (val5 != null)
							{
								ProcessSettings(val5);
							}
						}
						else
						{
							ProcessCompanionPoi(val4);
						}
					}
					else
					{
						ProcessCompanionPoiList(val3);
					}
				}
				else
				{
					ProcessTeleportation(val2);
				}
			}
			catch (Exception ex)
			{
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val6 = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Unable to deserialize message: ");
					((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(ex.Message);
				}
				SotfEditCompanionPlugin.Logger.LogError(val6);
			}
		}

		private static void ProcessSettings(CompanionSettingsMessage settings)
		{
			UnityMainThreadDispatcher.Enqueue(Action.op_Implicit((Action)delegate
			{
				ApplySettings(settings);
			}));
		}

		private static void ApplySettings(CompanionSettingsMessage settings)
		{
			SotfEditCompanionPlugin.Logger.LogInfo((object)"Applying settings received from SOTFEdit...");
			if (settings.PositionUpdateFrequency > 0m)
			{
				SotfEditCompanionGameObject.Instance.timeBetweenUpdates = (float)settings.PositionUpdateFrequency;
			}
		}

		private static void ProcessCompanionPoi(CompanionPoiMessage companionPoi)
		{
			CompanionPoiStorage.Add(companionPoi);
		}

		private static void ProcessCompanionPoiList(CompanionPoiListMessage poiListMessage)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			CompanionPoiStorage.Replace(poiListMessage.Type, poiListMessage.Pois);
		}

		private static void ProcessTeleportation(CompanionTeleportMessage message)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected I4, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			CharacterTarget target = message.Target;
			switch ((int)target)
			{
			case 0:
				SotfEditPlayerHandler.TeleportTo(message.X, message.Y, message.Z, message.AreaMask);
				return;
			case 1:
				SotfEditFollowerHandler.TeleportKelvinTo(message.X, message.Y, message.Z, message.AreaMask, message.GraphMask);
				return;
			case 2:
				SotfEditFollowerHandler.TeleportVirginiaTo(message.X, message.Y, message.Z, message.AreaMask, message.GraphMask);
				return;
			}
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Unsupported teleportation target: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<CharacterTarget>(message.Target);
			}
			SotfEditCompanionPlugin.Logger.LogWarning(val);
		}
	}
}
namespace SOTFEdit_Companion.Behaviors
{
	public static class BehaviourUtils
	{
		public static bool IsValid(Behaviour behaviour)
		{
			if (Object.op_Implicit((Object)(object)behaviour))
			{
				return behaviour.isActiveAndEnabled;
			}
			return false;
		}
	}
	public class SotfEditCompanionGameObject : MonoBehaviour
	{
		public SotfEditPlayerHandler playerHandler;

		public SotfEditFollowerHandler followerHandler;

		public float timeBetweenUpdates = 0.1f;

		private readonly IEnumerator _collector;

		private bool _hasConnections;

		public ConnectionHandler ConnectionHandler;

		public static SotfEditCompanionGameObject Instance { get; private set; }

		public SotfEditCompanionGameObject()
		{
			Instance = this;
			_collector = Coroutines.CollectAndSendPositions(this);
		}

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			((Component)this).gameObject.AddComponent<UnityMainThreadDispatcher>();
			playerHandler = ((Component)this).gameObject.AddComponent<SotfEditPlayerHandler>();
			followerHandler = ((Component)this).gameObject.AddComponent<SotfEditFollowerHandler>();
			((Component)this).gameObject.AddComponent<AddCoordsDialog>();
			((Component)this).gameObject.AddComponent<ShowCoordsDialog>();
			ConnectionHandler = new ConnectionHandler();
			ConnectionHandler.Initialize();
			ConnectionHandler.OnConnected += OnConnected;
			ConnectionHandler.OnNoConnectionsOpen += OnNoConnectionsOpen;
		}

		private void Start()
		{
			ConnectionHandler.Start();
		}

		private void OnDestroy()
		{
			ConnectionHandler?.Shutdown();
			Instance = null;
		}

		private void OnNoConnectionsOpen()
		{
			UnityMainThreadDispatcher.Enqueue(Action.op_Implicit((Action)StopCollecting));
		}

		private void StopCollecting()
		{
			if (_hasConnections)
			{
				_hasConnections = false;
				((MonoBehaviour)this).StopCoroutine(_collector);
			}
			playerHandler.StopCollecting();
			followerHandler.StopCollecting();
		}

		private void OnConnected()
		{
			UnityMainThreadDispatcher.Enqueue(Action.op_Implicit((Action)StartCollecting));
			NetworkPlayerManager.ForceNetworkPlayerBroadcast = true;
		}

		private void StartCollecting()
		{
			if (!_hasConnections)
			{
				((MonoBehaviour)this).StartCoroutine(_collector);
				_hasConnections = true;
			}
			playerHandler.StartCollecting();
			followerHandler.StartCollecting();
		}

		public static bool IsPlayerAvailable()
		{
			if (IsInGame())
			{
				return BehaviourUtils.IsValid((Behaviour)(object)LocalPlayer._instance);
			}
			return false;
		}

		private static bool IsInGame()
		{
			return LocalPlayer.IsInWorld;
		}

		public static bool IsInInventory()
		{
			return LocalPlayer.IsInInventory;
		}

		public static bool IsPaused()
		{
			return PauseMenu.IsActive;
		}
	}
	public class SotfEditFollowerHandler : MonoBehaviour
	{
		public VailActor kelvinActor;

		public VailActor virginiaActor;

		private readonly IEnumerator _followerFinder;

		public readonly FollowerState KelvinState = new FollowerState();

		public readonly FollowerState VirginiaState = new FollowerState();

		public static SotfEditFollowerHandler Instance { get; private set; }

		public SotfEditFollowerHandler()
		{
			_followerFinder = Coroutines.FindActors(this);
		}

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			StopCollecting();
			Instance = null;
		}

		public void RefreshLocations()
		{
			if (!MustFindKelvin())
			{
				KelvinState.UpdateLocation(kelvinActor);
			}
			if (!MustFindVirginia())
			{
				VirginiaState.UpdateLocation(virginiaActor);
			}
		}

		public bool MustFindKelvin()
		{
			return !BehaviourUtils.IsValid((Behaviour)(object)kelvinActor);
		}

		public bool MustFindVirginia()
		{
			return !BehaviourUtils.IsValid((Behaviour)(object)virginiaActor);
		}

		public void StopCollecting()
		{
			((MonoBehaviour)this).StopCoroutine(_followerFinder);
		}

		public void StartCollecting()
		{
			((MonoBehaviour)this).StartCoroutine(_followerFinder);
		}

		public static void TeleportKelvinTo(float x, float y, float z, int areaMask, int graphMask)
		{
			UnityMainThreadDispatcher.Enqueue(Actions.TeleportKelvin(x, y, z, areaMask, graphMask));
		}

		public static void TeleportVirginiaTo(float x, float y, float z, int areaMask, int graphMask)
		{
			UnityMainThreadDispatcher.Enqueue(Actions.TeleportVirginia(x, y, z, areaMask, graphMask));
		}
	}
	public class SotfEditPlayerHandler : MonoBehaviour
	{
		public Vector3 lastPosition;

		public int lastMask;

		public PlayerLocation playerLocation;

		public float lastRotation;

		private readonly IEnumerator _playerFinder;

		public static SotfEditPlayerHandler Instance { get; private set; }

		public SotfEditPlayerHandler()
		{
			_playerFinder = Coroutines.FindPlayers(this);
		}

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
		}

		private void OnDestroy()
		{
			StopCollecting();
			Instance = null;
		}

		public void RefreshLocation()
		{
			//IL_0023: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (SotfEditCompanionGameObject.IsPlayerAvailable() && BehaviourUtils.IsValid((Behaviour)(object)playerLocation))
			{
				Transform transform = ((Component)playerLocation).transform;
				lastPosition = transform.position;
				Quaternion rotation = transform.rotation;
				lastRotation = ((Quaternion)(ref rotation)).eulerAngles.y;
				lastMask = playerLocation.AreaMask;
			}
		}

		public void StopCollecting()
		{
			((MonoBehaviour)this).StopCoroutine(_playerFinder);
		}

		public void StartCollecting()
		{
			((MonoBehaviour)this).StartCoroutine(_playerFinder);
		}

		public static void TeleportTo(float x, float y, float z, int areaMask)
		{
			UnityMainThreadDispatcher.Enqueue(Actions.TeleportPlayer(x, y, z, areaMask));
		}
	}
	public class UnityMainThreadDispatcher : MonoBehaviour
	{
		private static readonly Queue<IEnumerator> ExecutionQueue = new Queue<IEnumerator>();

		public void Update()
		{
			lock (ExecutionQueue)
			{
				while (ExecutionQueue.Count > 0)
				{
					((MonoBehaviour)this).StartCoroutine(ExecutionQueue.Dequeue());
				}
			}
		}

		public static void Enqueue(IEnumerator action)
		{
			lock (ExecutionQueue)
			{
				ExecutionQueue.Enqueue(action);
			}
		}

		public static void Enqueue(Action action)
		{
			Enqueue(Coroutines.WrapAction(action));
		}
	}
}

BepInEx/plugins/SOTFEdit_Companion/WatsonWebsocket.dll

Decompiled 9 months ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Joel Christner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("(c)2023 Joel Christner")]
[assembly: AssemblyDescription("WatsonWebsocket is the EASIEST and FASTEST way to build client and server applications that rely on messaging using websockets.  It's.  Really.  Easy.")]
[assembly: AssemblyFileVersion("4.0.9.0")]
[assembly: AssemblyInformationalVersion("4.0.9")]
[assembly: AssemblyProduct("WatsonWebsocket")]
[assembly: AssemblyTitle("WatsonWebsocket")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/jchristn/WatsonWebsocket")]
[assembly: AssemblyVersion("4.0.9.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace WatsonWebsocket
{
	public class ClientMetadata
	{
		internal HttpListenerContext HttpContext;

		internal WebSocket Ws;

		internal WebSocketContext WsContext;

		internal readonly CancellationTokenSource TokenSource;

		internal readonly SemaphoreSlim SendLock = new SemaphoreSlim(1);

		public Guid Guid { get; } = Guid.NewGuid();


		public string IpPort => Ip + ":" + Port;

		public string Ip { get; }

		public int Port { get; }

		public string Name { get; set; }

		public object Metadata { get; set; }

		public ClientMetadata(HttpListenerContext httpContext, WebSocket ws, WebSocketContext wsContext, CancellationTokenSource tokenSource)
		{
			HttpContext = httpContext ?? throw new ArgumentNullException("httpContext");
			Ws = ws ?? throw new ArgumentNullException("ws");
			WsContext = wsContext ?? throw new ArgumentNullException("wsContext");
			TokenSource = tokenSource ?? throw new ArgumentNullException("tokenSource");
			Ip = HttpContext.Request.RemoteEndPoint.Address.ToString();
			Port = HttpContext.Request.RemoteEndPoint.Port;
		}

		public override string ToString()
		{
			string text = "[";
			text = text + Guid.ToString() + "|" + IpPort;
			if (!string.IsNullOrEmpty(Name))
			{
				text = text + "|" + Name;
			}
			return text + "]";
		}
	}
	public class ConnectionEventArgs : EventArgs
	{
		public ClientMetadata Client { get; }

		public HttpListenerRequest HttpRequest { get; }

		internal ConnectionEventArgs(ClientMetadata client, HttpListenerRequest http)
		{
			Client = client;
			HttpRequest = http;
		}
	}
	public class DisconnectionEventArgs : EventArgs
	{
		public ClientMetadata Client { get; }

		internal DisconnectionEventArgs(ClientMetadata client)
		{
			Client = client;
		}
	}
	public class MessageReceivedEventArgs : EventArgs
	{
		public WebSocketMessageType MessageType = WebSocketMessageType.Binary;

		public ClientMetadata Client { get; }

		public ArraySegment<byte> Data { get; }

		internal MessageReceivedEventArgs(ClientMetadata client, ArraySegment<byte> data, WebSocketMessageType messageType)
		{
			Client = client;
			Data = data;
			MessageType = messageType;
		}
	}
	public class Statistics
	{
		private DateTime _StartTime = DateTime.Now.ToUniversalTime();

		private long _ReceivedBytes;

		private long _ReceivedMessages;

		private long _SentBytes;

		private long _SentMessages;

		public DateTime StartTime => _StartTime;

		public TimeSpan UpTime => DateTime.Now.ToUniversalTime() - _StartTime;

		public long ReceivedBytes => _ReceivedBytes;

		public long ReceivedMessages => _ReceivedMessages;

		public int ReceivedMessageSizeAverage
		{
			get
			{
				if (_ReceivedBytes > 0 && _ReceivedMessages > 0)
				{
					return (int)(_ReceivedBytes / _ReceivedMessages);
				}
				return 0;
			}
		}

		public long SentBytes => _SentBytes;

		public long SentMessages => _SentMessages;

		public decimal SentMessageSizeAverage
		{
			get
			{
				if (_SentBytes > 0 && _SentMessages > 0)
				{
					return (int)(_SentBytes / _SentMessages);
				}
				return 0m;
			}
		}

		public override string ToString()
		{
			return "--- Statistics ---" + Environment.NewLine + "    Started     : " + _StartTime.ToString() + Environment.NewLine + "    Uptime      : " + UpTime.ToString() + Environment.NewLine + "    Received    : " + Environment.NewLine + "       Bytes    : " + ReceivedBytes + Environment.NewLine + "       Messages : " + ReceivedMessages + Environment.NewLine + "       Average  : " + ReceivedMessageSizeAverage + " bytes" + Environment.NewLine + "    Sent        : " + Environment.NewLine + "       Bytes    : " + SentBytes + Environment.NewLine + "       Messages : " + SentMessages + Environment.NewLine + "       Average  : " + SentMessageSizeAverage + " bytes" + Environment.NewLine;
		}

		public void Reset()
		{
			_ReceivedBytes = 0L;
			_ReceivedMessages = 0L;
			_SentBytes = 0L;
			_SentMessages = 0L;
		}

		internal void IncrementReceivedMessages()
		{
			_ReceivedMessages = Interlocked.Increment(ref _ReceivedMessages);
		}

		internal void IncrementSentMessages()
		{
			_SentMessages = Interlocked.Increment(ref _SentMessages);
		}

		internal void AddReceivedBytes(long bytes)
		{
			_ReceivedBytes = Interlocked.Add(ref _ReceivedBytes, bytes);
		}

		internal void AddSentBytes(long bytes)
		{
			_SentBytes = Interlocked.Add(ref _SentBytes, bytes);
		}
	}
	public class WatsonWsClient : IDisposable
	{
		public Action<string> Logger;

		private string _Header = "[WatsonWsClient] ";

		private bool _AcceptInvalidCertificates = true;

		private Uri _ServerUri;

		private string _ServerIp;

		private int _ServerPort;

		private string _ServerIpPort;

		private string _Url;

		private int _KeepAliveIntervalSeconds = 30;

		private ClientWebSocket _ClientWs;

		private CookieContainer _Cookies = new CookieContainer();

		private Action<ClientWebSocketOptions> _PreConfigureOptions;

		private readonly SemaphoreSlim _SendLock = new SemaphoreSlim(1);

		private readonly SemaphoreSlim _AwaitingSyncResposeLock = new SemaphoreSlim(1);

		private CancellationTokenSource _TokenSource = new CancellationTokenSource();

		private CancellationToken _Token;

		private Statistics _Stats = new Statistics();

		private readonly bool _IsBrowser = RuntimeInformation.RuntimeIdentifier == "browser-wasm";

		public bool AcceptInvalidCertificates
		{
			get
			{
				return _AcceptInvalidCertificates;
			}
			set
			{
				_AcceptInvalidCertificates = value;
			}
		}

		public bool Connected
		{
			get
			{
				if (_ClientWs != null && _ClientWs.State == WebSocketState.Open)
				{
					return true;
				}
				return false;
			}
		}

		public bool EnableStatistics { get; set; } = true;


		[UnsupportedOSPlatform("browser")]
		public int KeepAliveInterval
		{
			get
			{
				if (_IsBrowser)
				{
					throw new PlatformNotSupportedException();
				}
				return _KeepAliveIntervalSeconds;
			}
			set
			{
				if (_IsBrowser)
				{
					throw new PlatformNotSupportedException();
				}
				if (value < 1)
				{
					throw new ArgumentException("ConnectTimeoutSeconds must be greater than zero.");
				}
				_KeepAliveIntervalSeconds = value;
			}
		}

		public Statistics Stats => _Stats;

		public event EventHandler<MessageReceivedEventArgs> MessageReceived;

		public event EventHandler ServerConnected;

		public event EventHandler ServerDisconnected;

		private event EventHandler<MessageReceivedEventArgs> _AwaitingSyncResponseEvent;

		public WatsonWsClient(string serverIp, int serverPort, bool ssl)
		{
			if (string.IsNullOrEmpty(serverIp))
			{
				throw new ArgumentNullException("serverIp");
			}
			if (serverPort < 1)
			{
				throw new ArgumentOutOfRangeException("serverPort");
			}
			_ServerIp = serverIp;
			_ServerPort = serverPort;
			_ServerIpPort = serverIp + ":" + serverPort;
			if (ssl)
			{
				_Url = "wss://" + _ServerIp + ":" + _ServerPort;
			}
			else
			{
				_Url = "ws://" + _ServerIp + ":" + _ServerPort;
			}
			_ServerUri = new Uri(_Url);
			_Token = _TokenSource.Token;
			_ClientWs = new ClientWebSocket();
		}

		public WatsonWsClient(Uri uri)
		{
			_ServerUri = uri;
			_ServerIp = uri.Host;
			_ServerPort = uri.Port;
			_ServerIpPort = uri.Host + ":" + uri.Port;
			_Token = _TokenSource.Token;
			_ClientWs = new ClientWebSocket();
		}

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

		[UnsupportedOSPlatform("browser")]
		public WatsonWsClient ConfigureOptions(Action<ClientWebSocketOptions> options)
		{
			if (_IsBrowser)
			{
				throw new PlatformNotSupportedException();
			}
			if (!Connected)
			{
				_PreConfigureOptions = options;
			}
			return this;
		}

		[UnsupportedOSPlatform("browser")]
		public void AddCookie(Cookie cookie)
		{
			if (_IsBrowser)
			{
				throw new PlatformNotSupportedException();
			}
			_Cookies.Add(cookie);
		}

		public void Start()
		{
			_Stats = new Statistics();
			if (_AcceptInvalidCertificates)
			{
				SetInvalidCertificateAcceptance();
			}
			if (!_IsBrowser)
			{
				_ClientWs.Options.Cookies = _Cookies;
				_ClientWs.Options.KeepAliveInterval = TimeSpan.FromSeconds(_KeepAliveIntervalSeconds);
				if (_PreConfigureOptions != null)
				{
					_PreConfigureOptions(_ClientWs.Options);
				}
			}
			_ClientWs.ConnectAsync(_ServerUri, _Token).ContinueWith(AfterConnect).Wait();
		}

		public Task StartAsync()
		{
			_Stats = new Statistics();
			if (_AcceptInvalidCertificates)
			{
				SetInvalidCertificateAcceptance();
			}
			if (!_IsBrowser)
			{
				_ClientWs.Options.Cookies = _Cookies;
				_ClientWs.Options.KeepAliveInterval = TimeSpan.FromSeconds(_KeepAliveIntervalSeconds);
				if (_PreConfigureOptions != null)
				{
					_PreConfigureOptions(_ClientWs.Options);
				}
			}
			return _ClientWs.ConnectAsync(_ServerUri, _Token).ContinueWith(AfterConnect);
		}

		public bool StartWithTimeout(int timeout = 30, CancellationToken token = default(CancellationToken))
		{
			if (timeout < 1)
			{
				throw new ArgumentException("Timeout must be greater than zero seconds.");
			}
			_Stats = new Statistics();
			if (_AcceptInvalidCertificates)
			{
				SetInvalidCertificateAcceptance();
			}
			Stopwatch stopwatch = new Stopwatch();
			TimeSpan timeSpan = TimeSpan.FromSeconds(timeout);
			stopwatch.Start();
			try
			{
				while (stopwatch.Elapsed < timeSpan && !token.IsCancellationRequested)
				{
					_ClientWs = new ClientWebSocket();
					if (!_IsBrowser)
					{
						_ClientWs.Options.Cookies = _Cookies;
						_ClientWs.Options.KeepAliveInterval = TimeSpan.FromSeconds(_KeepAliveIntervalSeconds);
						if (_PreConfigureOptions != null)
						{
							_PreConfigureOptions(_ClientWs.Options);
						}
					}
					try
					{
						_ClientWs.ConnectAsync(_ServerUri, token).ContinueWith(AfterConnect).Wait();
					}
					catch (TaskCanceledException)
					{
						return false;
					}
					catch (OperationCanceledException)
					{
						return false;
					}
					catch (WebSocketException)
					{
					}
					Task.Delay(100).Wait();
					if (_ClientWs.State == WebSocketState.Open)
					{
						return true;
					}
				}
			}
			catch (TaskCanceledException)
			{
			}
			catch (OperationCanceledException)
			{
			}
			return false;
		}

		public async Task<bool> StartWithTimeoutAsync(int timeout = 30, CancellationToken token = default(CancellationToken))
		{
			if (timeout < 1)
			{
				throw new ArgumentException("Timeout must be greater than zero seconds.");
			}
			_Stats = new Statistics();
			if (_AcceptInvalidCertificates)
			{
				SetInvalidCertificateAcceptance();
			}
			Stopwatch sw = new Stopwatch();
			TimeSpan timeOut = TimeSpan.FromSeconds(timeout);
			sw.Start();
			try
			{
				while (sw.Elapsed < timeOut && !token.IsCancellationRequested)
				{
					_ClientWs = new ClientWebSocket();
					if (!_IsBrowser)
					{
						_ClientWs.Options.Cookies = _Cookies;
						_ClientWs.Options.KeepAliveInterval = TimeSpan.FromSeconds(_KeepAliveIntervalSeconds);
						if (_PreConfigureOptions != null)
						{
							_PreConfigureOptions(_ClientWs.Options);
						}
					}
					try
					{
						await _ClientWs.ConnectAsync(_ServerUri, token).ContinueWith(AfterConnect);
					}
					catch (TaskCanceledException)
					{
						return false;
					}
					catch (OperationCanceledException)
					{
						return false;
					}
					catch (WebSocketException)
					{
					}
					await Task.Delay(100);
					if (_ClientWs.State == WebSocketState.Open)
					{
						return true;
					}
				}
			}
			catch (TaskCanceledException)
			{
			}
			catch (OperationCanceledException)
			{
			}
			return false;
		}

		public void Stop()
		{
			Stop(WebSocketCloseStatus.NormalClosure, _ClientWs.CloseStatusDescription);
		}

		public async Task StopAsync()
		{
			await StopAsync(WebSocketCloseStatus.NormalClosure, _ClientWs.CloseStatusDescription);
		}

		public void Stop(WebSocketCloseStatus closeCode, string reason)
		{
			_ClientWs.CloseOutputAsync(closeCode, reason, _Token).Wait();
		}

		public async Task StopAsync(WebSocketCloseStatus closeCode, string reason)
		{
			await _ClientWs.CloseOutputAsync(closeCode, reason, _Token).ConfigureAwait(continueOnCapturedContext: false);
		}

		public async Task<bool> SendAsync(string data, WebSocketMessageType msgType = WebSocketMessageType.Text, CancellationToken token = default(CancellationToken))
		{
			if (string.IsNullOrEmpty(data))
			{
				throw new ArgumentNullException("data");
			}
			return await MessageWriteAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(data)), msgType, token);
		}

		public async Task<bool> SendAsync(byte[] data, WebSocketMessageType msgType = WebSocketMessageType.Binary, CancellationToken token = default(CancellationToken))
		{
			return await MessageWriteAsync(new ArraySegment<byte>(data), msgType, token);
		}

		public async Task<bool> SendAsync(ArraySegment<byte> data, WebSocketMessageType msgType = WebSocketMessageType.Binary, CancellationToken token = default(CancellationToken))
		{
			if (data.Array == null || data.Count < 1)
			{
				throw new ArgumentNullException("data");
			}
			return await MessageWriteAsync(data, msgType, token);
		}

		public async Task<string> SendAndWaitAsync(string data, int timeout = 30, CancellationToken token = default(CancellationToken))
		{
			if (string.IsNullOrEmpty(data))
			{
				throw new ArgumentNullException("data");
			}
			if (timeout < 1)
			{
				throw new ArgumentException("Timeout must be greater than zero seconds.", "data");
			}
			string result = null;
			ManualResetEvent receivedEvent = new ManualResetEvent(initialState: false);
			await _AwaitingSyncResposeLock.WaitAsync(_Token);
			await Task.Run(async delegate
			{
				_AwaitingSyncResponseEvent += delegate(object? s, MessageReceivedEventArgs e)
				{
					result = Encoding.UTF8.GetString(e.Data.Array, 0, e.Data.Count);
					receivedEvent.Set();
				};
				await MessageWriteAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(data)), WebSocketMessageType.Text, token);
				receivedEvent.WaitOne(TimeSpan.FromSeconds(timeout));
				this._AwaitingSyncResponseEvent = null;
				_AwaitingSyncResposeLock.Release();
			});
			return result;
		}

		public async Task<ArraySegment<byte>> SendAndWaitAsync(byte[] data, int timeout = 30, CancellationToken token = default(CancellationToken))
		{
			return await SendAndWaitAsync(new ArraySegment<byte>(data), timeout, token);
		}

		public async Task<ArraySegment<byte>> SendAndWaitAsync(ArraySegment<byte> data, int timeout = 30, CancellationToken token = default(CancellationToken))
		{
			if (data.Array == null || data.Count < 1)
			{
				throw new ArgumentNullException("data");
			}
			if (timeout < 1)
			{
				throw new ArgumentException("Timeout must be zero or greater.", "data");
			}
			ArraySegment<byte> result = default(ArraySegment<byte>);
			ManualResetEvent receivedEvent = new ManualResetEvent(initialState: false);
			await _AwaitingSyncResposeLock.WaitAsync(_Token);
			await Task.Run(async delegate
			{
				_AwaitingSyncResponseEvent += delegate(object? s, MessageReceivedEventArgs e)
				{
					result = e.Data;
					receivedEvent.Set();
				};
				await MessageWriteAsync(data, WebSocketMessageType.Binary, token);
				receivedEvent.WaitOne(TimeSpan.FromSeconds(timeout));
				this._AwaitingSyncResponseEvent = null;
				_AwaitingSyncResposeLock.Release();
			});
			return result;
		}

		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (_ClientWs != null && _ClientWs.State == WebSocketState.Open)
				{
					Stop();
					_ClientWs.Dispose();
				}
				_TokenSource.Cancel();
				Logger?.Invoke(_Header + "dispose complete");
			}
		}

		private void SetInvalidCertificateAcceptance()
		{
			if (_ClientWs.State == WebSocketState.Open)
			{
				ClientWebSocketOptions options = _ClientWs.Options;
				options.RemoteCertificateValidationCallback = (RemoteCertificateValidationCallback)Delegate.Combine(options.RemoteCertificateValidationCallback, (RemoteCertificateValidationCallback)((object message, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) => true));
			}
		}

		private void AfterConnect(Task task)
		{
			if (!task.IsCompleted || _ClientWs.State != WebSocketState.Open)
			{
				return;
			}
			Task.Run(delegate
			{
				Task.Run(() => DataReceiver(), _Token);
				this.ServerConnected?.Invoke(this, EventArgs.Empty);
			}, _Token);
		}

		private async Task DataReceiver()
		{
			byte[] buffer = new byte[65536];
			try
			{
				while (!_Token.IsCancellationRequested)
				{
					MessageReceivedEventArgs messageReceivedEventArgs = await MessageReadAsync(buffer);
					if (messageReceivedEventArgs == null)
					{
						continue;
					}
					if (EnableStatistics)
					{
						_Stats.IncrementReceivedMessages();
						_Stats.AddReceivedBytes(messageReceivedEventArgs.Data.Count);
					}
					if (messageReceivedEventArgs.MessageType != WebSocketMessageType.Close)
					{
						if (this._AwaitingSyncResponseEvent != null)
						{
							this._AwaitingSyncResponseEvent?.Invoke(this, messageReceivedEventArgs);
						}
						else
						{
							this.MessageReceived?.Invoke(this, messageReceivedEventArgs);
						}
					}
				}
			}
			catch (OperationCanceledException)
			{
				Logger?.Invoke(_Header + "data receiver canceled");
			}
			catch (WebSocketException)
			{
				Logger?.Invoke(_Header + "websocket disconnected");
			}
			catch (Exception ex3)
			{
				Logger?.Invoke(_Header + "exception: " + Environment.NewLine + ex3.ToString());
			}
			this.ServerDisconnected?.Invoke(this, EventArgs.Empty);
		}

		private async Task<MessageReceivedEventArgs> MessageReadAsync(byte[] buffer)
		{
			if (_ClientWs == null)
			{
				return null;
			}
			ArraySegment<byte> data = default(ArraySegment<byte>);
			WebSocketReceiveResult result = null;
			using (MemoryStream dataMs = new MemoryStream())
			{
				buffer = new byte[buffer.Length];
				ArraySegment<byte> bufferSegment = new ArraySegment<byte>(buffer);
				if (_ClientWs.State == WebSocketState.CloseReceived || _ClientWs.State == WebSocketState.Closed)
				{
					throw new WebSocketException("Websocket close received");
				}
				while (_ClientWs.State == WebSocketState.Open)
				{
					result = await _ClientWs.ReceiveAsync(bufferSegment, _Token);
					if (result.Count > 0)
					{
						await dataMs.WriteAsync(buffer, 0, result.Count);
					}
					if (result.EndOfMessage)
					{
						data = new ArraySegment<byte>(dataMs.GetBuffer(), 0, (int)dataMs.Length);
						break;
					}
				}
			}
			return new MessageReceivedEventArgs(null, data, result.MessageType);
		}

		private async Task<bool> MessageWriteAsync(ArraySegment<byte> data, WebSocketMessageType msgType, CancellationToken token)
		{
			bool disconnectDetected = false;
			using (CancellationTokenSource.CreateLinkedTokenSource(_Token, token))
			{
				_ = 1;
				try
				{
					if (_ClientWs == null || _ClientWs.State != WebSocketState.Open)
					{
						Logger?.Invoke(_Header + "not connected");
						disconnectDetected = true;
						return false;
					}
					await _SendLock.WaitAsync(_Token).ConfigureAwait(continueOnCapturedContext: false);
					try
					{
						await _ClientWs.SendAsync(data, msgType, endOfMessage: true, token).ConfigureAwait(continueOnCapturedContext: false);
					}
					catch
					{
					}
					finally
					{
						_SendLock.Release();
					}
					if (EnableStatistics)
					{
						_Stats.IncrementSentMessages();
						_Stats.AddSentBytes(data.Count);
					}
					return true;
				}
				catch (TaskCanceledException)
				{
					if (_Token.IsCancellationRequested)
					{
						Logger?.Invoke(_Header + "canceled");
						disconnectDetected = true;
					}
					else if (token.IsCancellationRequested)
					{
						Logger?.Invoke(_Header + "message send canceled");
					}
					return false;
				}
				catch (OperationCanceledException)
				{
					if (_Token.IsCancellationRequested)
					{
						Logger?.Invoke(_Header + "canceled");
						disconnectDetected = true;
					}
					else if (token.IsCancellationRequested)
					{
						Logger?.Invoke(_Header + "message send canceled");
					}
					return false;
				}
				catch (WebSocketException)
				{
					Logger?.Invoke(_Header + "websocket disconnected");
					disconnectDetected = true;
					return false;
				}
				catch (ObjectDisposedException)
				{
					Logger?.Invoke(_Header + "disposed");
					disconnectDetected = true;
					return false;
				}
				catch (SocketException)
				{
					Logger?.Invoke(_Header + "socket disconnected");
					disconnectDetected = true;
					return false;
				}
				catch (InvalidOperationException)
				{
					Logger?.Invoke(_Header + "disconnected due to invalid operation");
					disconnectDetected = true;
					return false;
				}
				catch (IOException)
				{
					Logger?.Invoke(_Header + "IO disconnected");
					disconnectDetected = true;
					return false;
				}
				catch (Exception ex8)
				{
					Logger?.Invoke(_Header + "exception: " + Environment.NewLine + ex8.ToString());
					disconnectDetected = true;
					return false;
				}
				finally
				{
					if (disconnectDetected)
					{
						Dispose();
						this.ServerDisconnected?.Invoke(this, EventArgs.Empty);
					}
				}
			}
		}
	}
	public class WatsonWsServer : IDisposable
	{
		public List<string> PermittedIpAddresses = new List<string>();

		public Action<string> Logger;

		public Action<HttpListenerContext> HttpHandler;

		private string _Header = "[WatsonWsServer] ";

		private bool _AcceptInvalidCertificates = true;

		private List<string> _ListenerPrefixes = new List<string>();

		private HttpListener _Listener;

		private readonly object _PermittedIpsLock = new object();

		private ConcurrentDictionary<Guid, ClientMetadata> _Clients = new ConcurrentDictionary<Guid, ClientMetadata>();

		private CancellationTokenSource _TokenSource = new CancellationTokenSource();

		private CancellationToken _Token;

		private Task _AcceptConnectionsTask;

		private Statistics _Stats = new Statistics();

		public bool IsListening
		{
			get
			{
				if (_Listener != null)
				{
					return _Listener.IsListening;
				}
				return false;
			}
		}

		public bool EnableStatistics { get; set; } = true;


		public bool AcceptInvalidCertificates
		{
			get
			{
				return _AcceptInvalidCertificates;
			}
			set
			{
				_AcceptInvalidCertificates = value;
			}
		}

		public Statistics Stats => _Stats;

		public event EventHandler<ConnectionEventArgs> ClientConnected;

		public event EventHandler<DisconnectionEventArgs> ClientDisconnected;

		public event EventHandler ServerStopped;

		public event EventHandler<MessageReceivedEventArgs> MessageReceived;

		public WatsonWsServer(string hostname = "localhost", int port = 9000, bool ssl = false)
		{
			if (port < 0)
			{
				throw new ArgumentOutOfRangeException("port");
			}
			if (string.IsNullOrEmpty(hostname))
			{
				hostname = "localhost";
			}
			if (ssl)
			{
				_ListenerPrefixes.Add("https://" + hostname + ":" + port + "/");
			}
			else
			{
				_ListenerPrefixes.Add("http://" + hostname + ":" + port + "/");
			}
			_Listener = new HttpListener();
			foreach (string listenerPrefix in _ListenerPrefixes)
			{
				_Listener.Prefixes.Add(listenerPrefix);
			}
			_Token = _TokenSource.Token;
		}

		public WatsonWsServer(List<string> hostnames, int port, bool ssl = false)
		{
			if (port < 0)
			{
				throw new ArgumentOutOfRangeException("port");
			}
			if (hostnames == null)
			{
				throw new ArgumentNullException("hostnames");
			}
			if (hostnames.Count < 1)
			{
				throw new ArgumentException("At least one hostname must be supplied.");
			}
			foreach (string hostname in hostnames)
			{
				if (ssl)
				{
					_ListenerPrefixes.Add("https://" + hostname + ":" + port + "/");
				}
				else
				{
					_ListenerPrefixes.Add("http://" + hostname + ":" + port + "/");
				}
			}
			_Listener = new HttpListener();
			foreach (string listenerPrefix in _ListenerPrefixes)
			{
				_Listener.Prefixes.Add(listenerPrefix);
			}
			_Token = _TokenSource.Token;
		}

		public WatsonWsServer(Uri uri)
		{
			if (uri == null)
			{
				throw new ArgumentNullException("uri");
			}
			if (uri.Port < 0)
			{
				throw new ArgumentException("Port must be zero or greater.");
			}
			string host;
			if (!IPAddress.TryParse(uri.Host, out IPAddress _))
			{
				IPHostEntry hostEntry = Dns.GetHostEntry(uri.Host);
				if (hostEntry.AddressList.Length == 0)
				{
					throw new ArgumentException("Cannot resolve address to IP.");
				}
				host = hostEntry.AddressList.First().ToString();
			}
			else
			{
				host = uri.Host;
			}
			UriBuilder uriBuilder = new UriBuilder(uri)
			{
				Host = host
			};
			_ListenerPrefixes.Add(uriBuilder.ToString());
			_Listener = new HttpListener();
			foreach (string listenerPrefix in _ListenerPrefixes)
			{
				_Listener.Prefixes.Add(listenerPrefix);
			}
			_Token = _TokenSource.Token;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		public void Start()
		{
			if (IsListening)
			{
				throw new InvalidOperationException("Watson websocket server is already running.");
			}
			_Stats = new Statistics();
			string text = _Header + "starting on:";
			foreach (string listenerPrefix in _ListenerPrefixes)
			{
				text = text + " " + listenerPrefix;
			}
			Logger?.Invoke(text);
			if (_AcceptInvalidCertificates)
			{
				SetInvalidCertificateAcceptance();
			}
			_TokenSource = new CancellationTokenSource();
			_Token = _TokenSource.Token;
			_Listener.Start();
			_AcceptConnectionsTask = Task.Run(() => AcceptConnections(_Token), _Token);
		}

		public Task StartAsync(CancellationToken token = default(CancellationToken))
		{
			if (IsListening)
			{
				throw new InvalidOperationException("Watson websocket server is already running.");
			}
			_Stats = new Statistics();
			string text = _Header + "starting on:";
			foreach (string listenerPrefix in _ListenerPrefixes)
			{
				text = text + " " + listenerPrefix;
			}
			Logger?.Invoke(text);
			if (_AcceptInvalidCertificates)
			{
				SetInvalidCertificateAcceptance();
			}
			_TokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
			_Token = token;
			_Listener.Start();
			_AcceptConnectionsTask = Task.Run(() => AcceptConnections(_Token), _Token);
			return Task.Delay(1);
		}

		public void Stop()
		{
			if (!IsListening)
			{
				throw new InvalidOperationException("Watson websocket server is not running.");
			}
			Logger?.Invoke(_Header + "stopping");
			_Listener.Stop();
		}

		public Task<bool> SendAsync(Guid guid, string data, WebSocketMessageType msgType = WebSocketMessageType.Text, CancellationToken token = default(CancellationToken))
		{
			if (string.IsNullOrEmpty(data))
			{
				data = "";
			}
			return SendAsync(guid, Encoding.UTF8.GetBytes(data), msgType, token);
		}

		public Task<bool> SendAsync(Guid guid, byte[] data, WebSocketMessageType msgType = WebSocketMessageType.Binary, CancellationToken token = default(CancellationToken))
		{
			if (data == null)
			{
				data = new byte[0];
			}
			return SendAsync(guid, new ArraySegment<byte>(data), msgType, token);
		}

		public Task<bool> SendAsync(Guid guid, ArraySegment<byte> data, WebSocketMessageType msgType = WebSocketMessageType.Binary, CancellationToken token = default(CancellationToken))
		{
			if (data.Array == null || data.Count < 1)
			{
				throw new ArgumentNullException("data");
			}
			if (!_Clients.TryGetValue(guid, out var value))
			{
				Logger?.Invoke(_Header + "unable to find client " + guid);
				return Task.FromResult(result: false);
			}
			Task<bool> result = MessageWriteAsync(value, data, msgType, token);
			value = null;
			return result;
		}

		public bool IsClientConnected(Guid guid)
		{
			return _Clients.Any((KeyValuePair<Guid, ClientMetadata> c) => c.Key.Equals(guid));
		}

		public IEnumerable<ClientMetadata> ListClients()
		{
			return _Clients.Values;
		}

		public void DisconnectClient(Guid guid)
		{
			if (_Clients.TryGetValue(guid, out var value))
			{
				lock (value)
				{
					value.Ws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", value.TokenSource.Token).Wait();
					value.TokenSource.Cancel();
					value.Ws.Dispose();
				}
			}
		}

		public TaskAwaiter GetAwaiter()
		{
			return _AcceptConnectionsTask.GetAwaiter();
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!disposing)
			{
				return;
			}
			if (_Clients != null)
			{
				foreach (KeyValuePair<Guid, ClientMetadata> client in _Clients)
				{
					client.Value.Ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", client.Value.TokenSource.Token);
					client.Value.TokenSource.Cancel();
				}
			}
			if (_Listener != null)
			{
				if (_Listener.IsListening)
				{
					_Listener.Stop();
				}
				_Listener.Close();
			}
			_TokenSource.Cancel();
		}

		private void SetInvalidCertificateAcceptance()
		{
			ServicePointManager.ServerCertificateValidationCallback = (RemoteCertificateValidationCallback)Delegate.Combine(ServicePointManager.ServerCertificateValidationCallback, (RemoteCertificateValidationCallback)((object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) => true));
		}

		private async Task AcceptConnections(CancellationToken cancelToken)
		{
			bool exiting = false;
			while (!cancelToken.IsCancellationRequested)
			{
				try
				{
					if (!_Listener.IsListening)
					{
						Task.Delay(100).Wait();
						continue;
					}
					HttpListenerContext ctx = await _Listener.GetContextAsync().ConfigureAwait(continueOnCapturedContext: false);
					string text = ctx.Request.RemoteEndPoint.Address.ToString();
					string ipPort = text + ":" + ctx.Request.RemoteEndPoint.Port;
					lock (_PermittedIpsLock)
					{
						if (PermittedIpAddresses != null && PermittedIpAddresses.Count > 0 && !PermittedIpAddresses.Contains(text))
						{
							Logger?.Invoke(_Header + "rejecting " + ipPort + " (not permitted)");
							ctx.Response.StatusCode = 401;
							ctx.Response.Close();
							continue;
						}
					}
					if (ctx.Request.IsWebSocketRequest)
					{
						await Task.Run(delegate
						{
							Logger?.Invoke(_Header + "starting data receiver for " + ipPort);
							CancellationTokenSource tokenSource = new CancellationTokenSource();
							CancellationToken token = tokenSource.Token;
							Task.Run(async delegate
							{
								WebSocketContext webSocketContext = await ctx.AcceptWebSocketAsync(null);
								WebSocket webSocket = webSocketContext.WebSocket;
								ClientMetadata md = new ClientMetadata(ctx, webSocket, webSocketContext, tokenSource);
								_Clients.TryAdd(md.Guid, md);
								this.ClientConnected?.Invoke(this, new ConnectionEventArgs(md, ctx.Request));
								await Task.Run(() => DataReceiver(md), token);
							}, token);
						}, _Token).ConfigureAwait(continueOnCapturedContext: false);
					}
					else if (HttpHandler == null)
					{
						Logger?.Invoke(_Header + "non-websocket request rejected from " + ipPort);
						ctx.Response.StatusCode = 400;
						ctx.Response.Close();
					}
					else
					{
						Logger?.Invoke(_Header + "non-websocket request from " + ipPort + " HTTP-forwarded: " + ctx.Request.HttpMethod.ToString() + " " + ctx.Request.RawUrl);
						HttpHandler(ctx);
					}
				}
				catch (TaskCanceledException)
				{
					exiting = true;
					break;
				}
				catch (OperationCanceledException)
				{
					exiting = true;
					break;
				}
				catch (ObjectDisposedException)
				{
					exiting = true;
					break;
				}
				catch (HttpListenerException)
				{
					exiting = true;
					break;
				}
				catch (Exception ex5)
				{
					Logger?.Invoke(_Header + "listener exception:" + Environment.NewLine + ex5.ToString());
				}
				finally
				{
					if (exiting)
					{
						Logger?.Invoke(_Header + "listener stopped");
						this.ServerStopped?.Invoke(this, EventArgs.Empty);
					}
				}
			}
		}

		private async Task DataReceiver(ClientMetadata client)
		{
			string header = "[WatsonWsServer " + client.Guid.ToString() + "] ";
			Logger?.Invoke(header + "starting data receiver");
			byte[] buffer = new byte[65536];
			try
			{
				while (true)
				{
					MessageReceivedEventArgs msg = await MessageReadAsync(client, buffer).ConfigureAwait(continueOnCapturedContext: false);
					if (msg == null)
					{
						continue;
					}
					if (EnableStatistics)
					{
						_Stats.IncrementReceivedMessages();
						_Stats.AddReceivedBytes(msg.Data.Count);
					}
					if (msg.Data != null)
					{
						Task.Run(delegate
						{
							this.MessageReceived?.Invoke(this, msg);
						}, client.TokenSource.Token);
					}
					else
					{
						await Task.Delay(10).ConfigureAwait(continueOnCapturedContext: false);
					}
				}
			}
			catch (TaskCanceledException)
			{
			}
			catch (OperationCanceledException)
			{
			}
			catch (WebSocketException)
			{
			}
			catch (Exception ex4)
			{
				Logger?.Invoke(header + "exception: " + Environment.NewLine + ex4.ToString());
			}
			finally
			{
				_Clients.TryRemove(client.Guid, out var _);
				_ = client.IpPort;
				this.ClientDisconnected?.Invoke(this, new DisconnectionEventArgs(client));
				client.Ws.Dispose();
				Logger?.Invoke(header + "disconnected");
			}
		}

		private async Task<MessageReceivedEventArgs> MessageReadAsync(ClientMetadata client, byte[] buffer)
		{
			string header = "[WatsonWsServer " + client.Guid.ToString() + "] ";
			using MemoryStream ms = new MemoryStream();
			ArraySegment<byte> seg = new ArraySegment<byte>(buffer);
			WebSocketReceiveResult webSocketReceiveResult;
			do
			{
				webSocketReceiveResult = await client.Ws.ReceiveAsync(seg, client.TokenSource.Token).ConfigureAwait(continueOnCapturedContext: false);
				if (webSocketReceiveResult.CloseStatus.HasValue)
				{
					Logger?.Invoke(header + "close received");
					await client.Ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
					throw new WebSocketException("Websocket closed.");
				}
				if (client.Ws.State != WebSocketState.Open)
				{
					Logger?.Invoke(header + "websocket no longer open");
					throw new WebSocketException("Websocket closed.");
				}
				if (client.TokenSource.Token.IsCancellationRequested)
				{
					Logger?.Invoke(header + "cancel requested");
				}
				if (webSocketReceiveResult.Count > 0)
				{
					ms.Write(buffer, 0, webSocketReceiveResult.Count);
				}
			}
			while (!webSocketReceiveResult.EndOfMessage);
			return new MessageReceivedEventArgs(client, new ArraySegment<byte>(ms.GetBuffer(), 0, (int)ms.Length), webSocketReceiveResult.MessageType);
		}

		private async Task<bool> MessageWriteAsync(ClientMetadata md, ArraySegment<byte> data, WebSocketMessageType msgType, CancellationToken token)
		{
			string header = "[WatsonWsServer " + md.IpPort + "] ";
			using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_Token, token, md.TokenSource.Token))
			{
				_ = 1;
				try
				{
					await md.SendLock.WaitAsync(md.TokenSource.Token).ConfigureAwait(continueOnCapturedContext: false);
					try
					{
						await md.Ws.SendAsync(data, msgType, endOfMessage: true, linkedCts.Token).ConfigureAwait(continueOnCapturedContext: false);
					}
					finally
					{
						md.SendLock.Release();
					}
					if (EnableStatistics)
					{
						_Stats.IncrementSentMessages();
						_Stats.AddSentBytes(data.Count);
					}
					return true;
				}
				catch (TaskCanceledException)
				{
					if (_Token.IsCancellationRequested)
					{
						Logger?.Invoke(header + "server canceled");
					}
					else if (token.IsCancellationRequested)
					{
						Logger?.Invoke(header + "message send canceled");
					}
					else if (md.TokenSource.Token.IsCancellationRequested)
					{
						Logger?.Invoke(header + "client canceled");
					}
				}
				catch (OperationCanceledException)
				{
					if (_Token.IsCancellationRequested)
					{
						Logger?.Invoke(header + "canceled");
					}
					else if (token.IsCancellationRequested)
					{
						Logger?.Invoke(header + "message send canceled");
					}
					else if (md.TokenSource.Token.IsCancellationRequested)
					{
						Logger?.Invoke(header + "client canceled");
					}
				}
				catch (ObjectDisposedException)
				{
					Logger?.Invoke(header + "disposed");
				}
				catch (WebSocketException)
				{
					Logger?.Invoke(header + "websocket disconnected");
				}
				catch (SocketException)
				{
					Logger?.Invoke(header + "socket disconnected");
				}
				catch (InvalidOperationException)
				{
					Logger?.Invoke(header + "disconnected due to invalid operation");
				}
				catch (IOException)
				{
					Logger?.Invoke(header + "IO disconnected");
				}
				catch (Exception ex8)
				{
					Logger?.Invoke(header + "exception: " + Environment.NewLine + ex8.ToString());
				}
				finally
				{
					md = null;
				}
			}
			return false;
		}
	}
}