Decompiled source of Multipeglin v0.1.10

LiteNetLib.dll

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

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Ruslan Pyrch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2024 Ruslan Pyrch")]
[assembly: AssemblyDescription("Lite reliable UDP library for .NET, Mono, and .NET Core")]
[assembly: AssemblyFileVersion("1.3.5")]
[assembly: AssemblyInformationalVersion("1.0.0+cf54c7d7a15a45bd2460cd4a460807329ee7026a")]
[assembly: AssemblyProduct("LiteNetLib")]
[assembly: AssemblyTitle("LiteNetLib")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/RevenantX/LiteNetLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.5.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
	{
	}
}
namespace LiteNetLib
{
	internal abstract class BaseChannel
	{
		protected readonly NetPeer Peer;

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

		private int _isAddedToPeerChannelSendQueue;

		public int PacketsInQueue => OutgoingQueue.Count;

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

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

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

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

		protected abstract bool SendNextPackets();

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

		private int _used;

		internal NetConnectRequestPacket InternalPacket;

		public readonly IPEndPoint RemoteEndPoint;

		public NetDataReader Data => InternalPacket.Data;

		internal ConnectionRequestResult Result { get; private set; }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public SocketError SocketErrorCode;

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

		void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo);

		void OnNetworkError(IPEndPoint endPoint, SocketError socketError);

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

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

		void OnNetworkLatencyUpdate(NetPeer peer, int latency);

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

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

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

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

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

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

		public delegate void OnConnectionRequest(ConnectionRequest request);

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

		public delegate void OnNtpResponseEvent(NtpPacket packet);

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

		public event OnPeerConnected PeerConnectedEvent;

		public event OnPeerDisconnected PeerDisconnectedEvent;

		public event OnNetworkError NetworkErrorEvent;

		public event OnNetworkReceive NetworkReceiveEvent;

		public event OnNetworkReceiveUnconnected NetworkReceiveUnconnectedEvent;

		public event OnNetworkLatencyUpdate NetworkLatencyUpdateEvent;

		public event OnConnectionRequest ConnectionRequestEvent;

		public event OnDeliveryEvent DeliveryEvent;

		public event OnNtpResponseEvent NtpResponseEvent;

		public event OnPeerAddressChangedEvent PeerAddressChangedEvent;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public readonly long ConnectionTime;

		public byte ConnectionNumber;

		public readonly byte[] TargetAddress;

		public readonly NetDataReader Data;

		public readonly int PeerId;

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

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

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

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

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

		public readonly long ConnectionTime;

		public readonly byte ConnectionNumber;

		public readonly int PeerId;

		public readonly bool PeerNetworkChanged;

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

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

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

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

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

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

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

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

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

		public static readonly bool IsSupported;

		public static readonly bool UnixMode;

		public const int IPv4AddrSize = 16;

		public const int IPv6AddrSize = 28;

		public const int AF_INET = 2;

		public const int AF_INET6 = 10;

		private static readonly Dictionary<int, SocketError> NativeErrorToSocketError;

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

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

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

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

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

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

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

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

		public event OnNatIntroductionRequest NatIntroductionRequest;

		public event OnNatIntroductionSuccess NatIntroductionSuccess;

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

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

			public IPEndPoint RemoteEndPoint;

			public string Token;
		}

		private struct SuccessEventData
		{
			public IPEndPoint TargetEndPoint;

			public NatAddressType Type;

			public string Token;
		}

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

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

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

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

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

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

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

		private readonly NetManager _socket;

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

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

		private readonly NetDataReader _cacheReader = new NetDataReader();

		private readonly NetDataWriter _cacheWriter = new NetDataWriter();

		private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(256);

		private INatPunchListener _natPunchListener;

		public const int MaxTokenLength = 256;

		public bool UnsyncedEvents;

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

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

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

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

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

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

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

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

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

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

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

		public const int SocketBufferSize = 1048576;

		public const int SocketTTL = 255;

		public const int HeaderSize = 1;

		public const int ChanneledHeaderSize = 4;

		public const int FragmentHeaderSize = 6;

		public const int FragmentedHeaderTotalSize = 10;

		public const ushort MaxSequence = 32768;

		public const ushort HalfMaxSequence = 16384;

		internal const int ProtocolId = 13;

		internal const int MaxUdpHeaderSize = 68;

		internal const int ChannelTypeCount = 4;

		internal const int FragmentedChannelsCount = 2;

		internal const int MaxFragmentsInWindow = 32;

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

		public static readonly int InitialMtu = PossibleMtu[0];

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

		public static readonly int MaxUnreliableDataSize = MaxPacketSize - 1;

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

		private static readonly object DebugLogLock = new object();

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

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

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

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

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

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

		private readonly NetManager _manager;

		private readonly NetEvent _evt;

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

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

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

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

		public NetEvent Next;

		public EType Type;

		public NetPeer Peer;

		public IPEndPoint RemoteEndPoint;

		public object UserData;

		public int Latency;

		public SocketError ErrorCode;

		public DisconnectReason DisconnectReason;

		public ConnectionRequest ConnectionRequest;

		public DeliveryMethod DeliveryMethod;

		public byte ChannelNumber;

		public readonly NetPacketReader DataReader;

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

			private NetPeer _p;

			public NetPeer Current => _p;

			object IEnumerator.Current => _p;

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

			public void Dispose()
			{
			}

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

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

		private struct IncomingData
		{
			public NetPacket Data;

			public IPEndPoint EndPoint;

			public DateTime TimeWhenGet;
		}

		private struct OutboundDelayedPacket
		{
			public byte[] Data;

			public int Start;

			public int Length;

			public IPEndPoint EndPoint;

			public DateTime TimeWhenSend;
		}

		private struct Slot
		{
			internal int HashCode;

			internal int Next;

			internal NetPeer Value;
		}

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

		private readonly List<OutboundDelayedPacket> _outboundSimulationList = new List<OutboundDelayedPacket>();

		private readonly Random _randomGenerator = new Random();

		private const int MinLatencyThreshold = 5;

		private Thread _logicThread;

		private bool _manualMode;

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

		private NetEvent _pendingEventHead;

		private NetEvent _pendingEventTail;

		private NetEvent _netEventPoolHead;

		private readonly INetEventListener _netEventListener;

		private readonly IDeliveryEventListener _deliveryEventListener;

		private readonly INtpEventListener _ntpEventListener;

		private readonly IPeerAddressChangedListener _peerAddressChangedListener;

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

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

		private long _connectedPeersCount;

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

		private readonly PacketLayerBase _extraPacketLayer;

		private int _lastPeerId;

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

		private byte _channelsCount = 1;

		private readonly object _eventLock = new object();

		private volatile bool _isRunning;

		private bool _dropPacket;

		public bool UnconnectedMessagesEnabled;

		public bool NatPunchEnabled;

		public int UpdateTime = 15;

		public int PingInterval = 1000;

		public int DisconnectTimeout = 5000;

		public bool SimulatePacketLoss;

		public bool SimulateLatency;

		public int SimulationPacketLossChance = 10;

		public int SimulationMinLatency = 30;

		public int SimulationMaxLatency = 100;

		public bool UnsyncedEvents;

		public bool UnsyncedReceiveEvent;

		public bool UnsyncedDeliveryEvent;

		public bool BroadcastReceiveEnabled;

		public int ReconnectDelay = 500;

		public int MaxConnectAttempts = 10;

		public bool ReuseAddress;

		public bool DontRoute;

		public readonly NetStatistics Statistics = new NetStatistics();

		public bool EnableStatistics;

		public readonly NatPunchModule NatPunchModule;

		public bool AutoRecycle;

		public bool IPv6Enabled = true;

		public int MtuOverride;

		public bool MtuDiscovery;

		public bool UseNativeSockets;

		public bool DisconnectOnUnreachable;

		public bool AllowPeerAddressChange;

		private const int MaxPrimeArrayLength = 2147483587;

		private const int HashPrime = 101;

		private const int Lower31BitMask = int.MaxValue;

		private static readonly int[] Primes;

		private int[] _buckets;

		private Slot[] _slots;

		private int _count;

		private int _lastIndex;

		private int _freeList = -1;

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

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

		private volatile NetPeer _headPeer;

		private NetPacket _poolHead;

		private int _poolCount;

		private readonly object _poolLock = new object();

		public int PacketPoolSize = 1000;

		private Socket _udpSocketv4;

		private Socket _udpSocketv6;

		private Thread _receiveThread;

		private IPEndPoint _bufferEndPointv4;

		private IPEndPoint _bufferEndPointv6;

		private const int SioUdpConnreset = -1744830452;

		private static readonly IPAddress MulticastAddressV6;

		public static readonly bool IPv6Support;

		internal bool NotConnected;

		public int ReceivePollingTime = 50000;

		public bool IsRunning => _isRunning;

		public int LocalPort { get; private set; }

		public NetPeer FirstPeer => _headPeer;

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

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

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

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

		public int PoolCount => _poolCount;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public void SendToAll(ReadOnlySpan<byte> data, DeliveryMethod options)
		{
			SendToAll(data, 0, options, null);
		}

		public void SendToAll(ReadOnlySpan<byte> data, DeliveryMethod options, NetPeer excludePeer)
		{
			SendToAll(data, 0, options, excludePeer);
		}

		public void SendToAll(ReadOnlySpan<byte> data, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
		{
			try
			{
				_peersLock.EnterReadLock();
				for (NetPeer netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer)
				{
					if (netPeer != excludePeer)
					{
						netPeer.Send(data, channelNumber, options);
					}
				}
			}
			finally
			{
				_peersLock.ExitReadLock();
			}
		}

		public bool SendUnconnectedMessage(ReadOnlySpan<byte> message, IPEndPoint remoteEndPoint)
		{
			int headerSize = NetPacket.GetHeaderSize(PacketProperty.UnconnectedMessage);
			NetPacket netPacket = PoolGetPacket(message.Length + headerSize);
			netPacket.Property = PacketProperty.UnconnectedMessage;
			message.CopyTo(new Span<byte>(netPacket.RawData, headerSize, message.Length));
			return SendRawAndRecycle(netPacket, remoteEndPoint) > 0;
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		[Conditional("DEBUG")]
		[Conditional("SIMULATE_NETWORK")]
		private void ClearOutboundSimulationList()
		{
			lock (_outboundSimulationList)
			{
				_outboundSimulationList.Clear();
			}
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		private void ManualReceive(Socket socket, EndPoint bufferEndPoint, int maxReceive)
		{
			try
			{
				int num = 0;
				while (socket.Available > 0)
				{
					ReceiveFrom(socket, ref bufferEndPoint);
					num++;
					if (num == maxReceive)
					{
						break;
					}
				}
			}
			catch (SocketException ex)
			{
				ProcessError(ex);
			}
			catch (ObjectDisposedException)
			{
			}
			catch (Exception ex3)
			{
				NetDebug.WriteError("[NM] SocketReceiveThread error: " + ex3);
			}
		}

		private void NativeReceiveLogic()
		{
			IntPtr handle = _udpSocketv4.Handle;
			IntPtr s2 = _udpSocketv6?.Handle ?? IntPtr.Zero;
			byte[] address2 = new byte[16];
			byte[] address3 = new byte[28];
			IPEndPoint tempEndPoint = new IPEndPoint(IPAddress.Any, 0);
			List<Socket> list = new List<Socket>(2);
			Socket udpSocketv = _udpSocketv4;
			Socket udpSocketv2 = _udpSocketv6;
			NetPacket packet = PoolGetPacket(NetConstants.MaxPacketSize);
			while (_isRunning)
			{
				try
				{
					if (udpSocketv2 == null)
					{
						if (!NativeReceiveFrom(handle, address2))
						{
							break;
						}
						continue;
					}
					bool flag = false;
					if (udpSocketv.Available != 0 || list.Contains(udpSocketv))
					{
						if (!NativeReceiveFrom(handle, address2))
						{
							break;
						}
						flag = true;
					}
					if (udpSocketv2.Available != 0 || list.Contains(udpSocketv2))
					{
						if (!NativeReceiveFrom(s2, address3))
						{
							break;
						}
						flag = true;
					}
					list.Clear();
					if (!flag)
					{
						list.Add(udpSocketv);
						list.Add(udpSocketv2);
						Socket.Select(list, null, null, ReceivePollingTime);
					}
				}
				catch (SocketException ex)
				{
					if (ProcessError(ex))
					{
						break;
					}
				}
				catch (ObjectDisposedException)
				{
					break;
				}
				catch (ThreadAbortException)
				{
					break;
				}
				catch (Exception ex4)
				{
					NetDebug.WriteError("[NM] SocketReceiveThread error: " + ex4);
				}
			}
			bool NativeReceiveFrom(IntPtr s, byte[] address)
			{
				int socketAddressSize = address.Length;
				packet.Size = NativeSocket.RecvFrom(s, packet.RawData, NetConstants.MaxPacketSize, address, ref socketAddressSize);
				if (packet.Size == 0)
				{
					return true;
				}
				if (packet.Size == -1)
				{
					return !ProcessError(new SocketException((int)NativeSocket.GetSocketError()));
				}
				short num = (short)((address[1] << 8) | address[0]);
				tempEndPoint.Port = (ushort)((address[2] << 8) | address[3]);
				if ((NativeSocket.UnixMode && num == 10) || (!NativeSocket.UnixMode && num == 23))
				{
					uint num2 = (uint)((address[27] << 24) + (address[26] << 16) + (address[25] << 8) + address[24]);
					tempEndPoint.Address = new IPAddress(new ReadOnlySpan<byte>(address, 8, 16), num2);
				}
				else
				{
					long newAddress = (uint)((address[4] & 0xFF) | ((address[5] << 8) & 0xFF00) | ((address[6] << 16) & 0xFF0000) | (address[7] << 24));
					tempEndPoint.Address = new IPAddress(newAddress);
				}
				if (TryGetPeer(tempEndPoint, out var actualValue))
				{
					OnMessageReceived(packet, actualValue);
				}
				else
				{
					OnMessageReceived(packet, tempEndPoint);
					tempEndPoint = new IPEndPoint(IPAddress.Any, 0);
				}
				packet = PoolGetPacket(NetConstants.MaxPacketSize);
				return true;
			}
		}

		private void ReceiveFrom(Socket s, ref EndPoint bufferEndPoint)
		{
			NetPacket netPacket = PoolGetPacket(NetConstants.MaxPacketSize);
			netPacket.Size = s.ReceiveFrom(netPacket.RawData, 0, NetConstants.MaxPacketSize, SocketFlags.None, ref bufferEndPoint);
			OnMessageReceived(netPacket, (IPEndPoint)bufferEndPoint);
		}

		private void ReceiveLogic()
		{
			EndPoint bufferEndPoint = new IPEndPoint(IPAddress.Any, 0);
			EndPoint bufferEndPoint2 = new IPEndPoint(IPAddress.IPv6Any, 0);
			List<Socket> list = new List<Socket>(2);
			Socket udpSocketv = _udpSocketv4;
			Socket udpSocketv2 = _udpSocketv6;
			while (_isRunning)
			{
				try
				{
					if (udpSocketv2 == null)
					{
						if (udpSocketv.Available != 0 || udpSocketv.Poll(ReceivePollingTime, SelectMode.SelectRead))
						{
							ReceiveFrom(udpSocketv, ref bufferEndPoint);
						}
						continue;
					}
					bool flag = false;
					if (udpSocketv.Available != 0 || list.Contains(udpSocketv))
					{
						ReceiveFrom(udpSocketv, ref bufferEndPoint);
						flag = true;
					}
					if (udpSocketv2.Available != 0 || list.Contains(udpSocketv2))
					{
						ReceiveFrom(udpSocketv2, ref bufferEndPoint2);
						flag = true;
					}
					list.Clear();
					if (!flag)
					{
						list.Add(udpSocketv);
						list.Add(udpSocketv2);
						Socket.Select(list, null, null, ReceivePollingTime);
					}
				}
				catch (SocketException ex)
				{
					if (ProcessError(ex))
					{
						break;
					}
				}
				catch (ObjectDisposedException)
				{
					break;
				}
				catch (ThreadAbortException)
				{
					break;
				}
				catch (Exception ex4)
				{
					NetDebug.WriteError("[NM] SocketReceiveThread error: " + ex4);
				}
			}
		}

		public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode)
		{
			if (IsRunning && !NotConnected)
			{
				return false;
			}
			NotConnected = false;
			_manualMode = manualMode;
			UseNativeSockets = UseNativeSockets && NativeSocket.IsSupported;
			_udpSocketv4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
			if (!BindSocket(_udpSocketv4, new IPEndPoint(addressIPv4, port)))
			{
				return false;
			}
			LocalPort = ((IPEndPoint)_udpSocketv4.LocalEndPoint).Port;
			_isRunning = true;
			if (_manualMode)
			{
				_bufferEndPointv4 = new IPEndPoint(IPAddress.Any, 0);
			}
			if (IPv6Support && IPv6Enabled)
			{
				_udpSocketv6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
				if (BindSocket(_udpSocketv6, new IPEndPoint(addressIPv6, LocalPort)))
				{
					if (_manualMode)
					{
						_bufferEndPointv6 = new IPEndPoint(IPAddress.IPv6Any, 0);
					}
				}
				else
				{
					_udpSocketv6 = null;
				}
			}
			if (!manualMode)
			{
				ThreadStart start = ReceiveLogic;
				if (UseNativeSockets)
				{
					start = NativeReceiveLogic;
				}
				_receiveThread = new Thread(start)
				{
					Name = $"ReceiveThread({LocalPort})",
					IsBackground = true
				};
				_receiveThread.Start();
				if (_logicThread == null)
				{
					_logicThread = new Thread(UpdateLogic)
					{
						Name = "LogicThread",
						IsBackground = true
					};
					_logicThread.Start();
				}
			}
			return true;
		}

		private bool BindSocket(Socket socket, IPEndPoint ep)
		{
			socket.ReceiveTimeout = 500;
			socket.SendTimeout = 500;
			socket.ReceiveBufferSize = 1048576;
			socket.SendBufferSize = 1048576;
			socket.Blocking = true;
			if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
			{
				try
				{
					socket.IOControl(-1744830452, new byte[1], null);
				}
				catch
				{
				}
			}
			try
			{
				socket.ExclusiveAddressUse = !ReuseAddress;
				socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, ReuseAddress);
				socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, DontRoute);
			}
			catch
			{
			}
			if (ep.AddressFamily == AddressFamily.InterNetwork)
			{
				Ttl = 255;
				try
				{
					socket.EnableBroadcast = true;
				}
				catch (SocketException ex)
				{
					NetDebug.WriteError($"[B]Broadcast error: {ex.SocketErrorCode}");
				}
				if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
				{
					try
					{
						socket.DontFragment = true;
					}
					catch (SocketException ex2)
					{
						NetDebug.WriteError($"[B]DontFragment error: {ex2.SocketErrorCode}");
					}
				}
			}
			try
			{
				socket.Bind(ep);
				if (ep.AddressFamily == AddressFamily.InterNetworkV6)
				{
					try
					{
						socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, new IPv6MulticastOption(MulticastAddressV6));
					}
					catch (Exception)
					{
					}
				}
			}
			catch (SocketException ex4)
			{
				switch (ex4.SocketErrorCode)
				{
				case SocketError.AddressAlreadyInUse:
					if (socket.AddressFamily == AddressFamily.InterNetworkV6)
					{
						try
						{
							socket.DualMode = false;
							socket.Bind(ep);
						}
						catch (SocketException ex5)
						{
							NetDebug.WriteError($"[B]Bind exception: {ex5}, errorCode: {ex5.SocketErrorCode}");
							return false;
						}
						return true;
					}
					break;
				case SocketError.AddressFamilyNotSupported:
					return true;
				}
				NetDebug.WriteError($"[B]Bind exception: {ex4}, errorCode: {ex4.SocketErrorCode}");
				return false;
			}
			return true;
		}

		internal int SendRawAndRecycle(NetPacket packet, IPEndPoint remoteEndPoint)
		{
			int result = SendRaw(packet.RawData, 0, packet.Size, remoteEndPoint);
			PoolRecycle(packet);
			return result;
		}

		internal int SendRaw(NetPacket packet, IPEndPoint remoteEndPoint)
		{
			return SendRaw(packet.RawData, 0, packet.Size, remoteEndPoint);
		}

		internal int SendRaw(byte[] message, int start, int length, IPEndPoint remoteEndPoint)
		{
			if (!_isRunning)
			{
				return 0;
			}
			NetPacket netPacket = null;
			if (_extraPacketLayer != null)
			{
				netPacket = PoolGetPacket(length + _extraPacketLayer.ExtraPacketSizeForLayer);
				Buffer.BlockCopy(message, start, netPacket.RawData, 0, length);
				start = 0;
				_extraPacketLayer.ProcessOutBoundPacket(ref remoteEndPoint, ref netPacket.RawData, ref start, ref length);
				message = netPacket.RawData;
			}
			return SendRawCoreWithCleanup(message, start, length, remoteEndPoint, netPacket);
		}

		private int SendRawCoreWithCleanup(byte[] message, int start, int length, IPEndPoint remoteEndPoint, NetPacket expandedPacket)
		{
			try
			{
				return SendRawCore(message, start, length, remoteEndPoint);
			}
			finally
			{
				if (expandedPacket != null)
				{
					PoolRecycle(expandedPacket);
				}
			}
		}

		internal unsafe int SendRawCore(byte[] message, int start, int length, IPEndPoint remoteEndPoint)
		{
			if (!_isRunning)
			{
				return 0;
			}
			Socket socket = _udpSocketv4;
			if (remoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6 && IPv6Support)
			{
				socket = _udpSocketv6;
				if (socket == null)
				{
					return 0;
				}
			}
			int num;
			try
			{
				if (UseNativeSockets && remoteEndPoint is NetPeer netPeer)
				{
					fixed (byte* pinnedBuffer = &message[start])
					{
						num = NativeSocket.SendTo(socket.Handle, pinnedBuffer, length, netPeer.NativeAddress, netPeer.NativeAddress.Length);
					}
					if (num == -1)
					{
						throw NativeSocket.GetSocketException();
					}
				}
				else
				{
					num = socket.SendTo(message, start, length, SocketFlags.None, remoteEndPoint);
				}
			}
			catch (SocketException ex)
			{
				switch (ex.SocketErrorCode)
				{
				case SocketError.Interrupted:
				case SocketError.NoBufferSpaceAvailable:
					return 0;
				case SocketError.MessageSize:
					return 0;
				case SocketError.NetworkUnreachable:
				case SocketError.HostUnreachable:
					if (DisconnectOnUnreachable && remoteEndPoint is NetPeer peer)
					{
						DisconnectPeerForce(peer, (ex.SocketErrorCode == SocketError.HostUnreachable) ? DisconnectReason.HostUnreachable : DisconnectReason.NetworkUnreachable, ex.SocketErrorCode, null);
					}
					CreateEvent(NetEvent.EType.Error, null, remoteEndPoint, ex.SocketErrorCode, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0);
					return -1;
				case SocketError.Shutdown:
					CreateEvent(NetEvent.EType.Error, null, remoteEndPoint, ex.SocketErrorCode, 0, DisconnectReason.ConnectionFailed, null, DeliveryMethod.Unreliable, 0);
					return -1;
				default:
					NetDebug.WriteError($"[S] {ex}");
					return -1;
				}
			}
			catch (Exception arg)
			{
				NetDebug.WriteError($"[S] {arg}");
				return 0;
			}
			if (num <= 0)
			{
				return 0;
			}
			if (EnableStatistics)
			{
				Statistics.IncrementPacketsSent();
				Statistics.AddBytesSent(length);
			}
			return num;
		}

		public bool SendBroadcast(NetDataWriter writer, int port)
		{
			return SendBroadcast(writer.Data, 0, writer.Length, port);
		}

		public bool SendBroadcast(byte[] data, int port)
		{
			return SendBroadcast(data, 0, data.Length, port);
		}

		public bool SendBroadcast(byte[] data, int start, int length, int port)
		{
			if (!IsRunning)
			{
				return false;
			}
			NetPacket netPacket;
			if (_extraPacketLayer != null)
			{
				int headerSize = NetPacket.GetHeaderSize(PacketProperty.Broadcast);
				netPacket = PoolGetPacket(headerSize + length + _extraPacketLayer.ExtraPacketSizeForLayer);
				netPacket.Property = PacketProperty.Broadcast;
				Buffer.BlockCopy(data, start, netPacket.RawData, headerSize, length);
				int offset = 0;
				int length2 = length + headerSize;
				IPEndPoint endPoint = null;
				_extraPacketLayer.ProcessOutBoundPacket(ref endPoint, ref netPacket.RawData, ref offset, ref length2);
			}
			else
			{
				netPacket = PoolGetWithData(PacketProperty.Broadcast, data, start, length);
			}
			bool flag = false;
			bool flag2 = false;
			try
			{
				flag = _udpSocketv4.SendTo(netPacket.RawData, 0, netPacket.Size, SocketFlags.None, new IPEndPoint(IPAddress.Broadcast, port)) > 0;
				if (_udpSocketv6 != null)
				{
					flag2 = _udpSocketv6.SendTo(netPacket.RawData, 0, netPacket.Size, SocketFlags.None, new IPEndPoint(MulticastAddressV6, port)) > 0;
				}
			}
			catch (SocketException ex)
			{
				if (ex.SocketErrorCode == SocketError.HostUnreachable)
				{
					return flag;
				}
				NetDebug.WriteError($"[S][MCAST] {ex}");
				return flag;
			}
			catch (Exception arg)
			{
				NetDebug.WriteError($"[S][MCAST] {arg}");
				return flag;
			}
			finally
			{
				PoolRecycle(netPacket);
			}
			return flag || flag2;
		}

		private void CloseSocket()
		{
			_isRunning = false;
			if (_receiveThread != null && _receiveThread != Thread.CurrentThread)
			{
				_receiveThread.Join();
			}
			_receiveThread = null;
			_udpSocketv4?.Close();
			_udpSocketv6?.Close();
			_udpSocketv4 = null;
			_udpSocketv6 = null;
		}
	}
	internal enum PacketProperty : byte
	{
		Unreliable,
		Channeled,
		Ack,
		Ping,
		Pong,
		ConnectRequest,
		ConnectAccept,
		Disconnect,
		UnconnectedMessage,
		MtuCheck,
		MtuOk,
		Broadcast,
		Merged,
		ShutdownOk,
		PeerNotFound,
		InvalidProtocol,
		NatMessage,
		Empty
	}
	internal sealed class NetPacket
	{
		private static readonly int PropertiesCount;

		private static readonly int[] HeaderSizes;

		public byte[] RawData;

		public int Size;

		public object UserData;

		public NetPacket Next;

		public PacketProperty Property
		{
			get
			{
				return (PacketProperty)(RawData[0] & 0x1Fu);
			}
			set
			{
				RawData[0] = (byte)((RawData[0] & 0xE0u) | (uint)value);
			}
		}

		public byte ConnectionNumber
		{
			get
			{
				return (byte)((RawData[0] & 0x60) >> 5);
			}
			set
			{
				RawData[0] = (byte)((RawData[0] & 0x9Fu) | (uint)(value << 5));
			}
		}

		public ushort Sequence
		{
			get
			{
				return BitConverter.ToUInt16(RawData, 1);
			}
			set
			{
				FastBitConverter.GetBytes(RawData, 1, value);
			}
		}

		public bool IsFragmented => (RawData[0] & 0x80) != 0;

		public byte ChannelId
		{
			get
			{
				return RawData[3];
			}
			set
			{
				RawData[3] = value;
			}
		}

		public ushort FragmentId
		{
			get
			{
				return BitConverter.ToUInt16(RawData, 4);
			}
			set
			{
				FastBitConverter.GetBytes(RawData, 4, value);
			}
		}

		public ushort FragmentPart
		{
			get
			{
				return BitConverter.ToUInt16(RawData, 6);
			}
			set
			{
				FastBitConverter.GetBytes(RawData, 6, value);
			}
		}

		public ushort FragmentsTotal
		{
			get
			{
				return BitConverter.ToUInt16(RawData, 8);
			}
			set
			{
				FastBitConverter.GetBytes(RawData, 8, value);
			}
		}

		static NetPacket()
		{
			PropertiesCount = Enum.GetValues(typeof(PacketProperty)).Length;
			HeaderSizes = NetUtils.AllocatePinnedUninitializedArray<int>(PropertiesCount);
			for (int i = 0; i < HeaderSizes.Length; i++)
			{
				switch ((PacketProperty)(byte)i)
				{
				case PacketProperty.Channeled:
				case PacketProperty.Ack:
					HeaderSizes[i] = 4;
					break;
				case PacketProperty.Ping:
					HeaderSizes[i] = 3;
					break;
				case PacketProperty.ConnectRequest:
					HeaderSizes[i] = 18;
					break;
				case PacketProperty.ConnectAccept:
					HeaderSizes[i] = 15;
					break;
				case PacketProperty.Disconnect:
					HeaderSizes[i] = 9;
					break;
				case PacketProperty.Pong:
					HeaderSizes[i] = 11;
					break;
				default:
					HeaderSizes[i] = 1;
					break;
				}
			}
		}

		public void MarkFragmented()
		{
			RawData[0] |= 128;
		}

		public NetPacket(int size)
		{
			RawData = new byte[size];
			Size = size;
		}

		public NetPacket(PacketProperty property, int size)
		{
			size += GetHeaderSize(property);
			RawData = new byte[size];
			Property = property;
			Size = size;
		}

		public static int GetHeaderSize(PacketProperty property)
		{
			return HeaderSizes[(uint)property];
		}

		public int GetHeaderSize()
		{
			return HeaderSizes[RawData[0] & 0x1F];
		}

		public bool Verify()
		{
			byte b = (byte)(RawData[0] & 0x1Fu);
			if (b >= PropertiesCount)
			{
				return false;
			}
			int num = HeaderSizes[b];
			bool flag = (RawData[0] & 0x80) != 0;
			if (Size >= num)
			{
				if (flag)
				{
					return Size >= num + 6;
				}
				return true;
			}
			return false;
		}

		public static implicit operator Span<byte>(NetPacket p)
		{
			return new Span<byte>(p.RawData, 0, p.Size);
		}
	}
	[Flags]
	public enum ConnectionState : byte
	{
		Outgoing = 2,
		Connected = 4,
		ShutdownRequested = 8,
		Disconnected = 0x10,
		EndPointChange = 0x20,
		Any = 0x2E
	}
	internal enum ConnectRequestResult
	{
		None,
		P2PLose,
		Reconnection,
		NewConnection
	}
	internal enum DisconnectResult
	{
		None,
		Reject,
		Disconnect
	}
	internal enum ShutdownResult
	{
		None,
		Success,
		WasConnected
	}
	public class NetPeer : IPEndPoint
	{
		private class IncomingFragments
		{
			public NetPacket[] Fragments;

			public int ReceivedCount;

			public int TotalSize;

			public byte ChannelId;
		}

		private int _rtt;

		private int _avgRtt;

		private int _rttCount;

		private double _resendDelay = 27.0;

		private float _pingSendTimer;

		private float _rttResetTimer;

		private readonly Stopwatch _pingTimer = new Stopwatch();

		private volatile float _timeSinceLastPacket;

		private long _remoteDelta;

		private readonly object _shutdownLock = new object();

		internal volatile NetPeer NextPeer;

		internal NetPeer PrevPeer;

		private NetPacket[] _unreliableSecondQueue;

		private NetPacket[] _unreliableChannel;

		private int _unreliablePendingCount;

		private readonly object _unreliableChannelLock = new object();

		private readonly ConcurrentQueue<BaseChannel> _channelSendQueue;

		private readonly BaseChannel[] _channels;

		private int _mtu;

		private int _mtuIdx;

		private bool _finishMtu;

		private float _mtuCheckTimer;

		private int _mtuCheckAttempts;

		private const int MtuCheckDelay = 1000;

		private const int MaxMtuCheckAttempts = 4;

		private readonly object _mtuMutex = new object();

		private int _fragmentId;

		private readonly Dictionary<ushort, IncomingFragments> _holdedFragments;

		private readonly Dictionary<ushort, ushort> _deliveredFragments;

		private readonly NetPacket _mergeData;

		private int _mergePos;

		private int _mergeCount;

		private int _connectAttempts;

		private float _connectTimer;

		private long _connectTime;

		private byte _connectNum;

		private ConnectionState _connectionState;

		private NetPacket _shutdownPacket;

		private const int ShutdownDelay = 300;

		private float _shutdownTimer;

		private readonly NetPacket _pingPacket;

		private readonly NetPacket _pongPacket;

		private readonly NetPacket _connectRequestPacket;

		private readonly NetPacket _connectAcceptPacket;

		public readonly NetManager NetManager;

		public readonly int Id;

		public object Tag;

		public readonly NetStatistics Statistics;

		private SocketAddress _cachedSocketAddr;

		private int _cachedHashCode;

		internal byte[] NativeAddress;

		internal byte ConnectionNum
		{
			get
			{
				return _connectNum;
			}
			private set
			{
				_connectNum = value;
				_mergeData.ConnectionNumber = value;
				_pingPacket.ConnectionNumber = value;
				_pongPacket.ConnectionNumber = value;
			}
		}

		public ConnectionState ConnectionState => _connectionState;

		internal long ConnectTime => _connectTime;

		public int RemoteId { get; private set; }

		public int Ping => _avgRtt / 2;

		public int RoundTripTime => _avgRtt;

		public int Mtu => _mtu;

		public long RemoteTimeDelta => _remoteDelta;

		public DateTime RemoteUtcTime => new DateTime(DateTime.UtcNow.Ticks + _remoteDelta);

		public float TimeSinceLastPacket => _timeSinceLastPacket;

		internal double ResendDelay => _resendDelay;

		public override SocketAddress Serialize()
		{
			return _cachedSocketAddr;
		}

		public override int GetHashCode()
		{
			return _cachedHashCode;
		}

		interna

Multipeglin.Core.dll

Decompiled 4 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Multipeglin.Core")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Core mod loader for Peglin")]
[assembly: AssemblyFileVersion("0.1.10.0")]
[assembly: AssemblyInformationalVersion("0.1.10+fa08d30a0345f919382a92e95e02120aab7c2ac1")]
[assembly: AssemblyProduct("Multipeglin.Core")]
[assembly: AssemblyTitle("Multipeglin.Core")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.10.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 Multipeglin.Core
{
	[BepInPlugin("com.multipeglin.core", "Multipeglin Core", "0.1.10")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("com.multipeglin.core");
			_harmony.PatchAll();
			Logger.LogInfo((object)"Multipeglin Core v0.1.10 loaded");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.multipeglin.core";

		public const string PLUGIN_NAME = "Multipeglin Core";

		public const string PLUGIN_VERSION = "0.1.10";
	}
}

Multipeglin.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using Battle;
using Battle.Attacks;
using Battle.Attacks.AttackBehaviours;
using Battle.Enemies;
using Battle.Enemies.Behaviours.SpiritOfRadia;
using Battle.Pachinko;
using Battle.Pachinko.Obstacles;
using Battle.PegBehaviour;
using Battle.StatusEffects;
using BepInEx;
using BepInEx.Logging;
using Challenges;
using ClassSystem;
using Cruciball;
using Currency;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using Data;
using Data.Scenarios;
using HarmonyLib;
using I2.Loc;
using LiteNetLib;
using LiteNetLib.Layers;
using LiteNetLib.Utils;
using Loading;
using Loading.Pegboards;
using Map;
using Microsoft.CodeAnalysis;
using Multipeglin.Continue;
using Multipeglin.DI;
using Multipeglin.Debug;
using Multipeglin.Events;
using Multipeglin.Events.Handlers;
using Multipeglin.Events.Handlers.Ball;
using Multipeglin.Events.Handlers.Battle;
using Multipeglin.Events.Handlers.Coop;
using Multipeglin.Events.Handlers.Currency;
using Multipeglin.Events.Handlers.Cursor;
using Multipeglin.Events.Handlers.Deck;
using Multipeglin.Events.Handlers.Enemy;
using Multipeglin.Events.Handlers.Health;
using Multipeglin.Events.Handlers.Lobby;
using Multipeglin.Events.Handlers.Map;
using Multipeglin.Events.Handlers.Peg;
using Multipeglin.Events.Handlers.Relic;
using Multipeglin.Events.Handlers.Scenarios;
using Multipeglin.Events.Handlers.State;
using Multipeglin.Events.Handlers.StatusEffect;
using Multipeglin.Events.Network;
using Multipeglin.Events.Network.Ball;
using Multipeglin.Events.Network.Battle;
using Multipeglin.Events.Network.Coop;
using Multipeglin.Events.Network.Currency;
using Multipeglin.Events.Network.Cursor;
using Multipeglin.Events.Network.Deck;
using Multipeglin.Events.Network.Enemy;
using Multipeglin.Events.Network.Health;
using Multipeglin.Events.Network.Lobby;
using Multipeglin.Events.Network.Map;
using Multipeglin.Events.Network.Peg;
using Multipeglin.Events.Network.Relic;
using Multipeglin.Events.Network.Scenarios;
using Multipeglin.Events.Network.StatusEffect;
using Multipeglin.Events.Subscriptions;
using Multipeglin.Events.Subscriptions.Coop;
using Multipeglin.GameState;
using Multipeglin.GameState.Appliers;
using Multipeglin.GameState.Providers;
using Multipeglin.GameState.Snapshots;
using Multipeglin.Multiplayer;
using Multipeglin.Network;
using Multipeglin.Network.Protocol;
using Multipeglin.Patches;
using Multipeglin.UI;
using Multipeglin.Utility;
using NLog;
using NLog.Config;
using NLog.Layouts;
using NLog.Targets;
using NLog.Targets.Wrappers;
using Newtonsoft.Json;
using Peglin;
using Peglin.ClassSystem;
using Peglin.PegMinigame;
using PeglinUI;
using PeglinUI.ControllerSupport;
using PeglinUI.LoadoutManager;
using PeglinUI.MainMenu;
using PeglinUI.OrbDisplay;
using PeglinUI.PostBattle;
using PeglinUI.RunSummary;
using PeglinUI.UIUtils;
using PixelCrushers;
using PixelCrushers.DialogueSystem;
using RNG.Scenarios;
using Relics;
using Rewired;
using Rewired.Integration.UnityUI;
using Scenarios;
using Scenarios.Shop;
using Stats;
using Steamworks;
using TMPro;
using ToolBox.Serialization;
using Tutorial;
using UI.OrbDisplay;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Worldmap;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Multipeglin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Multiplayer mode for Peglin")]
[assembly: AssemblyFileVersion("0.1.10.0")]
[assembly: AssemblyInformationalVersion("0.1.10+fa08d30a0345f919382a92e95e02120aab7c2ac1")]
[assembly: AssemblyProduct("Multipeglin")]
[assembly: AssemblyTitle("Multipeglin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.10.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 Multipeglin
{
	[BepInPlugin("com.multipeglin", "Multipeglin", "0.1.10")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MultiplayerPlugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private FileLogger _fileLogger;

		private static GameObject _modObject;

		public static MultiplayerPlugin Instance { get; private set; }

		public static IServiceContainer Services { get; private set; }

		public static ManualLogSource Logger { get; private set; }

		public static IReadOnlyList<string> MissingPatches { get; private set; }

		private void Awake()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			try
			{
				string logsDirectory = Path.Combine(Paths.BepInExRootPath, "logs");
				_fileLogger = new FileLogger(logsDirectory);
				Logger.Listeners.Add((ILogListener)(object)new FileLogListener(_fileLogger));
				Logger.LogInfo((object)("Log file: " + _fileLogger.FilePath));
				Services = ServiceRegistration.CreateAndConfigure(Logger);
				_modObject = new GameObject("Multipeglin")
				{
					hideFlags = (HideFlags)61
				};
				Object.DontDestroyOnLoad((Object)(object)_modObject);
				_modObject.AddComponent<NetworkPollBehaviour>().Initialize(Services.Resolve<INetworkTransport>());
				MainThreadDispatcher instance = _modObject.AddComponent<MainThreadDispatcher>();
				Services.RegisterSingleton(instance);
				_modObject.AddComponent<MultiplayerUI>();
				_modObject.AddComponent<SceneWatcher>();
				_modObject.AddComponent<BallPositionSync>();
				_modObject.AddComponent<HostBallSync>();
				_modObject.AddComponent<ClientBallRenderer>();
				_modObject.AddComponent<ClientAimRenderer>();
				_modObject.AddComponent<RttPingTicker>();
				_modObject.AddComponent<HostRttTickerBehaviour>();
				_modObject.AddComponent<CursorSync>();
				_modObject.AddComponent<RemoteCursorRenderer>();
				_modObject.AddComponent<ClientAttackProjectile>();
				_modObject.AddComponent<CoopPlayerVisuals>();
				_modObject.AddComponent<PendingDamageOverlay>();
				_modObject.AddComponent<SkipTurnButton>();
				_modObject.AddComponent<CoopRewardUI>();
				_modObject.AddComponent<CoopNavigateClientInput>();
				_modObject.AddComponent<ClientRelicChoiceApplier>();
				_modObject.AddComponent<DebugHotkeys>();
				_harmony = new Harmony("com.multipeglin");
				try
				{
					_harmony.PatchAll();
				}
				catch (Exception ex)
				{
					Logger.LogError((object)$"Harmony PatchAll failed: {ex}");
					MissingPatches = new List<string> { "PatchAll failed: " + ex.Message };
				}
				int num = 0;
				foreach (MethodBase patchedMethod in _harmony.GetPatchedMethods())
				{
					Logger.LogInfo((object)("Harmony patched: " + patchedMethod.DeclaringType?.FullName + "." + patchedMethod.Name));
					num++;
				}
				Logger.LogInfo((object)$"Harmony total patches applied: {num}");
				if (MissingPatches == null)
				{
					List<string> list = PatchValidator.FindMissingPatchTargets(Logger);
					if (list.Count > 0)
					{
						Logger.LogWarning((object)$"[PatchValidator] {list.Count} patch target(s) not found:");
						foreach (string item in list)
						{
							Logger.LogWarning((object)("  Missing: " + item));
						}
						MissingPatches = list;
					}
				}
				Logger.LogInfo((object)"Multipeglin v0.1.10 loaded");
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Failed to initialize: {arg}");
			}
		}

		private void OnDestroy()
		{
		}
	}
	public static class MultiplayerPluginInfo
	{
		public const string GUID = "com.multipeglin";

		public const string NAME = "Multipeglin";

		public const string VERSION = "0.1.10";

		public const string COMPILED_GAME_VERSION = "2.0.12";
	}
}
namespace Multipeglin.Utility
{
	public class BallIdentifier
	{
		private readonly Dictionary<string, PachinkoBall> _guidToBall = new Dictionary<string, PachinkoBall>();

		private readonly Dictionary<PachinkoBall, string> _ballToGuid = new Dictionary<PachinkoBall, string>();

		private static ManualLogSource Log => MultiplayerPlugin.Logger;

		public int Count => _guidToBall.Count;

		public string GetOrAssignGuid(PachinkoBall ball)
		{
			if ((Object)(object)ball == (Object)null)
			{
				return "null";
			}
			if (_ballToGuid.TryGetValue(ball, out var value))
			{
				return value;
			}
			string text = Guid.NewGuid().ToString("N").Substring(0, 12);
			_guidToBall[text] = ball;
			_ballToGuid[ball] = text;
			return text;
		}

		public string GetGuid(PachinkoBall ball)
		{
			if ((Object)(object)ball == (Object)null)
			{
				return null;
			}
			if (!_ballToGuid.TryGetValue(ball, out var value))
			{
				return null;
			}
			return value;
		}

		public void Forget(PachinkoBall ball)
		{
			if (!((Object)(object)ball == (Object)null) && _ballToGuid.TryGetValue(ball, out var value))
			{
				_guidToBall.Remove(value);
				_ballToGuid.Remove(ball);
			}
		}

		public void ForgetByGuid(string guid)
		{
			if (!string.IsNullOrEmpty(guid) && _guidToBall.TryGetValue(guid, out var value))
			{
				_guidToBall.Remove(guid);
				if ((Object)(object)value != (Object)null)
				{
					_ballToGuid.Remove(value);
				}
			}
		}

		public List<string> PruneDestroyed()
		{
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			foreach (KeyValuePair<string, PachinkoBall> item in _guidToBall)
			{
				if ((Object)(object)item.Value == (Object)null)
				{
					list2.Add(item.Key);
				}
			}
			foreach (string item2 in list2)
			{
				_guidToBall.Remove(item2);
				list.Add(item2);
			}
			List<PachinkoBall> list3 = new List<PachinkoBall>();
			foreach (KeyValuePair<PachinkoBall, string> item3 in _ballToGuid)
			{
				if ((Object)(object)item3.Key == (Object)null)
				{
					list3.Add(item3.Key);
				}
			}
			foreach (PachinkoBall item4 in list3)
			{
				_ballToGuid.Remove(item4);
			}
			return list;
		}

		public void Clear()
		{
			int count = _guidToBall.Count;
			_guidToBall.Clear();
			_ballToGuid.Clear();
			if (count > 0)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)$"[BallGUID] Cleared {count} entries");
				}
			}
		}
	}
	public static class DiagnosticLogger
	{
		private static ManualLogSource Log => MultiplayerPlugin.Logger;

		public static void DumpBattleState(string trigger)
		{
			//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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			//IL_069a: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)("=== DIAG [" + trigger + "] scene=" + name + " ==="));
				}
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogInfo((object)($"  SGD: seed={StaticGameData.currentSeed}, floor={StaticGameData.totalFloorCount}, " + $"class={StaticGameData.chosenClass}, nodeIdx={StaticGameData.chosenNextNodeIndex}, " + string.Format("seedSet={0}, dataToLoad={1}", StaticGameData.seedSet, ((Object)(object)StaticGameData.dataToLoad != (Object)null) ? ((object)StaticGameData.dataToLoad).GetType().Name : "NULL")));
				}
				MapData dataToLoad = StaticGameData.dataToLoad;
				MapDataBattle val = (MapDataBattle)(object)((dataToLoad is MapDataBattle) ? dataToLoad : null);
				if (val != null)
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						string[] obj = new string[6]
						{
							"  MapDataBattle: name=",
							((Object)val).name,
							", pegLayout=",
							((Object)(object)val.pegLayout != (Object)null) ? ((Object)val.pegLayout).name : "NULL",
							", ",
							null
						};
						object arg = val.NumberOfSlots;
						object arg2 = val.starterSpawns?.Count ?? (-1);
						WaveGroup[] waveGroups = val.waveGroups;
						obj[5] = $"slots={arg}, starterSpawns={arg2}, waves={((waveGroups != null) ? waveGroups.Length : (-1))}";
						log3.LogInfo((object)string.Concat(obj));
					}
				}
				try
				{
					RelicManager[] array = Resources.FindObjectsOfTypeAll<RelicManager>();
					RelicManager val2 = ((array.Length != 0) ? array[0] : null);
					if ((Object)(object)val2 != (Object)null)
					{
						IDictionary dictionary = AccessTools.Field(typeof(RelicManager), "_ownedRelics")?.GetValue(val2) as IDictionary;
						ManualLogSource log4 = Log;
						if (log4 != null)
						{
							log4.LogInfo((object)$"  Relics: {dictionary?.Count ?? 0} owned");
						}
					}
				}
				catch
				{
				}
				try
				{
					List<GameObject> completeDeck = DeckManager.completeDeck;
					ManualLogSource log5 = Log;
					if (log5 != null)
					{
						log5.LogInfo((object)$"  CompleteDeck: {completeDeck?.Count ?? 0} orbs");
					}
				}
				catch
				{
				}
				try
				{
					Dictionary<string, GameObject> dictionary2 = AssetLoading.Instance?.EnemyPrefabs;
					ManualLogSource log6 = Log;
					if (log6 != null)
					{
						log6.LogInfo((object)$"  EnemyPrefabCache: {dictionary2?.Count ?? (-1)} entries");
					}
				}
				catch
				{
				}
				if (name != "Battle")
				{
					ManualLogSource log7 = Log;
					if (log7 != null)
					{
						log7.LogInfo((object)("=== END DIAG [" + trigger + "] (not Battle) ==="));
					}
					return;
				}
				EnemyManager val3 = Object.FindObjectOfType<EnemyManager>();
				if ((Object)(object)val3 != (Object)null)
				{
					List<Enemy> enemies = val3.Enemies;
					ManualLogSource log8 = Log;
					if (log8 != null)
					{
						log8.LogInfo((object)$"  Enemies ({enemies?.Count ?? 0}):");
					}
					if (enemies != null)
					{
						for (int i = 0; i < enemies.Count; i++)
						{
							Enemy val4 = enemies[i];
							if ((Object)(object)val4 == (Object)null)
							{
								ManualLogSource log9 = Log;
								if (log9 != null)
								{
									log9.LogInfo((object)$"    [{i}] NULL");
								}
								continue;
							}
							ManualLogSource log10 = Log;
							if (log10 != null)
							{
								log10.LogInfo((object)($"    [{i}] {val4.locKey} name={((Object)((Component)val4).gameObject).name} hp={val4.CurrentHealth}/{GetMaxHp(val4):F0} " + $"pos=({((Component)val4).transform.position.x:F2},{((Component)val4).transform.position.y:F2}) flying={val4.IsFlying}"));
							}
						}
					}
				}
				else
				{
					ManualLogSource log11 = Log;
					if (log11 != null)
					{
						log11.LogInfo((object)"  EnemyManager: NOT FOUND");
					}
				}
				BattleController obj5 = Object.FindObjectOfType<BattleController>();
				PegManager val5 = ((obj5 != null) ? obj5.pegManager : null);
				if (val5 != null && val5.allPegs != null)
				{
					List<Bomb> list = AccessTools.Field(typeof(BattleController).Assembly.GetType("Battle.PegManager"), "_bombs")?.GetValue(val5) as List<Bomb>;
					List<Peg> list2 = new List<Peg>(val5.allPegs);
					if (list != null)
					{
						foreach (Bomb item in list)
						{
							list2.Add((Peg)(object)item);
						}
					}
					Peg[] array2 = list2.Where((Peg p) => (Object)(object)p != (Object)null && ((Component)p).gameObject.activeSelf).ToArray();
					IOrderedEnumerable<IGrouping<PegType, Peg>> orderedEnumerable = from p in array2
						group p by p.pegType into g
						orderby g.Count() descending
						select g;
					ManualLogSource log12 = Log;
					if (log12 != null)
					{
						log12.LogInfo((object)$"  Pegs: {array2.Length} active / {list2.Count} total (allPegs={val5.allPegs.Count}, bombs={list?.Count ?? 0})");
					}
					foreach (IGrouping<PegType, Peg> item2 in orderedEnumerable)
					{
						ManualLogSource log13 = Log;
						if (log13 != null)
						{
							log13.LogInfo((object)$"    {item2.Key}: {item2.Count()}");
						}
					}
					IEnumerable<Peg> enumerable = (from p in array2
						orderby ((Component)p).transform.position.y, ((Component)p).transform.position.x
						select p).Take(10);
					ManualLogSource log14 = Log;
					if (log14 != null)
					{
						log14.LogInfo((object)"  First 10 pegs by pos:");
					}
					foreach (Peg item3 in enumerable)
					{
						ManualLogSource log15 = Log;
						if (log15 != null)
						{
							log15.LogInfo((object)$"    ({((Component)item3).transform.position.x:F3},{((Component)item3).transform.position.y:F3}) type={item3.pegType}");
						}
					}
				}
				else
				{
					ManualLogSource log16 = Log;
					if (log16 != null)
					{
						log16.LogInfo((object)"  PegManager: NOT FOUND");
					}
				}
				ManualLogSource log17 = Log;
				if (log17 != null)
				{
					log17.LogInfo((object)$"  BattleState: {BattleController.CurrentBattleState}");
				}
				PachinkoBall[] array3 = Object.FindObjectsOfType<PachinkoBall>();
				ManualLogSource log18 = Log;
				if (log18 != null)
				{
					log18.LogInfo((object)$"  Balls: {array3.Length} (dummy={array3.Count((PachinkoBall b) => b.IsDummy)}, real={array3.Count((PachinkoBall b) => !b.IsDummy)})");
				}
				ManualLogSource log19 = Log;
				if (log19 != null)
				{
					log19.LogInfo((object)("=== END DIAG [" + trigger + "] ==="));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log20 = Log;
				if (log20 != null)
				{
					log20.LogError((object)("DiagnosticLogger.DumpBattleState failed: " + ex.Message));
				}
			}
		}

		private static float GetMaxHp(Enemy e)
		{
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(Enemy), "_maxHealth");
				return (fieldInfo != null) ? ((float)fieldInfo.GetValue(e)) : (-1f);
			}
			catch
			{
				return -1f;
			}
		}
	}
	public class EnemyIdentifier
	{
		private readonly Dictionary<string, Enemy> _guidToEnemy = new Dictionary<string, Enemy>();

		private readonly Dictionary<Enemy, string> _enemyToGuid = new Dictionary<Enemy, string>();

		private static ManualLogSource Log => MultiplayerPlugin.Logger;

		public string GetOrAssignGuid(Enemy enemy)
		{
			if ((Object)(object)enemy == (Object)null)
			{
				return "null";
			}
			if (_enemyToGuid.TryGetValue(enemy, out var value))
			{
				return value;
			}
			string text = Guid.NewGuid().ToString("N").Substring(0, 12);
			_guidToEnemy[text] = enemy;
			_enemyToGuid[enemy] = text;
			return text;
		}

		public void Register(Enemy enemy, string guid)
		{
			if ((Object)(object)enemy == (Object)null || string.IsNullOrEmpty(guid))
			{
				return;
			}
			if (_guidToEnemy.TryGetValue(guid, out var value) && (Object)(object)value != (Object)(object)enemy)
			{
				_enemyToGuid.Remove(value);
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)("[EnemyGUID] Replaced stale mapping for " + guid + " (was '" + value?.locKey + "')"));
				}
			}
			if (_enemyToGuid.TryGetValue(enemy, out var value2) && value2 != guid)
			{
				_guidToEnemy.Remove(value2);
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogInfo((object)("[EnemyGUID] Enemy '" + enemy.locKey + "' had old GUID " + value2 + ", replacing with " + guid));
				}
			}
			_guidToEnemy[guid] = enemy;
			_enemyToGuid[enemy] = guid;
		}

		public Enemy Find(string guid)
		{
			if (string.IsNullOrEmpty(guid))
			{
				return null;
			}
			if (_guidToEnemy.TryGetValue(guid, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			if ((Object)(object)value == (Object)null && _guidToEnemy.ContainsKey(guid))
			{
				_guidToEnemy.Remove(guid);
			}
			return null;
		}

		public string GetGuid(Enemy enemy)
		{
			if ((Object)(object)enemy == (Object)null)
			{
				return null;
			}
			if (!_enemyToGuid.TryGetValue(enemy, out var value))
			{
				return null;
			}
			return value;
		}

		public void Unregister(Enemy enemy)
		{
			if (!((Object)(object)enemy == (Object)null) && _enemyToGuid.TryGetValue(enemy, out var value))
			{
				_enemyToGuid.Remove(enemy);
				_guidToEnemy.Remove(value);
			}
		}

		public void Unregister(string guid)
		{
			if (!string.IsNullOrEmpty(guid) && _guidToEnemy.TryGetValue(guid, out var value))
			{
				_guidToEnemy.Remove(guid);
				if ((Object)(object)value != (Object)null)
				{
					_enemyToGuid.Remove(value);
				}
			}
		}

		public void Clear()
		{
			int count = _guidToEnemy.Count;
			_guidToEnemy.Clear();
			_enemyToGuid.Clear();
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)$"[EnemyGUID] Cleared {count} entries");
			}
		}

		public void DumpState(string trigger)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)$"[EnemyGUID] === DUMP ({trigger}) {_guidToEnemy.Count} entries ===");
			}
			foreach (KeyValuePair<string, Enemy> item in _guidToEnemy)
			{
				Enemy value = item.Value;
				if ((Object)(object)value != (Object)null)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogInfo((object)("[EnemyGUID]   " + item.Key + " → '" + value.locKey + "' (" + ((Object)((Component)value).gameObject).name + ") " + $"pos=({((Component)value).transform.position.x:F1},{((Component)value).transform.position.y:F1}) hp={value.CurrentHealth}"));
					}
				}
				else
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogInfo((object)("[EnemyGUID]   " + item.Key + " → DESTROYED"));
					}
				}
			}
		}

		public string GetId(Enemy enemy)
		{
			return GetOrAssignGuid(enemy);
		}
	}
	public sealed class EventDiscovery
	{
		private readonly ManualLogSource _log;

		public Dictionary<string, FieldInfo> AvailableEvents { get; } = new Dictionary<string, FieldInfo>();


		public HashSet<string> RegisteredTypeIds { get; } = new HashSet<string>();


		public EventDiscovery(ManualLogSource log)
		{
			_log = log;
		}

		public void ScanGameDelegates()
		{
			AvailableEvents.Clear();
			try
			{
				Assembly assembly = Assembly.Load("Assembly-CSharp");
				if (assembly == null)
				{
					_log.LogWarning((object)"Could not load Assembly-CSharp for event discovery");
					return;
				}
				Type[] types = assembly.GetTypes();
				foreach (Type type in types)
				{
					try
					{
						FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public);
						foreach (FieldInfo fieldInfo in fields)
						{
							if (typeof(Delegate).IsAssignableFrom(fieldInfo.FieldType))
							{
								string key = type.FullName + "." + fieldInfo.Name;
								AvailableEvents[key] = fieldInfo;
							}
						}
					}
					catch
					{
					}
				}
				_log.LogInfo((object)$"Event discovery: found {AvailableEvents.Count} static delegate fields in game");
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("Event discovery scan failed: " + ex.Message));
			}
		}

		public void MarkRegistered(string typeId)
		{
			RegisteredTypeIds.Add(typeId);
		}

		public void LogReport()
		{
			_log.LogInfo((object)"=== Event Discovery Report ===");
			_log.LogInfo((object)$"Game delegates found: {AvailableEvents.Count}");
			_log.LogInfo((object)$"Handlers registered:  {RegisteredTypeIds.Count}");
			foreach (IGrouping<string, KeyValuePair<string, FieldInfo>> item in from kv in AvailableEvents
				group kv by kv.Value.DeclaringType?.Name ?? "Unknown" into g
				orderby g.Key
				select g)
			{
				IOrderedEnumerable<string> values = from kv in item
					select kv.Value.Name into n
					orderby n
					select n;
				_log.LogInfo((object)("  [" + item.Key + "] " + string.Join(", ", values)));
			}
			_log.LogInfo((object)"--- Registered handler typeIds ---");
			foreach (string item2 in RegisteredTypeIds.OrderBy((string s) => s))
			{
				_log.LogInfo((object)("  " + item2));
			}
		}
	}
	public sealed class FileLogger : IDisposable
	{
		private readonly Logger _nlog;

		private readonly string _filePath;

		private static string _roleTag = string.Empty;

		public string FilePath => _filePath;

		public static string RoleTag
		{
			get
			{
				return _roleTag;
			}
			set
			{
				_roleTag = AnnotateClientTag(value);
			}
		}

		public FileLogger(string logsDirectory)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			Directory.CreateDirectory(logsDirectory);
			string text = Environment.GetEnvironmentVariable("MULTIPEGLIN_LOGNAME");
			if (string.IsNullOrEmpty(text))
			{
				text = "multipeglin_log.log";
			}
			_filePath = Path.Combine(logsDirectory, text);
			string environmentVariable = Environment.GetEnvironmentVariable("MULTIPEGLIN_INSTANCE");
			if (!string.IsNullOrEmpty(environmentVariable))
			{
				RoleTag = environmentVariable;
			}
			LoggingConfiguration val = new LoggingConfiguration();
			FileTarget val2 = new FileTarget("multipeglinFile")
			{
				FileName = Layout.op_Implicit(_filePath),
				Layout = Layout.op_Implicit("${message}"),
				KeepFileOpen = true,
				AutoFlush = false,
				OpenFileFlushTimeout = 2,
				BufferSize = 32768
			};
			AsyncTargetWrapper val3 = new AsyncTargetWrapper("multipeglinFileAsync", (Target)(object)val2)
			{
				QueueLimit = 10000,
				BatchSize = 200,
				TimeToSleepBetweenBatches = 0,
				OverflowAction = (AsyncTargetWrapperOverflowAction)1
			};
			val.AddRule(LogLevel.Trace, LogLevel.Fatal, (Target)(object)val3, "*");
			LogManager.Configuration = val;
			_nlog = LogManager.GetLogger("Multipeglin");
			_nlog.Info($"--- Multipeglin [{RoleTag}] log started at {DateTime.Now:O} ---");
		}

		private static string AnnotateClientTag(string baseTag)
		{
			if (baseTag != "CLIENT")
			{
				return baseTag;
			}
			try
			{
				string environmentVariable = Environment.GetEnvironmentVariable("MULTIPEGLIN_INSTANCE");
				if (string.IsNullOrEmpty(environmentVariable))
				{
					return baseTag;
				}
				int num = environmentVariable.Length;
				while (num > 0 && char.IsDigit(environmentVariable[num - 1]))
				{
					num--;
				}
				string text = environmentVariable.Substring(num);
				return string.IsNullOrEmpty(text) ? baseTag : ("CLIENT" + text);
			}
			catch
			{
				return baseTag;
			}
		}

		public void Log(LogLevel level, string message)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			string text = (string.IsNullOrEmpty(RoleTag) ? string.Empty : ("[" + RoleTag + "] "));
			string text2 = $"[{DateTime.Now:HH:mm:ss.fff}] [{level}] {text}{message}";
			_nlog.Info(text2);
		}

		public void Dispose()
		{
			LogManager.Shutdown();
		}
	}
	public sealed class FileLogListener : ILogListener, IDisposable
	{
		private readonly FileLogger _fileLogger;

		public FileLogListener(FileLogger fileLogger)
		{
			_fileLogger = fileLogger;
		}

		public void LogEvent(object sender, LogEventArgs eventArgs)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			ILogSource source = eventArgs.Source;
			if (source != null && (source.SourceName?.StartsWith("Multipeglin")).GetValueOrDefault())
			{
				_fileLogger.Log(eventArgs.Level, $"[{eventArgs.Source.SourceName}] {eventArgs.Data}");
			}
		}

		public void Dispose()
		{
		}
	}
	public static class LongPegVisualHelper
	{
		public static void ApplyHitVisual(LongPeg peg)
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)peg == (Object)null)
			{
				return;
			}
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(LongPeg), "_hit");
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(Peg), "_cleared");
				FieldInfo fieldInfo3 = AccessTools.Field(typeof(LongPeg), "_renderer");
				FieldInfo fieldInfo4 = AccessTools.Field(typeof(LongPeg), "_colors");
				FieldInfo fieldInfo5 = AccessTools.Field(typeof(LongPeg), "_activeMaterial");
				FieldInfo fieldInfo6 = AccessTools.Field(typeof(LongPeg), "_destroyedMaterial");
				FieldInfo fieldInfo7 = AccessTools.Field(typeof(Peg), "_poppedPegTrigger");
				fieldInfo?.SetValue(peg, true);
				fieldInfo2?.SetValue(peg, true);
				object? obj = fieldInfo3?.GetValue(peg);
				MeshRenderer val = (MeshRenderer)((obj is MeshRenderer) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				object? obj2 = fieldInfo7?.GetValue(peg);
				Collider2D val2 = (Collider2D)((obj2 is Collider2D) ? obj2 : null);
				object? obj3 = (((Object)(object)val2 != (Object)null && ((Behaviour)val2).enabled) ? fieldInfo6 : fieldInfo5)?.GetValue(peg);
				Material val3 = (Material)((obj3 is Material) ? obj3 : null);
				if ((Object)(object)val3 != (Object)null)
				{
					((Renderer)val).material = val3;
				}
				object obj4 = fieldInfo4?.GetValue(peg);
				if (obj4 != null)
				{
					FieldInfo field = obj4.GetType().GetField("Hit");
					if (field != null && (Object)(object)((Renderer)val).material != (Object)null)
					{
						Color color = (Color)field.GetValue(obj4);
						((Renderer)val).material.color = color;
					}
				}
			}
			catch
			{
			}
		}
	}
	public class MainThreadDispatcher : MonoBehaviour
	{
		private readonly ConcurrentQueue<Action> _queue = new ConcurrentQueue<Action>();

		private float _heartbeatTimer;

		private int _heartbeatCount;

		public static MainThreadDispatcher Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				ManualLogSource logger = MultiplayerPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"[MainThreadDispatcher] Duplicate detected — destroying old instance");
				}
				Object.Destroy((Object)(object)((Component)Instance).gameObject);
			}
			Instance = this;
			_heartbeatCount = 0;
			ManualLogSource logger2 = MultiplayerPlugin.Logger;
			if (logger2 != null)
			{
				logger2.LogInfo((object)"[MainThreadDispatcher] Awake — Instance set, heartbeat will auto-start");
			}
		}

		public void Enqueue(Action action)
		{
			_queue.Enqueue(action);
		}

		private void Update()
		{
			Action result;
			while (_queue.TryDequeue(out result))
			{
				result();
			}
			RunHeartbeat();
		}

		private void RunHeartbeat()
		{
			//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_0008: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			BattleState currentBattleState = BattleController.CurrentBattleState;
			bool flag = (int)currentBattleState == 3 || (int)currentBattleState == 9;
			float num = (flag ? 1f : 2f);
			_heartbeatTimer += Time.unscaledDeltaTime;
			if (_heartbeatTimer < num)
			{
				return;
			}
			_heartbeatTimer = 0f;
			try
			{
				IServiceContainer services = MultiplayerPlugin.Services;
				if (services != null && services.TryResolve<IMultiplayerMode>(out var instance) && instance.IsHosting && services.TryResolve<IGameStateSyncService>(out var instance2))
				{
					_heartbeatCount++;
					string trigger = (flag ? $"HEARTBEAT#{_heartbeatCount}(shot)" : $"HEARTBEAT#{_heartbeatCount}");
					instance2.SyncAll(trigger);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = MultiplayerPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)$"[HEARTBEAT#{_heartbeatCount}] Exception: {ex.Message}");
				}
			}
		}
	}
	public class OrbIdentifier
	{
		private readonly Dictionary<string, GameObject> _guidToOrb = new Dictionary<string, GameObject>();

		private readonly Dictionary<GameObject, string> _orbToGuid = new Dictionary<GameObject, string>();

		private static ManualLogSource Log => MultiplayerPlugin.Logger;

		public int Count => _guidToOrb.Count;

		public string GetOrAssignGuid(GameObject orb)
		{
			if ((Object)(object)orb == (Object)null)
			{
				return "null";
			}
			if (_orbToGuid.TryGetValue(orb, out var value))
			{
				return value;
			}
			string text = Guid.NewGuid().ToString("N").Substring(0, 12);
			_guidToOrb[text] = orb;
			_orbToGuid[orb] = text;
			return text;
		}

		public void Register(GameObject orb, string guid)
		{
			if (!((Object)(object)orb == (Object)null) && !string.IsNullOrEmpty(guid))
			{
				if (_guidToOrb.TryGetValue(guid, out var value) && (Object)(object)value != (Object)(object)orb)
				{
					_orbToGuid.Remove(value);
				}
				if (_orbToGuid.TryGetValue(orb, out var value2) && value2 != guid)
				{
					_guidToOrb.Remove(value2);
				}
				_guidToOrb[guid] = orb;
				_orbToGuid[orb] = guid;
			}
		}

		public GameObject Find(string guid)
		{
			if (string.IsNullOrEmpty(guid))
			{
				return null;
			}
			if (_guidToOrb.TryGetValue(guid, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			if ((Object)(object)value == (Object)null && _guidToOrb.ContainsKey(guid))
			{
				_guidToOrb.Remove(guid);
			}
			return null;
		}

		public string GetGuid(GameObject orb)
		{
			if ((Object)(object)orb == (Object)null)
			{
				return null;
			}
			if (!_orbToGuid.TryGetValue(orb, out var value))
			{
				return null;
			}
			return value;
		}

		public string GetId(GameObject ball)
		{
			if ((Object)(object)ball == (Object)null)
			{
				return "unknown";
			}
			Attack component = ball.GetComponent<Attack>();
			if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(component.locNameString))
			{
				return component.locNameString;
			}
			return ((Object)ball).name;
		}

		public int GetLevel(GameObject ball)
		{
			if ((Object)(object)ball == (Object)null)
			{
				return 0;
			}
			return ball.GetComponent<Attack>()?.Level ?? 0;
		}

		public void Clear()
		{
			int count = _guidToOrb.Count;
			_guidToOrb.Clear();
			_orbToGuid.Clear();
			if (count > 0)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)$"[OrbGUID] Cleared {count} entries");
				}
			}
		}
	}
	public static class PatchValidator
	{
		public static List<string> FindMissingPatchTargets(ManualLogSource log)
		{
			List<string> list = new List<string>();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			Type[] array;
			try
			{
				array = executingAssembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				array = ex.Types.Where((Type t) => t != null).ToArray();
				foreach (Exception item in ex.LoaderExceptions?.Where((Exception e) => e != null).Distinct() ?? Array.Empty<Exception>())
				{
					string text = item.Message ?? "Unknown type load error";
					if (log != null)
					{
						log.LogWarning((object)("[PatchValidator] Type load failed: " + text));
					}
					list.Add(text);
				}
			}
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				try
				{
					HarmonyPatch[] array3 = type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Cast<HarmonyPatch>().ToArray();
					if (array3.Length == 0)
					{
						continue;
					}
					Type type2 = null;
					string text2 = null;
					HarmonyPatch[] array4 = array3;
					foreach (HarmonyPatch val in array4)
					{
						if (((HarmonyAttribute)val).info.declaringType != null)
						{
							type2 = ((HarmonyAttribute)val).info.declaringType;
						}
						if (((HarmonyAttribute)val).info.methodName != null)
						{
							text2 = ((HarmonyAttribute)val).info.methodName;
						}
					}
					if (type2 != null && text2 != null && !HasMember(type2, text2))
					{
						list.Add(type2.Name + "." + text2);
					}
					MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					for (int j = 0; j < methods.Length; j++)
					{
						HarmonyPatch[] array5 = methods[j].GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Cast<HarmonyPatch>().ToArray();
						if (array5.Length == 0)
						{
							continue;
						}
						Type type3 = type2;
						string text3 = text2;
						array4 = array5;
						foreach (HarmonyPatch val2 in array4)
						{
							if (((HarmonyAttribute)val2).info.declaringType != null)
							{
								type3 = ((HarmonyAttribute)val2).info.declaringType;
							}
							if (((HarmonyAttribute)val2).info.methodName != null)
							{
								text3 = ((HarmonyAttribute)val2).info.methodName;
							}
						}
						if (type3 != null && text3 != null && !HasMember(type3, text3))
						{
							list.Add(type3.Name + "." + text3);
						}
					}
				}
				catch
				{
				}
			}
			return list.Distinct().ToList();
		}

		private static bool HasMember(Type type, string name)
		{
			return type.GetMember(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Length != 0;
		}
	}
	public class PegIdentifier
	{
		private readonly Dictionary<string, Peg> _guidToPeg = new Dictionary<string, Peg>();

		private readonly Dictionary<Peg, string> _pegToGuid = new Dictionary<Peg, string>();

		private static ManualLogSource Log => MultiplayerPlugin.Logger;

		public int Count => _guidToPeg.Count;

		public string GetOrAssignGuid(Peg peg)
		{
			if ((Object)(object)peg == (Object)null)
			{
				return "null";
			}
			if (_pegToGuid.TryGetValue(peg, out var value))
			{
				return value;
			}
			string text = Guid.NewGuid().ToString("N").Substring(0, 12);
			_guidToPeg[text] = peg;
			_pegToGuid[peg] = text;
			return text;
		}

		public void Register(Peg peg, string guid)
		{
			if (!((Object)(object)peg == (Object)null) && !string.IsNullOrEmpty(guid))
			{
				if (_guidToPeg.TryGetValue(guid, out var value) && (Object)(object)value != (Object)(object)peg)
				{
					_pegToGuid.Remove(value);
				}
				if (_pegToGuid.TryGetValue(peg, out var value2) && value2 != guid)
				{
					_guidToPeg.Remove(value2);
				}
				_guidToPeg[guid] = peg;
				_pegToGuid[peg] = guid;
			}
		}

		public Peg Find(string guid)
		{
			if (string.IsNullOrEmpty(guid))
			{
				return null;
			}
			if (_guidToPeg.TryGetValue(guid, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			if ((Object)(object)value == (Object)null && _guidToPeg.ContainsKey(guid))
			{
				_guidToPeg.Remove(guid);
			}
			return null;
		}

		public string GetGuid(Peg peg)
		{
			if ((Object)(object)peg == (Object)null)
			{
				return null;
			}
			if (!_pegToGuid.TryGetValue(peg, out var value))
			{
				return null;
			}
			return value;
		}

		public void Clear()
		{
			int count = _guidToPeg.Count;
			_guidToPeg.Clear();
			_pegToGuid.Clear();
			if (count > 0)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)$"[PegGUID] Cleared {count} entries");
				}
			}
		}

		public void DumpState(string trigger)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)$"[PegGUID] === DUMP ({trigger}) {_guidToPeg.Count} entries ===");
			}
			int num = 0;
			foreach (KeyValuePair<string, Peg> item in _guidToPeg)
			{
				Peg value = item.Value;
				if ((Object)(object)value != (Object)null)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogInfo((object)$"[PegGUID]   {item.Key} → type={value.pegType} pos=({((Component)value).transform.position.x:F2},{((Component)value).transform.position.y:F2}) active={((Component)value).gameObject.activeSelf}");
					}
				}
				else
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogInfo((object)("[PegGUID]   " + item.Key + " → DESTROYED"));
					}
				}
				if (++num >= 20)
				{
					ManualLogSource log4 = Log;
					if (log4 != null)
					{
						log4.LogInfo((object)$"[PegGUID]   ... and {_guidToPeg.Count - num} more");
					}
					break;
				}
			}
		}
	}
	public sealed class VersionChecker
	{
		private readonly ManualLogSource _log;

		public string CompiledGameVersion => "2.0.12";

		public string ModVersion => "0.1.10";

		public string RuntimeGameVersion { get; private set; }

		public bool IsVersionMatch { get; private set; }

		public VersionChecker(ManualLogSource log)
		{
			_log = log;
		}

		public void Check()
		{
			RuntimeGameVersion = Application.version ?? "unknown";
			IsVersionMatch = RuntimeGameVersion == CompiledGameVersion;
			_log.LogInfo((object)("Mod version: " + ModVersion));
			_log.LogInfo((object)("Compiled against Peglin: " + CompiledGameVersion));
			_log.LogInfo((object)("Running Peglin: " + RuntimeGameVersion));
			if (!IsVersionMatch)
			{
				_log.LogWarning((object)"========================================");
				_log.LogWarning((object)"GAME VERSION MISMATCH");
				_log.LogWarning((object)("  Mod compiled for: " + CompiledGameVersion));
				_log.LogWarning((object)("  Game running:     " + RuntimeGameVersion));
				_log.LogWarning((object)"  Some features may not work correctly.");
				_log.LogWarning((object)"========================================");
			}
		}
	}
}
namespace Multipeglin.UI
{
	public sealed class ClientRelicChoiceApplier : MonoBehaviour
	{
	}
	public static class CoopNavigateSlotPainter
	{
		private static readonly Color WinnerColor = new Color(0.25f, 0.85f, 0.25f, 1f);

		private static readonly Color LoserColor = new Color(0.85f, 0.2f, 0.2f, 1f);

		private static readonly Color ZeroVoteColor = new Color(0.95f, 0.85f, 0.15f, 1f);

		private static List<int> _lastTally;

		private static int _lastChildCount = -1;

		public static void Tick()
		{
			if (!CoopNavigateState.PhaseActive)
			{
				_lastTally = null;
				_lastChildCount = -1;
				return;
			}
			List<int> voteCounts = CoopNavigateState.VoteCounts;
			if (voteCounts == null || voteCounts.Count == 0 || !TallyChanged(voteCounts, CoopNavigateState.ChildNodeCount))
			{
				return;
			}
			_lastTally = new List<int>(voteCounts);
			_lastChildCount = CoopNavigateState.ChildNodeCount;
			try
			{
				if (CoopNavigateState.Source == "nav_only")
				{
					PaintNavOnly(voteCounts, CoopNavigateState.ChildNodeCount);
				}
				else
				{
					PaintPostBattle(voteCounts, CoopNavigateState.ChildNodeCount);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = MultiplayerPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("[CoopNavigate] Slot paint failed: " + ex.Message));
				}
			}
		}

		private static bool TallyChanged(List<int> votes, int childCount)
		{
			if (_lastTally == null || _lastChildCount != childCount || _lastTally.Count != votes.Count)
			{
				return true;
			}
			for (int i = 0; i < votes.Count; i++)
			{
				if (_lastTally[i] != votes[i])
				{
					return true;
				}
			}
			return false;
		}

		private static void PaintPostBattle(List<int> votes, int childCount)
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			PostBattleController[] array = Resources.FindObjectsOfTypeAll<PostBattleController>();
			PostBattleController val = null;
			PostBattleController[] array2 = array;
			foreach (PostBattleController val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && ((Component)val2).gameObject.activeInHierarchy)
				{
					val = val2;
					break;
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				object? obj = AccessTools.Field(typeof(PostBattleController), "_leftSlotManager")?.GetValue(val);
				SlotManager slot = (SlotManager)((obj is SlotManager) ? obj : null);
				object? obj2 = AccessTools.Field(typeof(PostBattleController), "_centerSlotManager")?.GetValue(val);
				SlotManager slot2 = (SlotManager)((obj2 is SlotManager) ? obj2 : null);
				object? obj3 = AccessTools.Field(typeof(PostBattleController), "_rightSlotManager")?.GetValue(val);
				SlotManager slot3 = (SlotManager)((obj3 is SlotManager) ? obj3 : null);
				switch (childCount)
				{
				case 1:
				{
					Color color = ColorFor(votes, 0);
					ApplyColor(slot, color);
					ApplyColor(slot2, color);
					ApplyColor(slot3, color);
					break;
				}
				case 2:
					ApplyColor(slot, ColorFor(votes, 0));
					ApplyColor(slot3, ColorFor(votes, 1));
					break;
				default:
					ApplyColor(slot, ColorFor(votes, 0));
					ApplyColor(slot2, ColorFor(votes, 1));
					ApplyColor(slot3, ColorFor(votes, childCount - 1));
					break;
				}
			}
		}

		private static void PaintNavOnly(List<int> votes, int childCount)
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			NavOnlyController[] array = Resources.FindObjectsOfTypeAll<NavOnlyController>();
			NavOnlyController val = null;
			NavOnlyController[] array2 = array;
			foreach (NavOnlyController val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && ((Component)val2).gameObject.activeInHierarchy)
				{
					val = val2;
					break;
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				object? obj = AccessTools.Field(typeof(NavOnlyController), "_leftSlotManager")?.GetValue(val);
				SlotManager slot = (SlotManager)((obj is SlotManager) ? obj : null);
				object? obj2 = AccessTools.Field(typeof(NavOnlyController), "_centreSlotManager")?.GetValue(val);
				SlotManager slot2 = (SlotManager)((obj2 is SlotManager) ? obj2 : null);
				object? obj3 = AccessTools.Field(typeof(NavOnlyController), "_rightSlotManager")?.GetValue(val);
				SlotManager slot3 = (SlotManager)((obj3 is SlotManager) ? obj3 : null);
				if (childCount == 1)
				{
					Color color = ColorFor(votes, 0);
					ApplyColor(slot, color);
					ApplyColor(slot2, color);
					ApplyColor(slot3, color);
				}
				else
				{
					ApplyColor(slot, ColorFor(votes, 0));
					ApplyColor(slot3, ColorFor(votes, childCount - 1));
				}
			}
		}

		private static Color ColorFor(List<int> votes, int childIdx)
		{
			//IL_000d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (childIdx < 0 || childIdx >= votes.Count)
			{
				return ZeroVoteColor;
			}
			if (votes[childIdx] == 0)
			{
				return ZeroVoteColor;
			}
			int num = 0;
			for (int i = 0; i < votes.Count; i++)
			{
				if (votes[i] > num)
				{
					num = votes[i];
				}
			}
			if (votes[childIdx] != num)
			{
				return LoserColor;
			}
			return WinnerColor;
		}

		private static void ApplyColor(SlotManager slot, Color color)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)slot == (Object)null) && ((Component)slot).gameObject.activeInHierarchy)
			{
				if ((Object)(object)slot.highlightHalf != (Object)null && ((Component)slot.highlightHalf).gameObject.activeInHierarchy)
				{
					Color color2 = slot.highlightHalf.color;
					slot.highlightHalf.color = new Color(color.r, color.g, color.b, (color2.a > 0f) ? color2.a : 1f);
				}
				if ((Object)(object)slot.highlightFull != (Object)null && ((Component)slot.highlightFull).gameObject.activeInHierarchy)
				{
					Color color3 = slot.highlightFull.color;
					slot.highlightFull.color = new Color(color.r, color.g, color.b, (color3.a > 0f) ? color3.a : 1f);
				}
			}
		}
	}
	public class CoopPlayerVisuals : MonoBehaviour
	{
		private class PlayerVisual
		{
			public int SlotIndex;

			public GameObject SpriteClone;

			public GameObject NamePanel;

			public TextMeshProUGUI NameText;

			public GameObject HpPanel;

			public TextMeshProUGUI HpText;

			public GameObject ArrowPanel;

			public TextMeshProUGUI ArrowText;

			public GameObject StatusIconContainer;

			public Dictionary<int, StatusIconEntry> StatusIcons = new Dictionary<int, StatusIconEntry>();
		}

		private class StatusIconEntry
		{
			public GameObject Root;

			public Image IconImage;

			public TextMeshProUGUI IntensityText;

			public StatusIconHoverHandler Hover;
		}

		internal class StatusIconHoverHandler : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
		{
			public StatusEffectType EffectType;

			public Vector3 WorldAnchor;

			private bool _tooltipShowing;

			public void OnPointerEnter(PointerEventData eventData)
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				if (_tooltipShowing)
				{
					return;
				}
				TooltipManager instance = TooltipManager.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				try
				{
					instance.ShowTooltipStatusEffect(EffectType, WorldAnchor, new Vector3(1f, -1f), true, false);
					_tooltipShowing = true;
				}
				catch
				{
				}
			}

			public void OnPointerExit(PointerEventData eventData)
			{
				if (!_tooltipShowing)
				{
					return;
				}
				try
				{
					TooltipManager instance = TooltipManager.Instance;
					if (instance != null)
					{
						instance.HideTooltip();
					}
				}
				catch
				{
				}
				_tooltipShowing = false;
			}

			private void OnDisable()
			{
				if (!_tooltipShowing)
				{
					return;
				}
				try
				{
					TooltipManager instance = TooltipManager.Instance;
					if (instance != null)
					{
						instance.HideTooltip();
					}
				}
				catch
				{
				}
				_tooltipShowing = false;
			}
		}

		private static StatusEffectData _statusEffectData;

		private static bool _statusEffectDataSearched;

		private readonly List<PlayerVisual> _visuals = new List<PlayerVisual>();

		private bool _inBattle;

		private string _lastScene = string.Empty;

		private GameObject _playerRef;

		private PlayerVisual _hostLabel;

		private bool _updateErrorLogged;

		private PlayerStatusEffectController _cachedStatusCtrl;

		private float _lastHeavyTickTime;

		private const float HeavyTickInterval = 0.2f;

		private readonly HashSet<int> _activeTypesScratch = new HashSet<int>();

		private readonly List<int> _removeScratch = new List<int>();

		private static GameObject _overlayCanvasObj;

		private static Canvas _overlayCanvas;

		private static RectTransform _overlayCanvasRect;

		private static TMP_FontAsset _gameFont;

		private static bool _gameFontSearched;

		private static TMP_FontAsset _numberFont;

		private static bool _numberFontSearched;

		private const int HostSlot = 0;

		private static readonly Color _nameColorBase = new Color(0.9f, 0.5f, 0.1f);

		private static readonly Color _nameColorActive = new Color(1f, 0.95f, 0.4f);

		private static readonly Color _arrowColorDim = new Color(1f, 0.9f, 0.3f, 0.5f);

		private static readonly Color _arrowColorBright = new Color(1f, 1f, 0.6f, 1f);

		private static readonly HashSet<int> _loggedMissingClassSprite = new HashSet<int>();

		private static Sprite _cachedPeglinSprite;

		private static Sprite _cachedBalladinSprite;

		private static Sprite _cachedRoundrelSprite;

		private static Sprite _cachedSpinventorSprite;

		private static RuntimeAnimatorController _cachedPeglinCtrl;

		private static RuntimeAnimatorController _cachedBalladinCtrl;

		private static RuntimeAnimatorController _cachedRoundrelCtrl;

		private static RuntimeAnimatorController _cachedSpinventorCtrl;

		private static readonly HashSet<int> _loggedMissingClassCtrl = new HashSet<int>();

		private static readonly HashSet<int> _addressableAttempted = new HashSet<int>();

		private static ManualLogSource Log => MultiplayerPlugin.Logger;

		public static List<CoopPlayerSummary> LatestPlayerSummaries { get; set; }

		public static int LatestActiveSlot { get; set; } = -1;


		private void Update()
		{
			//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)
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				if (name != _lastScene)
				{
					_lastScene = name;
					CleanupVisuals();
					_playerRef = null;
					_inBattle = false;
					_updateErrorLogged = false;
					_cachedStatusCtrl = null;
					_lastHeavyTickTime = 0f;
				}
				IServiceContainer services = MultiplayerPlugin.Services;
				if (services == null || !services.TryResolve<IMultiplayerMode>(out var instance) || (!instance.IsHosting && !instance.IsSpectating))
				{
					return;
				}
				if (name != "Battle")
				{
					if (_inBattle)
					{
						CleanupVisuals();
						_inBattle = false;
					}
					return;
				}
				_inBattle = true;
				float unscaledTime = Time.unscaledTime;
				if (unscaledTime - _lastHeavyTickTime >= 0.2f)
				{
					_lastHeavyTickTime = unscaledTime;
					HideNativeStatusIcons();
					if (instance.IsHosting)
					{
						BuildHostSummaries(services);
					}
				}
				List<CoopPlayerSummary> latestPlayerSummaries = LatestPlayerSummaries;
				if (latestPlayerSummaries == null || latestPlayerSummaries.Count <= 1)
				{
					return;
				}
				if ((Object)(object)_playerRef == (Object)null)
				{
					_playerRef = GameObject.FindGameObjectWithTag("Player");
					if ((Object)(object)_playerRef == (Object)null)
					{
						return;
					}
				}
				if (!((Object)(object)Camera.main == (Object)null))
				{
					EnsureVisuals(latestPlayerSummaries);
					UpdateVisuals(latestPlayerSummaries);
					_updateErrorLogged = false;
				}
			}
			catch (Exception arg)
			{
				if (!_updateErrorLogged)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)$"[CoopPlayerVisuals] Update error (will suppress repeats): {arg}");
					}
					_updateErrorLogged = true;
				}
			}
		}

		private void BuildHostSummaries(IServiceContainer services)
		{
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!services.TryResolve<CoopStateManager>(out var instance) || instance.TotalPlayerCount < 2)
				{
					return;
				}
				List<StatusEffectEntry> list = null;
				try
				{
					PlayerStatusEffectController cachedStatusController = GetCachedStatusController();
					if ((Object)(object)cachedStatusController != (Object)null && AccessTools.Field(typeof(PlayerStatusEffectController), "_statusEffects")?.GetValue(cachedStatusController) is IList list2 && list2.Count > 0)
					{
						list = new List<StatusEffectEntry>();
						foreach (object item in list2)
						{
							FieldInfo fieldInfo = AccessTools.Field(item.GetType(), "EffectType");
							FieldInfo fieldInfo2 = AccessTools.Field(item.GetType(), "Intensity");
							if (!(fieldInfo == null))
							{
								object value = fieldInfo.GetValue(item);
								int num = (int)(fieldInfo2?.GetValue(item) ?? ((object)0));
								if (num > 0)
								{
									list.Add(new StatusEffectEntry
									{
										EffectType = (int)value,
										EffectName = value.ToString(),
										Intensity = num
									});
								}
							}
						}
					}
				}
				catch
				{
				}
				float num2 = -1f;
				float num3 = -1f;
				try
				{
					PlayerHealthController val = Object.FindObjectOfType<PlayerHealthController>();
					if ((Object)(object)val != (Object)null)
					{
						num2 = val.CurrentHealth;
						num3 = val.MaxHealth;
					}
				}
				catch
				{
				}
				List<CoopPlayerSummary> list3 = new List<CoopPlayerSummary>();
				foreach (KeyValuePair<int, CoopPlayerState> playerState in instance.PlayerStates)
				{
					CoopPlayerState value2 = playerState.Value;
					bool num4 = value2.SlotIndex == instance.ActivePlayerSlot;
					float currentHealth = ((num4 && num2 >= 0f) ? num2 : value2.CurrentHealth);
					float maxHealth = ((num4 && num3 > 0f) ? num3 : value2.MaxHealth);
					CoopPlayerSummary coopPlayerSummary = new CoopPlayerSummary
					{
						SlotIndex = value2.SlotIndex,
						PlayerName = value2.PlayerName,
						ChosenClass = value2.ChosenClass,
						CurrentHealth = currentHealth,
						MaxHealth = maxHealth,
						Gold = value2.Gold,
						HasShotThisRound = value2.HasShotThisRound
					};
					if (num4 && list != null)
					{
						coopPlayerSummary.StatusEffects = list;
					}
					else if (value2.StatusEffects != null)
					{
						foreach (SerializedStatusEffect statusEffect in value2.StatusEffects)
						{
							List<StatusEffectEntry> statusEffects = coopPlayerSummary.StatusEffects;
							StatusEffectEntry obj3 = new StatusEffectEntry
							{
								EffectType = statusEffect.EffectType
							};
							StatusEffectType val2 = (StatusEffectType)statusEffect.EffectType;
							obj3.EffectName = ((object)(StatusEffectType)(ref val2)).ToString();
							obj3.Intensity = statusEffect.Intensity;
							statusEffects.Add(obj3);
						}
					}
					list3.Add(coopPlayerSummary);
				}
				LatestPlayerSummaries = list3;
				LatestActiveSlot = instance.ActivePlayerSlot;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)("[CoopPlayerVisuals] BuildHostSummaries failed: " + ex.Message));
				}
			}
		}

		private void OnDestroy()
		{
			CleanupVisuals();
		}

		private void EnsureVisuals(List<CoopPlayerSummary> summaries)
		{
			int localSlotIndex = GetLocalSlotIndex();
			CoopPlayerSummary coopPlayerSummary = null;
			foreach (CoopPlayerSummary summary in summaries)
			{
				if (summary.SlotIndex == 0)
				{
					coopPlayerSummary = summary;
					break;
				}
			}
			for (int num = _visuals.Count - 1; num >= 0; num--)
			{
				PlayerVisual playerVisual = _visuals[num];
				bool flag = false;
				foreach (CoopPlayerSummary summary2 in summaries)
				{
					if (summary2.SlotIndex == playerVisual.SlotIndex)
					{
						flag = true;
						break;
					}
				}
				if (!flag || (Object)(object)playerVisual.SpriteClone == (Object)null || playerVisual.SlotIndex == 0)
				{
					DestroyVisual(playerVisual);
					_visuals.RemoveAt(num);
				}
			}
			if (_hostLabel != null && (Object)(object)_hostLabel.NamePanel == (Object)null)
			{
				_hostLabel = null;
			}
			if (_hostLabel == null && (Object)(object)_playerRef != (Object)null && coopPlayerSummary != null)
			{
				_hostLabel = CreatePlayerLabels(coopPlayerSummary, null);
			}
			if (localSlotIndex != 0 && coopPlayerSummary != null && (Object)(object)_playerRef != (Object)null)
			{
				ApplyHostClassToPlayerRef(coopPlayerSummary.ChosenClass);
			}
			foreach (CoopPlayerSummary summary3 in summaries)
			{
				if (summary3.SlotIndex == 0)
				{
					continue;
				}
				bool flag2 = false;
				foreach (PlayerVisual visual in _visuals)
				{
					if (visual.SlotIndex == summary3.SlotIndex)
					{
						flag2 = true;
						break;
					}
				}
				if (!flag2)
				{
					PlayerVisual playerVisual2 = CreatePlayerVisual(summary3);
					if (playerVisual2 != null)
					{
						_visuals.Add(playerVisual2);
					}
				}
			}
		}

		private static int GetLocalSlotIndex()
		{
			try
			{
				return CoopSlotHelper.GetLocalSlotIndex(MultiplayerPlugin.Services);
			}
			catch
			{
				return -1;
			}
		}

		private void EnsureOverlayCanvas()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_overlayCanvasObj != (Object)null))
			{
				_overlayCanvasObj = new GameObject("CoopPlayerLabelsOverlay");
				Object.DontDestroyOnLoad((Object)(object)_overlayCanvasObj);
				_overlayCanvas = _overlayCanvasObj.AddComponent<Canvas>();
				_overlayCanvas.renderMode = (RenderMode)0;
				_overlayCanvas.sortingOrder = 9000;
				CanvasScaler obj = _overlayCanvasObj.AddComponent<CanvasScaler>();
				obj.uiScaleMode = (ScaleMode)1;
				obj.referenceResolution = new Vector2(1920f, 1080f);
				obj.matchWidthOrHeight = 0.5f;
				_overlayCanvasObj.AddComponent<GraphicRaycaster>();
				_overlayCanvasRect = _overlayCanvasObj.GetComponent<RectTransform>();
			}
		}

		private static TMP_FontAsset GetGameFont()
		{
			if (_gameFontSearched)
			{
				return _gameFont;
			}
			_gameFontSearched = true;
			try
			{
				TextMeshProUGUI[] array = Object.FindObjectsOfType<TextMeshProUGUI>();
				foreach (TextMeshProUGUI val in array)
				{
					if ((Object)(object)((TMP_Text)val).font != (Object)null)
					{
						_gameFont = ((TMP_Text)val).font;
						break;
					}
				}
			}
			catch
			{
			}
			return _gameFont;
		}

		private static TMP_FontAsset GetStatusEffectNumberFont()
		{
			if (_numberFontSearched)
			{
				return _numberFont ?? GetGameFont();
			}
			_numberFontSearched = true;
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(StatusEffectIcon), "_intensityText");
				if (fieldInfo != null)
				{
					StatusEffectIcon[] array = Resources.FindObjectsOfTypeAll<StatusEffectIcon>();
					foreach (StatusEffectIcon val in array)
					{
						if (!((Object)(object)val == (Object)null))
						{
							object? value = fieldInfo.GetValue(val);
							TextMeshProUGUI val2 = (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null);
							if ((Object)(object)((val2 != null) ? ((TMP_Text)val2).font : null) != (Object)null)
							{
								_numberFont = ((TMP_Text)val2).font;
								break;
							}
						}
					}
				}
			}
			catch
			{
			}
			return _numberFont ?? GetGameFont();
		}

		private static string FormatName(string name, int slot)
		{
			if (string.IsNullOrEmpty(name))
			{
				name = $"P{slot}";
			}
			if (name.Length > 14)
			{
				name = name.Substring(0, 14);
			}
			if (name.Length > 7)
			{
				name = name.Substring(0, 7) + "\n" + name.Substring(7);
			}
			return name;
		}

		private GameObject CreateTextPanel(string goName, float width, float height, string text, float fontSize, Color textColor, Color bgColor, out TextMeshProUGUI tmpText)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_002c: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			EnsureOverlayCanvas();
			GameObject val = new GameObject(goName);
			val.transform.SetParent(_overlayCanvasObj.transform, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.sizeDelta = new Vector2(width, height);
			obj.pivot = new Vector2(0.5f, 0.5f);
			Image obj2 = val.AddComponent<Image>();
			((Graphic)obj2).color = bgColor;
			((Graphic)obj2).raycastTarget = false;
			GameObject val2 = new GameObject("Text");
			val2.transform.SetParent(val.transform, false);
			tmpText = val2.AddComponent<TextMeshProUGUI>();
			((TMP_Text)tmpText).text = text;
			((TMP_Text)tmpText).fontSize = fontSize;
			((TMP_Text)tmpText).fontStyle = (FontStyles)1;
			TMP_FontAsset gameFont = GetGameFont();
			if ((Object)(object)gameFont != (Object)null)
			{
				((TMP_Text)tmpText).font = gameFont;
			}
			((TMP_Text)tmpText).alignment = (TextAlignmentOptions)514;
			((Graphic)tmpText).color = textColor;
			try
			{
				((TMP_Text)tmpText).outlineWidth = 0.3f;
			}
			catch
			{
			}
			try
			{
				((TMP_Text)tmpText).outlineColor = Color32.op_Implicit(Color.black);
			}
			catch
			{
			}
			((TMP_Text)tmpText).enableWordWrapping = false;
			((TMP_Text)tmpText).overflowMode = (TextOverflowModes)0;
			((TMP_Text)tmpText).lineSpacing = -25f;
			((Graphic)tmpText).raycastTarget = false;
			RectTransform rectTransform = ((TMP_Text)tmpText).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.offsetMin = Vector2.zero;
			rectTransform.offsetMax = Vector2.zero;
			return val;
		}

		private PlayerVisual CreatePlayerLabels(CoopPlayerSummary summary, GameObject spriteClone)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Color textColor = default(Color);
				((Color)(ref textColor))..ctor(0.9f, 0.5f, 0.1f);
				Color textColor2 = default(Color);
				((Color)(ref textColor2))..ctor(0.6f, 1f, 0.6f);
				Color textColor3 = default(Color);
				((Color)(ref textColor3))..ctor(1f, 0.9f, 0.3f);
				Color bgColor = default(Color);
				((Color)(ref bgColor))..ctor(0f, 0f, 0f, 0.3f);
				string text = FormatName(summary.PlayerName, summary.SlotIndex);
				bool flag = text.Contains("\n");
				TextMeshProUGUI tmpText;
				GameObject namePanel = CreateTextPanel($"CoopName_Slot{summary.SlotIndex}", 187f, flag ? 80 : 50, text, 45f, textColor, bgColor, out tmpText);
				TextMeshProUGUI tmpText2;
				GameObject hpPanel = CreateTextPanel($"CoopHP_Slot{summary.SlotIndex}", 160f, 45f, $"{summary.CurrentHealth:F0}/{summary.MaxHealth:F0}", 38f, textColor2, bgColor, out tmpText2);
				TextMeshProUGUI tmpText3;
				GameObject val = CreateTextPanel($"CoopArrow_Slot{summary.SlotIndex}", 80f, 100f, "◀", 64f, textColor3, new Color(0f, 0f, 0f, 0f), out tmpText3);
				val.SetActive(false);
				EnsureOverlayCanvas();
				GameObject val2 = new GameObject($"CoopStatusIcons_Slot{summary.SlotIndex}");
				val2.transform.SetParent(_overlayCanvasObj.transform, false);
				RectTransform obj = val2.AddComponent<RectTransform>();
				obj.sizeDelta = new Vector2(380f, 56f);
				obj.pivot = new Vector2(0.5f, 0.5f);
				HorizontalLayoutGroup obj2 = val2.AddComponent<HorizontalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f;
				((LayoutGroup)obj2).childAlignment = (TextAnchor)4;
				((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
				((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
				val2.SetActive(false);
				return new PlayerVisual
				{
					SlotIndex = summary.SlotIndex,
					SpriteClone = spriteClone,
					NamePanel = namePanel,
					NameText = tmpText,
					HpPanel = hpPanel,
					HpText = tmpText2,
					ArrowPanel = val,
					ArrowText = tmpText3,
					StatusIconContainer = val2
				};
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)$"[CoopPlayerVisuals] CreatePlayerLabels failed for slot {summary.SlotIndex}: {ex.Message}");
				}
				return null;
			}
		}

		private PlayerVisual CreatePlayerVisual(CoopPlayerSummary summary)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_playerRef == (Object)null)
			{
				return null;
			}
			try
			{
				GameObject val = new GameObject($"CoopPlayer_Slot{summary.SlotIndex}");
				val.transform.position = _playerRef.transform.position;
				val.layer = _playerRef.layer;
				SpriteRenderer val2 = FindPlayerSpriteRenderer();
				if ((Object)(object)val2 != (Object)null)
				{
					SpriteRenderer obj = val.AddComponent<SpriteRenderer>();
					Sprite val3 = (obj.sprite = GetClassBaseSprite(summary.ChosenClass));
					if ((Object)(object)val3 == (Object)null)
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogWarning((object)$"[CoopPlayerVisuals] GetClassBaseSprite returned null for slot {summary.SlotIndex} class {summary.ChosenClass}");
						}
					}
					((Renderer)obj).material = ((Renderer)val2).material;
					((Renderer)obj).sortingLayerID = ((Renderer)val2).sortingLayerID;
					((Renderer)obj).sortingOrder = ((Renderer)val2).sortingOrder - 1;
					obj.color = GetSlotColor(summary.SlotIndex);
					obj.flipX = val2.flipX;
					obj.flipY = val2.flipY;
					Animator val4 = val.AddComponent<Animator>();
					RuntimeAnimatorController classAnimationController = GetClassAnimationController(summary.ChosenClass);
					if ((Object)(object)classAnimationController != (Object)null)
					{
						val4.runtimeAnimatorController = classAnimationController;
					}
				}
				else
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)$"[CoopPlayerVisuals] No SpriteRenderer found on _playerRef for slot {summary.SlotIndex}");
					}
				}
				return CreatePlayerLabels(summary, val);
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Log;
				if (log3 != null)
				{
					log3.LogError((object)$"[CoopPlayerVisuals] Failed to create visual for slot {summary.SlotIndex}: {ex.Message}");
				}
				return null;
			}
		}

		private SpriteRenderer FindPlayerSpriteRenderer()
		{
			if ((Object)(object)_playerRef == (Object)null)
			{
				return null;
			}
			SpriteRenderer component = _playerRef.GetComponent<SpriteRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			return _playerRef.GetComponentInChildren<SpriteRenderer>(true);
		}

		private void ApplyHostClassToPlayerRef(int hostClass)
		{
			//IL_001c: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected I4, but got Unknown
			try
			{
				SpriteRenderer val = FindPlayerSpriteRenderer();
				PeglinClassAnimationSwitcher val2 = FindClassAnimationSwitcher();
				if (!((Object)(object)val2 == (Object)null))
				{
					Class val3 = (Class)hostClass;
					Sprite val4;
					RuntimeAnimatorController val5;
					switch (val3 - 1)
					{
					case 0:
						val4 = val2.balladinBaseSprite;
						val5 = val2.balladinAnimationController;
						break;
					case 1:
						val4 = val2.roundrelBaseSprite;
						val5 = val2.roundrelAnimationController;
						break;
					case 2:
						val4 = val2.spinventorBaseSprite;
						val5 = val2.spinventorAnimationController;
						break;
					default:
						val4 = val2.peglinBaseSprite;
						val5 = val2.peglinAnimationController;
						break;
					}
					Animator component = ((Component)val2).GetComponent<Animator>();
					if ((Object)(object)component != (Object)null && (Object)(object)val5 != (Object)null && (Object)(object)component.runtimeAnimatorController != (Object)(object)val5)
					{
						component.runtimeAnimatorController = val5;
					}
					if ((Object)(object)val != (Object)null && (Object)(object)val4 != (Object)null && (Object)(object)val.sprite != (Object)(object)val4)
					{
						val.sprite = val4;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[CoopPlayerVisuals] ApplyHostClassToPlayerRef failed: " + ex.Message));
				}
			}
		}

		private static PeglinClassAnimationSwitcher FindClassAnimationSwitcher()
		{
			try
			{
				GameObject val = GameObject.FindGameObjectWithTag("Player");
				if ((Object)(object)val != (Object)null)
				{
					PeglinClassAnimationSwitcher val2 = val.GetComponentInChildren<PeglinClassAnimationSwitcher>(true) ?? val.GetComponentInParent<PeglinClassAnimationSwitcher>();
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
				PeglinClassAnimationSwitcher val3 = Object.FindObjectOfType<PeglinClassAnimationSwitcher>();
				if ((Object)(object)val3 != (Object)null)
				{
					return val3;
				}
				PeglinClassAnimationSwitcher[] array = Resources.FindObjectsOfTypeAll<PeglinClassAnimationSwitcher>();
				if (array != null && array.Length != 0)
				{
					return array[0];
				}
			}
			catch
			{
			}
			return null;
		}

		private void UpdateVisuals(List<CoopPlayerSummary> summaries)
		{
			//IL_002a: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_playerRef == (Object)null)
			{
				return;
			}
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return;
			}
			Vector3 position = _playerRef.transform.position;
			int latestActiveSlot = LatestActiveSlot;
			try
			{
				float num = ((latestActiveSlot == 0) ? 1.15f : 1f);
				_playerRef.transform.localScale = Vector3.Lerp(_playerRef.transform.localScale, Vector3.one * num, Time.deltaTime * 5f);
			}
			catch
			{
			}
			if (_hostLabel != null)
			{
				CoopPlayerSummary coopPlayerSummary = null;
				foreach (CoopPlayerSummary summary in summaries)
				{
					if (summary.SlotIndex == 0)
					{
						coopPlayerSummary = summary;
						break;
					}
				}
				if (coopPlayerSummary != null)
				{
					UpdatePlayerLabel(_hostLabel, coopPlayerSummary, position, latestActiveSlot, main);
				}
			}
			Vector3 val = default(Vector3);
			foreach (PlayerVisual visual in _visuals)
			{
				if ((Object)(object)visual.SpriteClone == (Object)null)
				{
					continue;
				}
				CoopPlayerSummary coopPlayerSummary2 = null;
				foreach (CoopPlayerSummary summary2 in summaries)
				{
					if (summary2.SlotIndex == visual.SlotIndex)
					{
						coopPlayerSummary2 = summary2;
						break;
					}
				}
				if (coopPlayerSummary2 == null)
				{
					continue;
				}
				((Vector3)(ref val))..ctor(-2.5f * (float)visual.SlotIndex, -0.2f * (float)visual.SlotIndex, 0f);
				visual.SpriteClone.transform.position = position + val;
				Vector3 position2 = visual.SpriteClone.transform.position;
				UpdatePlayerLabel(visual, coopPlayerSummary2, position2, latestActiveSlot, main);
				float num2 = ((latestActiveSlot == visual.SlotIndex) ? 1.15f : 1f);
				visual.SpriteClone.transform.localScale = Vector3.Lerp(visual.SpriteClone.transform.localScale, Vector3.one * num2, Time.deltaTime * 5f);
				SpriteRenderer component = visual.SpriteClone.GetComponent<SpriteRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					if ((Object)(object)component.sprite == (Object)null)
					{
						Sprite classBaseSprite = GetClassBaseSprite(coopPlayerSummary2.ChosenClass);
						if ((Object)(object)classBaseSprite != (Object)null)
						{
							component.sprite = classBaseSprite;
						}
					}
					Color slotColor = GetSlotColor(visual.SlotIndex);
					component.color = ((latestActiveSlot == visual.SlotIndex) ? Color.Lerp(component.color, Color.white, Time.deltaTime * 3f) : Color.Lerp(component.color, slotColor, Time.deltaTime * 3f));
				}
				Animator component2 = visual.SpriteClone.GetComponent<Animator>();
				if ((Object)(object)component2 != (Object)null && (Object)(object)component2.runtimeAnimatorController == (Object)null)
				{
					RuntimeAnimatorController classAnimationController = GetClassAnimationController(coopPlayerSummary2.ChosenClass);
					if ((Object)(object)classAnimationController != (Object)null)
					{
						component2.runtimeAnimatorController = classAnimationController;
					}
				}
			}
		}

		private void UpdatePlayerLabel(PlayerVisual visual, CoopPlayerSummary summary, Vector3 charPos, int activeSlot, Camera cam)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			if (visual == null || (Object)(object)cam == (Object)null)
			{
				return;
			}
			if ((Object)(object)visual.HpText != (Object)null)
			{
				((TMP_Text)visual.HpText).text = $"{summary.CurrentHealth:F0}/{summary.MaxHealth:F0}";
			}
			if ((Object)(object)visual.NameText != (Object)null)
			{
				((TMP_Text)visual.NameText).text = FormatName(summary.PlayerName, summary.SlotIndex);
			}
			PositionPanelAtWorld(visual.NamePanel, charPos + new Vector3(0f, 2f, 0f), cam);
			PositionPanelAtWorld(visual.HpPanel, charPos + new Vector3(0f, -0.6f, 0f), cam);
			bool flag = activeSlot == visual.SlotIndex;
			if ((Object)(object)visual.NameText != (Object)null)
			{
				if (flag)
				{
					float num = (Mathf.Sin(Time.unscaledTime * 3f) + 1f) * 0.5f;
					((Graphic)visual.NameText).color = Color.Lerp(_nameColorBase, _nameColorActive, num);
				}
				else
				{
					((Graphic)visual.NameText).color = _nameColorBase;
				}
			}
			if ((Object)(object)visual.ArrowPanel != (Object)null)
			{
				visual.ArrowPanel.SetActive(flag);
				if (flag)
				{
					PositionPanelAtWorld(visual.ArrowPanel, charPos + new Vector3(1f, 0.5f, 0f), cam);
					float num2 = (Mathf.Sin(Time.unscaledTime * 4f) + 1f) * 0.5f;
					float num3 = Mathf.Lerp(0.85f, 1.15f, num2);
					visual.ArrowPanel.transform.localScale = new Vector3(num3, num3, 1f);
					if ((Object)(object)visual.ArrowText != (Object)null)
					{
						((Graphic)visual.ArrowText).color = Color.Lerp(_arrowColorDim, _arrowColorBright, num2);
					}
				}
			}
			UpdateStatusIcons(visual, summary.StatusEffects, charPos, cam);
		}

		private void UpdateStatusIcons(PlayerVisual visual, List<StatusEffectEntry> effects, Vector3 charPos, Camera cam)
		{
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)visual.StatusIconContainer == (Object)null)
			{
				return;
			}
			bool flag = effects != null && effects.Count > 0;
			_activeTypesScratch.Clear();
			_removeScratch.Clear();
			if (flag)
			{
				foreach (StatusEffectEntry effect in effects)
				{
					if (effect.Intensity > 0)
					{
						_activeTypesScratch.Add(effect.EffectType);
					}
				}
			}
			foreach (KeyValuePair<int, StatusIconEntry> statusIcon in visual.StatusIcons)
			{
				if (_activeTypesScratch.Contains(statusIcon.Key))
				{
					continue;
				}
				try
				{
					if ((Object)(object)statusIcon.Value.Root != (Object)null)
					{
						Object.Destroy((Object)(object)statusIcon.Value.Root);
					}
				}
				catch
				{
				}
				_removeScratch.Add(statusIcon.Key);
			}
			foreach (int item in _removeScratch)
			{
				visual.StatusIcons.Remove(item);
			}
			if (!flag)
			{
				visual.StatusIconContainer.SetActive(false);
				return;
			}
			foreach (StatusEffectEntry effect2 in effects)
			{
				if (effect2.Intensity <= 0)
				{
					continue;
				}
				if (visual.StatusIcons.TryGetValue(effect2.EffectType, out var value))
				{
					if ((Object)(object)value.IntensityText != (Object)null)
					{
						((TMP_Text)value.IntensityText).text = ((effect2.Intensity > 999) ? (effect2.Intensity / 1000 + "K") : effect2.Intensity.ToString());
					}
					continue;
				}
				StatusIconEntry statusIconEntry = CreateStatusIcon(effect2.EffectType, effect2.Intensity, visual.StatusIconContainer.transform);
				if (statusIconEntry != null)
				{
					visual.StatusIcons[effect2.EffectType] = statusIconEntry;
				}
			}
			visual.StatusIconContainer.SetActive(true);
			PositionPanelAtWorld(visual.StatusIconContainer, charPos + new Vector3(0f, 2.9f, 0f), cam);
			Vector3 worldAnchor = charPos + new Vector3(0f, 2.2f, 0f);
			foreach (KeyValuePair<int, StatusIconEntry> statusIcon2 in visual.StatusIcons)
			{
				if ((Object)(object)statusIcon2.Value.Hover != (Object)null)
				{
					statusIcon2.Value.Hover.WorldAnchor = worldAnchor;
				}
			}
		}

		private StatusIconEntry CreateStatusIcon(int effectType, int intensity, Transform parent)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = new GameObject($"StatusIcon_{effectType}", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(parent, false);
				RectTransform component = val.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.sizeDelta = new Vector2(50f, 50f);
				}
				LayoutElement val2 = val.AddComponent<LayoutElement>();
				if ((Object)(object)val2 != (Object)null)
				{
					val2.preferredWidth = 50f;
					val2.preferredHeight = 50f;
				}
				Image val3 = val.AddComponent<Image>();
				if ((Object)(object)val3 != (Object)null)
				{
					Sprite statusEffectSprite = GetStatusEffectSprite(effectType);
					if ((Object)(object)statusEffectSprite != (Object)null)
					{
						val3.sprite = statusEffectSprite;
						val3.preserveAspect = true;
					}
					else
					{
						((Graphic)val3).color = new Color(0.4f, 0.3f, 0.6f, 0.8f);
					}
					((Graphic)val3).raycastTarget = true;
				}
				StatusIconHoverHandler statusIconHoverHandler = val.AddComponent<StatusIconHoverHandler>();
				statusIconHoverHandler.EffectType = (StatusEffectType)effectType;
				GameObject val4 = new GameObject("Intensity", new Type[1] { typeof(RectTransform) });
				val4.transform.SetParent(val.transform, false);
				TextMeshProUGUI val5 = val4.AddComponent<TextMeshProUGUI>();
				if ((Object)(object)val5 == (Object)null)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)$"[CoopPlayerVisuals] AddComponent<TextMeshProUGUI> returned null for effect {effectType}");
					}
					return new StatusIconEntry
					{
						Root = val,
						IconImage = val3,
						IntensityText = null
					};
				}
				((TMP_Text)val5).text = ((intensity > 999) ? (intensity / 1000 + "K") : intensity.ToString());
				((TMP_Text)val5).fontSize = 32f;
				((TMP_Text)val5).fontStyle = (FontStyles)0;
				TMP_FontAsset statusEffectNumberFont = GetStatusEffectNumberFont();
				if ((Object)(object)statusEffectNumberFont != (Object)null)
				{
					((TMP_Text)val5).font = statusEffectNumberFont;
				}
				((TMP_Text)val5).alignment = (TextAlignmentOptions)1028;
				((Graphic)val5).color = Color.white;
				try
				{
					((TMP_Text)val5).outlineWidth = 0.35f;
				}
				catch
				{
				}
				try
				{
					((TMP_Text)val5).outlineColor = Color32.op_Implicit(Color.black);
				}
				catch
				{
				}
				((TMP_Text)val5).enableWordWrapping = false;
				((TMP_Text)val5).overflowMode = (TextOverflowModes)0;
				((Graphic)val5).raycastTarget = false;
				RectTransform rectTransform = ((TMP_Text)val5).rectTransform;
				if ((Object)(object)rectTransform != (Object)null)
				{
					rectTransform.anchorMin = new Vector2(1f, 0f);
					rectTransform.anchorMax = new Vector2(1f, 0f);
					rectTransform.pivot = new Vector2(1f, 0f);
					rectTransform.sizeDelta = new Vector2(44f, 30f);
					rectTransform.anchoredPosition = new Vector2(8f, -6f);
				}
				return new StatusIconEntry
				{
					Root = val,
					IconImage = val3,
					IntensityText = val5,
					Hover = statusIconHoverHandler
				};
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)$"[CoopPlayerVisuals] CreateStatusIcon({effectType}, {intensity}) failed: {arg}");
				}
				return null;
			}
		}

		private void HideNativeStatusIcons()
		{
			try
			{
				PlayerStatusEffectController cachedStatusController = GetCachedStatusController();
				if (!((Object)(object)cachedStatusController == (Object)null))
				{
					object? obj = AccessTools.Field(typeof(PlayerStatusEffectController), "_statusEffectUI")?.GetValue(cachedStatusController);
					StatusEffectIconManager val = (StatusEffectIconManager)((obj is StatusEffectIconManager) ? obj : null);
					if (!((Object)(object)val == (Object)null) && (Object)(object)val.horizontalContainer != (Object)null && ((Component)val.horizontalContainer).gameObject.activeSelf)
					{
						((Component)val.horizontalContainer).gameObject.SetActive(false);
					}
				}
			}
			catch
			{
			}
		}

		private PlayerStatusEffectController GetCachedStatusController()
		{
			if ((Object)(object)_cachedStatusCtrl == (Object)null)
			{
				_cachedStatusCtrl = Object.FindObjectOfType<PlayerStatusEffectController>();
			}
			return _cachedStatusCtrl;
		}

		private static StatusEffectData GetStatusEffectData()
		{
			if (_statusEffectDataSearched)
			{
				return _statusEffectData;
			}
			_statusEffectDataSearched = true;
			try
			{
				StatusEffectData[] array = Resources.FindObjectsOfTypeAll<StatusEffectData>();
				if (array.Length != 0)
				{
					_statusEffectData = array[0];
				}
			}
			catch
			{
			}
			return _statusEffectData;
		}

		private static Sprite GetStatusEffectSprite(int effectType)
		{
			StatusEffectData statusEffectData = GetStatusEffectData();
			if ((Object)(object)statusEffectData == (Object)null)
			{
				return null;
			}
			return statusEffectData.GetStatusEffectIcon((StatusEffectType)effectType);
		}

		private void PositionPanelAtWorld(GameObject panel, Vector3 worldPos, Camera cam)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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)
			if ((Object)(object)panel == (Object)null || (Object)(object)cam == (Object)null)
			{
				return;
			}
			Vector3 val = cam.WorldToScreenPoint(worldPos);
			if (val.z < 0f)
			{
				panel.SetActive(false);
				return;
			}
			if (!panel.activeSelf)
			{
				panel.SetActive(true);
			}
			RectTransform component = panel.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				if ((Object)(object)_overlayCanvasRect != (Object)null)
				{
					Vector2 val2 = default(Vector2);
					RectTransformUtility.ScreenPointToLocalPointInRectangle(_overlayCanvasRect, Vector2.op_Implicit(val), (Camera)null, ref val2);
					((Transform)component).localPosition = Vector2.op_Implicit(val2);
				}
				else
				{
					((Transform)component).position = val;
				}
			}
		}

		private void CleanupVisuals()
		{
			foreach (PlayerVisual visual in _visuals)
			{
				DestroyVisual(visual);
			}
			_visuals.Clear();
			if (_hostLabel != null)
			{
				DestroyPanels(_hostLabel);
				_hostLabel = null;
			}
		}

		private void DestroyVisual(PlayerVisual v)
		{
			try
			{
				if ((Object)(object)v.SpriteClone != (Object)null)
				{
					Object.Destroy((Object)(object)v.SpriteClone);
				}
			}
			catch
			{
			}
			DestroyPanels(v);
		}

		private void DestroyPanels(PlayerVisual v)
		{
			try
			{
				if ((Object)(object)v.NamePanel != (Object)null)
				{
					Object.Destroy((Object)(object)v.NamePanel);
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)v.HpPanel != (Object)null)
				{
					Object.Destroy((Object)(object)v.HpPanel);
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)v.ArrowPanel != (Object)null)
				{
					Object.Destroy((Object)(object)v.ArrowPanel);
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)v.StatusIconContainer != (Object)null)
				{
					Object.Destroy((Object)(object)v.StatusIconContainer);
				}
			}
			catch
			{
			}
			v.StatusIcons?.Clear();
		}

		private static Color GetSlotColor(int slot)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(slot switch
			{
				1 => new Color(0.7f, 0.85f, 1f), 
				2 => new Color(1f, 0.8f, 0.7f), 
				3 => new Color(0.8f, 1f, 0.7f), 
				_ => new Color(0.9f, 0.9f, 0.9f), 
			});
		}

		private static RuntimeAnimatorController GetClassAnimationController(int chosenClass)
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected I4, but got Unknown
			try
			{
				RuntimeAnimatorController cachedController = GetCachedController(chosenClass);
				if ((Object)(object)cachedController != (Object)null)
				{
					return cachedController;
				}
				PeglinClassAnimationSwitcher[] array = Resources.FindObjectsOfTypeAll<PeglinClassAnimationSwitcher>();
				if (array != null)
				{
					PeglinClassAnimationSwitcher[] array2 = array;
					foreach (PeglinClassAnimationSwitcher val in array2)
					{
						if (!((Object)(object)val == (Object)null))
						{
							if ((Object)(object)_cachedPeglinCtrl == (Object)null && (Object)(object)val.peglinAnimationController != (Object)null)
							{
								_cachedPeglinCtrl = val.peglinAnimationController;
							}
							if ((Object)(object)_cachedBalladinCtrl == (Object)null && (Object)(object)val.balladinAnimationController != (Object)null)
							{
								_cachedBalladinCtrl = val.balladinAnimationController;
							}
							if ((Object)(object)_cachedRoundrelCtrl == (Object)null && (Object)(object)val.roundrelAnimationController != (Object)null)
							{
								_cachedRoundrelCtrl = val.roundrelAnimationController;
							}
							if ((Object)(object)_cachedSpinventorCtrl == (Object)null && (Object)(object)val.spinventorAnimationController != (Object)null)
							{
								_cachedSpinventorCtrl = val.spinventorAnimationController;
							}
						}
					}
				}
				cachedController = GetCachedController(chosenClass);
				if ((Object)(object)cachedController != (Object)null)
				{
					return c

NLog.dll

Decompiled 4 days ago
#define DEBUG
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using NLog.Attributes;
using NLog.Common;
using NLog.Conditions;
using NLog.Config;
using NLog.Filters;
using NLog.Internal;
using NLog.Internal.Fakeables;
using NLog.LayoutRenderers;
using NLog.LayoutRenderers.Wrappers;
using NLog.Layouts;
using NLog.MessageTemplates;
using NLog.Targets;
using NLog.Targets.FileAppenders;
using NLog.Targets.FileArchiveHandlers;
using NLog.Targets.Wrappers;
using NLog.Time;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CLSCompliant(true)]
[assembly: ComVisible(false)]
[assembly: InternalsVisibleTo("NLog.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100ef8eab4fbdeb511eeb475e1659fe53f00ec1c1340700f1aa347bf3438455d71993b28b1efbed44c8d97a989e0cb6f01bcb5e78f0b055d311546f63de0a969e04cf04450f43834db9f909e566545a67e42822036860075a1576e90e1c43d43e023a24c22a427f85592ae56cac26f13b7ec2625cbc01f9490d60f16cfbb1bc34d9")]
[assembly: InternalsVisibleTo("NLog.Benchmarks, PublicKey=0024000004800000940000000602000000240000525341310004000001000100ef8eab4fbdeb511eeb475e1659fe53f00ec1c1340700f1aa347bf3438455d71993b28b1efbed44c8d97a989e0cb6f01bcb5e78f0b055d311546f63de0a969e04cf04450f43834db9f909e566545a67e42822036860075a1576e90e1c43d43e023a24c22a427f85592ae56cac26f13b7ec2625cbc01f9490d60f16cfbb1bc34d9")]
[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityRules(SecurityRuleSet.Level1)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("NLog")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2004-2026 NLog Project - https://nlog-project.org/ ")]
[assembly: AssemblyDescription("NLog is a logging platform for .NET with rich log routing and management capabilities.\nNLog supports traditional logging, structured logging and the combination of both.\n\nSupported platforms:\n\n- .NET 6, 7, 8, 9 and 10\n- .NET Standard 2.0 and 2.1\n- .NET Framework 3.5 - 4.8\n- Xamarin Android + iOS (.NET Standard)\n- Mono 4\n\nFor integrating NLog with Microsoft.Extensions.Logging, check: https://www.nuget.org/packages/NLog.Extensions.Logging\n\nFor using NLog with ASP.NET Core, check: https://www.nuget.org/packages/NLog.Web.AspNetCore\n    ")]
[assembly: AssemblyFileVersion("6.1.1.5033")]
[assembly: AssemblyInformationalVersion("6.1.1+0e83056311dfcda0493d7db60b7191d0927eb5da")]
[assembly: AssemblyProduct("NLog v6.1.1")]
[assembly: AssemblyTitle("NLog for NetStandard 2.1")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/NLog/NLog.git")]
[assembly: AssemblyVersion("6.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class ParamCollectionAttribute : 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;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	internal sealed class ScopedRefAttribute : Attribute
	{
	}
	[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;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter)]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string Param { get; }

		public CallerArgumentExpressionAttribute(string param)
		{
			Param = param;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, Inherited = false)]
	internal sealed class DynamicallyAccessedMembersAttribute : Attribute
	{
		public DynamicallyAccessedMemberTypes MemberTypes { get; }

		public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
		{
			MemberTypes = memberTypes;
		}
	}
	[Flags]
	internal enum DynamicallyAccessedMemberTypes
	{
		None = 0,
		PublicParameterlessConstructor = 1,
		PublicConstructors = 3,
		NonPublicConstructors = 4,
		PublicMethods = 8,
		NonPublicMethods = 0x10,
		PublicFields = 0x20,
		NonPublicFields = 0x40,
		PublicNestedTypes = 0x80,
		NonPublicNestedTypes = 0x100,
		PublicProperties = 0x200,
		NonPublicProperties = 0x400,
		PublicEvents = 0x800,
		NonPublicEvents = 0x1000,
		Interfaces = 0x2000,
		All = -1
	}
	[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
	internal sealed class UnconditionalSuppressMessageAttribute : Attribute
	{
		public string Category { get; }

		public string CheckId { get; }

		public string? Scope { get; set; }

		public string? Target { get; set; }

		public string? MessageId { get; set; }

		public string? Justification { get; set; }

		public UnconditionalSuppressMessageAttribute(string category, string checkId)
		{
			Category = category;
			CheckId = checkId;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
	internal sealed class RequiresUnreferencedCodeAttribute : Attribute
	{
		public string Message { get; }

		public string? Url { get; set; }

		public RequiresUnreferencedCodeAttribute(string message)
		{
			Message = message;
		}
	}
}
namespace NLog
{
	public static class GlobalDiagnosticsContext
	{
		private static readonly object _lockObject = new object();

		private static Dictionary<string, object?> _dict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

		private static Dictionary<string, object?>? _dictReadOnly;

		public static void Set(string item, string? value)
		{
			Set(item, (object?)value);
		}

		public static void Set(string item, object? value)
		{
			Guard.ThrowIfNull(item, "item");
			lock (_lockObject)
			{
				GetWritableDict()[item] = value;
			}
		}

		public static string Get(string item)
		{
			Guard.ThrowIfNull(item, "item");
			return Get(item, null);
		}

		public static string Get(string item, IFormatProvider? formatProvider)
		{
			Guard.ThrowIfNull(item, "item");
			return FormatHelper.ConvertToString(GetObject(item), formatProvider);
		}

		public static object? GetObject(string item)
		{
			Guard.ThrowIfNull(item, "item");
			GetReadOnlyDict().TryGetValue(item, out object value);
			return value;
		}

		public static ICollection<string> GetNames()
		{
			return GetReadOnlyDict().Keys;
		}

		public static bool Contains(string item)
		{
			Guard.ThrowIfNull(item, "item");
			return GetReadOnlyDict().ContainsKey(item);
		}

		public static void Remove(string item)
		{
			Guard.ThrowIfNull(item, "item");
			lock (_lockObject)
			{
				if (_dict.ContainsKey(item))
				{
					GetWritableDict().Remove(item);
				}
			}
		}

		public static void Clear()
		{
			lock (_lockObject)
			{
				if (_dict.Count != 0)
				{
					GetWritableDict(clearDictionary: true).Clear();
				}
			}
		}

		internal static Dictionary<string, object?> GetReadOnlyDict()
		{
			Dictionary<string, object> dictionary = _dictReadOnly;
			if (dictionary == null)
			{
				lock (_lockObject)
				{
					dictionary = (_dictReadOnly = _dict);
				}
			}
			return dictionary;
		}

		private static Dictionary<string, object?> GetWritableDict(bool clearDictionary = false)
		{
			if (_dictReadOnly != null)
			{
				_dict = CopyDictionaryOnWrite(clearDictionary);
				_dictReadOnly = null;
			}
			return _dict;
		}

		private static Dictionary<string, object?> CopyDictionaryOnWrite(bool clearDictionary)
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>((!clearDictionary) ? (_dict.Count + 1) : 0, _dict.Comparer);
			if (!clearDictionary)
			{
				foreach (KeyValuePair<string, object> item in _dict)
				{
					dictionary[item.Key] = item.Value;
				}
			}
			return dictionary;
		}
	}
	public interface IJsonConverter
	{
		bool SerializeObject(object? value, StringBuilder builder);
	}
	[CLSCompliant(false)]
	public interface ILogger : ISuppress, ILoggerBase
	{
		bool IsTraceEnabled { get; }

		bool IsDebugEnabled { get; }

		bool IsInfoEnabled { get; }

		bool IsWarnEnabled { get; }

		bool IsErrorEnabled { get; }

		bool IsFatalEnabled { get; }

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Trace(object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2, object? arg3);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Debug(object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2, object? arg3);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Info(object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2, object? arg3);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Warn(object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2, object? arg3);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Error(object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2, object? arg3);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, object argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Fatal(object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2, object? arg3);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		void Trace<T>(T? value);

		void Trace<T>(IFormatProvider? formatProvider, T? value);

		void Trace(LogMessageGenerator messageFunc);

		void Trace(Exception? exception, [Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Trace(Exception? exception, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Trace(Exception? exception, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Trace(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		void Trace([Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Trace([Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[Obsolete("Use Trace(Exception exception, string message) method instead. Marked obsolete with v4.3.11")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void Trace([Localizable(false)] string message, Exception? exception);

		[MessageTemplateFormatMethod("message")]
		void Trace<TArgument>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Trace<TArgument>([Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Trace<TArgument1, TArgument2>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Trace<TArgument1, TArgument2>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Trace<TArgument1, TArgument2, TArgument3>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[MessageTemplateFormatMethod("message")]
		void Trace<TArgument1, TArgument2, TArgument3>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[Obsolete("Use Trace(Exception exception, string message) method instead. Marked obsolete with v4.3.11 (Only here because of LibLog)")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void TraceException([Localizable(false)] string message, Exception? exception);

		void Debug<T>(T? value);

		void Debug<T>(IFormatProvider? formatProvider, T? value);

		void Debug(LogMessageGenerator messageFunc);

		void Debug(Exception? exception, [Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Debug(Exception? exception, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Debug(Exception? exception, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Debug(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		void Debug([Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Debug([Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Debug<TArgument>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Debug<TArgument>([Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Debug<TArgument1, TArgument2>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Debug<TArgument1, TArgument2>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Debug<TArgument1, TArgument2, TArgument3>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[MessageTemplateFormatMethod("message")]
		void Debug<TArgument1, TArgument2, TArgument3>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[Obsolete("Use Debug(Exception exception, string message) method instead. Marked obsolete with v4.3.11")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void Debug([Localizable(false)] string message, Exception exception);

		[Obsolete("Use Debug(Exception exception, string message) method instead. Marked obsolete with v4.3.11 (Only here because of LibLog)")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void DebugException([Localizable(false)] string message, Exception? exception);

		void Info<T>(T? value);

		void Info<T>(IFormatProvider? formatProvider, T? value);

		void Info(LogMessageGenerator messageFunc);

		void Info(Exception? exception, [Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Info(Exception? exception, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Info(Exception? exception, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Info(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		void Info([Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Info([Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Info<TArgument>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Info<TArgument>([Localizable(false)][StructuredMessageTemplate] string message, TArgument argument);

		[MessageTemplateFormatMethod("message")]
		void Info<TArgument1, TArgument2>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Info<TArgument1, TArgument2>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Info<TArgument1, TArgument2, TArgument3>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[MessageTemplateFormatMethod("message")]
		void Info<TArgument1, TArgument2, TArgument3>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[Obsolete("Use Info(Exception exception, string message) method instead. Marked obsolete with v4.3.11")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void Info([Localizable(false)] string message, Exception? exception);

		[Obsolete("Use Info(Exception exception, string message) method instead. Marked obsolete with v4.3.11 (Only here because of LibLog)")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void InfoException([Localizable(false)] string message, Exception? exception);

		void Warn<T>(T? value);

		void Warn<T>(IFormatProvider? formatProvider, T? value);

		void Warn(LogMessageGenerator messageFunc);

		void Warn(Exception? exception, [Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Warn(Exception? exception, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Warn(Exception? exception, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Warn(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		void Warn([Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Warn([Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Warn<TArgument>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Warn<TArgument>([Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Warn<TArgument1, TArgument2>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Warn<TArgument1, TArgument2>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Warn<TArgument1, TArgument2, TArgument3>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[MessageTemplateFormatMethod("message")]
		void Warn<TArgument1, TArgument2, TArgument3>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[Obsolete("Use Warn(Exception exception, string message) method instead. Marked obsolete with v4.3.11")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void Warn([Localizable(false)] string message, Exception? exception);

		[Obsolete("Use Warn(Exception exception, string message) method instead. Marked obsolete with v4.3.11 (Only here because of LibLog)")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void WarnException([Localizable(false)] string message, Exception? exception);

		void Error<T>(T? value);

		void Error<T>(IFormatProvider? formatProvider, T? value);

		void Error(LogMessageGenerator messageFunc);

		void Error(Exception? exception, [Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Error(Exception? exception, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Error(Exception? exception, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Error(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		void Error([Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Error([Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Error<TArgument>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Error<TArgument>([Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Error<TArgument1, TArgument2>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Error<TArgument1, TArgument2>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Error<TArgument1, TArgument2, TArgument3>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[MessageTemplateFormatMethod("message")]
		void Error<TArgument1, TArgument2, TArgument3>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[Obsolete("Use Error(Exception exception, string message) method instead. Marked obsolete with v4.3.11")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void Error([Localizable(false)] string message, Exception? exception);

		[Obsolete("Use Error(Exception exception, string message) method instead. Marked obsolete with v4.3.11 (Only here because of LibLog)")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void ErrorException([Localizable(false)] string message, Exception? exception);

		void Fatal<T>(T? value);

		void Fatal<T>(IFormatProvider? formatProvider, T? value);

		void Fatal(LogMessageGenerator messageFunc);

		void Fatal(Exception? exception, [Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Fatal(Exception? exception, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Fatal(Exception? exception, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Fatal(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		void Fatal([Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Fatal([Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Fatal<TArgument>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Fatal<TArgument>([Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Fatal<TArgument1, TArgument2>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Fatal<TArgument1, TArgument2>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Fatal<TArgument1, TArgument2, TArgument3>(IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[MessageTemplateFormatMethod("message")]
		void Fatal<TArgument1, TArgument2, TArgument3>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[Obsolete("Use Fatal(Exception exception, string message) method instead. Marked obsolete with v4.3.11")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void Fatal([Localizable(false)] string message, Exception? exception);

		[Obsolete("Use Fatal(Exception exception, string message) method instead. Marked obsolete with v4.3.11 (Only here because of LibLog)")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void FatalException([Localizable(false)] string message, Exception? exception);
	}
	[CLSCompliant(false)]
	[Obsolete("ILoggerBase should be replaced with ILogger. Marked obsolete with NLog v5.3")]
	[EditorBrowsable(EditorBrowsableState.Never)]
	public interface ILoggerBase
	{
		string Name { get; }

		[Obsolete("Factory-property is hard to mock for ILogger-interface. Instead use Logger.Factory. Marked obsolete with NLog v5.3")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		LogFactory Factory { get; }

		[Obsolete("LoggerReconfigured-EventHandler is very exotic for ILogger-interface. Instead use Logger.LoggerReconfigured. Marked obsolete with NLog v5.3")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		event EventHandler<EventArgs> LoggerReconfigured;

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, object? value);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, object? arg1, object? arg2, object? arg3);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, bool argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, char argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, byte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, string? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, int argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, long argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, float argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, double argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, decimal argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, object? argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, sbyte argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, uint argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		[EditorBrowsable(EditorBrowsableState.Never)]
		[MessageTemplateFormatMethod("message")]
		[OverloadResolutionPriority(-1)]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, ulong argument);

		bool IsEnabled(LogLevel level);

		void Log(LogEventInfo logEvent);

		void Log(Type wrapperType, LogEventInfo logEvent);

		void Log<T>(LogLevel level, T? value);

		void Log<T>(LogLevel level, IFormatProvider? formatProvider, T? value);

		void Log(LogLevel level, LogMessageGenerator messageFunc);

		[MessageTemplateFormatMethod("message")]
		void Log(LogLevel level, Exception? exception, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Log(LogLevel level, Exception? exception, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Log(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		void Log(LogLevel level, [Localizable(false)] string message);

		[MessageTemplateFormatMethod("message")]
		void Log(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args);

		[MessageTemplateFormatMethod("message")]
		void Log<TArgument>(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Log<TArgument>(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument);

		[MessageTemplateFormatMethod("message")]
		void Log<TArgument1, TArgument2>(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Log<TArgument1, TArgument2>(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2);

		[MessageTemplateFormatMethod("message")]
		void Log<TArgument1, TArgument2, TArgument3>(LogLevel level, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[MessageTemplateFormatMethod("message")]
		void Log<TArgument1, TArgument2, TArgument3>(LogLevel level, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3);

		[Obsolete("Use Log(LogLevel level, Exception exception, [Localizable(false)] string message, params object[] args) instead. Marked obsolete with v4.3.11")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void Log(LogLevel level, [Localizable(false)] string message, Exception? exception);

		[Obsolete("Use Log(LogLevel level, Exception exception, [Localizable(false)] string message, params object[] args) instead. Marked obsolete with v4.3.11")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		void LogException(LogLevel level, [Localizable(false)] string message, Exception? exception);
	}
	[CLSCompliant(false)]
	public static class ILoggerExtensions
	{
		public static LogEventBuilder ForLogEvent(this ILogger logger, LogLevel? logLevel = null)
		{
			if ((object)logLevel != null)
			{
				return new LogEventBuilder(logger, logLevel);
			}
			return new LogEventBuilder(logger);
		}

		public static LogEventBuilder ForTraceEvent(this ILogger logger)
		{
			return new LogEventBuilder(logger, LogLevel.Trace);
		}

		public static LogEventBuilder ForDebugEvent(this ILogger logger)
		{
			return new LogEventBuilder(logger, LogLevel.Debug);
		}

		public static LogEventBuilder ForInfoEvent(this ILogger logger)
		{
			return new LogEventBuilder(logger, LogLevel.Info);
		}

		public static LogEventBuilder ForWarnEvent(this ILogger logger)
		{
			return new LogEventBuilder(logger, LogLevel.Warn);
		}

		public static LogEventBuilder ForErrorEvent(this ILogger logger)
		{
			return new LogEventBuilder(logger, LogLevel.Error);
		}

		public static LogEventBuilder ForFatalEvent(this ILogger logger)
		{
			return new LogEventBuilder(logger, LogLevel.Fatal);
		}

		public static LogEventBuilder ForExceptionEvent(this ILogger logger, Exception? exception, LogLevel? logLevel = null)
		{
			return logger.ForLogEvent(logLevel ?? LogLevel.Error).Exception(exception);
		}

		[Conditional("DEBUG")]
		public static void ConditionalDebug<T>(this ILogger logger, T? value)
		{
			logger.Debug(value);
		}

		[Conditional("DEBUG")]
		public static void ConditionalDebug<T>(this ILogger logger, IFormatProvider? formatProvider, T? value)
		{
			logger.Debug(formatProvider, value);
		}

		[Conditional("DEBUG")]
		public static void ConditionalDebug(this ILogger logger, LogMessageGenerator messageFunc)
		{
			logger.Debug(messageFunc);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalDebug(this ILogger logger, Exception? exception, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			logger.Debug(exception, message, args);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalDebug(this ILogger logger, Exception? exception, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			logger.Debug(exception, formatProvider, message, args);
		}

		[Conditional("DEBUG")]
		public static void ConditionalDebug(this ILogger logger, [Localizable(false)] string message)
		{
			logger.Debug(message);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalDebug(this ILogger logger, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			logger.Debug(message, args);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalDebug(this ILogger logger, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			logger.Debug(formatProvider, message, args);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalDebug<TArgument>(this ILogger logger, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument)
		{
			if (logger.IsDebugEnabled)
			{
				logger.Debug<object>(message, (object?)argument);
			}
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalDebug<TArgument1, TArgument2>(this ILogger logger, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2)
		{
			if (logger.IsDebugEnabled)
			{
				logger.Debug<object, object>(message, (object?)argument1, (object?)argument2);
			}
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalDebug<TArgument1, TArgument2, TArgument3>(this ILogger logger, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3)
		{
			if (logger.IsDebugEnabled)
			{
				logger.Debug<object, object, object>(message, (object?)argument1, (object?)argument2, (object?)argument3);
			}
		}

		[Conditional("DEBUG")]
		public static void ConditionalTrace<T>(this ILogger logger, T? value)
		{
			logger.Trace(value);
		}

		[Conditional("DEBUG")]
		public static void ConditionalTrace<T>(this ILogger logger, IFormatProvider? formatProvider, T? value)
		{
			logger.Trace(formatProvider, value);
		}

		[Conditional("DEBUG")]
		public static void ConditionalTrace(this ILogger logger, LogMessageGenerator messageFunc)
		{
			logger.Trace(messageFunc);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalTrace(this ILogger logger, Exception? exception, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			logger.Trace(exception, message, args);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalTrace(this ILogger logger, Exception? exception, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			logger.Trace(exception, formatProvider, message, args);
		}

		[Conditional("DEBUG")]
		public static void ConditionalTrace(this ILogger logger, [Localizable(false)] string message)
		{
			logger.Trace(message);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalTrace(this ILogger logger, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			logger.Trace(message, args);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalTrace(this ILogger logger, IFormatProvider? formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			logger.Trace(formatProvider, message, args);
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalTrace<TArgument>(this ILogger logger, [Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument)
		{
			if (logger.IsTraceEnabled)
			{
				logger.Trace<object>(message, (object?)argument);
			}
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalTrace<TArgument1, TArgument2>(this ILogger logger, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2)
		{
			if (logger.IsTraceEnabled)
			{
				logger.Trace<object, object>(message, (object?)argument1, (object?)argument2);
			}
		}

		[Conditional("DEBUG")]
		[MessageTemplateFormatMethod("message")]
		public static void ConditionalTrace<TArgument1, TArgument2, TArgument3>(this ILogger logger, [Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3)
		{
			if (logger.IsTraceEnabled)
			{
				logger.Trace<object, object, object>(message, (object?)argument1, (object?)argument2, (object?)argument3);
			}
		}

		public static void Log(this ILogger logger, LogLevel level, Exception? exception, LogMessageGenerator messageFunc)
		{
			if (logger.IsEnabled(level))
			{
				logger.Log(level, exception, messageFunc(), ArrayHelper.Empty<object>());
			}
		}

		public static void Trace(this ILogger logger, Exception? exception, LogMessageGenerator messageFunc)
		{
			if (logger.IsTraceEnabled)
			{
				Guard.ThrowIfNull(messageFunc, "messageFunc");
				logger.Trace(exception, messageFunc());
			}
		}

		public static void Debug(this ILogger logger, Exception? exception, LogMessageGenerator messageFunc)
		{
			if (logger.IsDebugEnabled)
			{
				Guard.ThrowIfNull(messageFunc, "messageFunc");
				logger.Debug(exception, messageFunc());
			}
		}

		public static void Info(this ILogger logger, Exception? exception, LogMessageGenerator messageFunc)
		{
			if (logger.IsInfoEnabled)
			{
				Guard.ThrowIfNull(messageFunc, "messageFunc");
				logger.Info(exception, messageFunc());
			}
		}

		public static void Warn(this ILogger logger, Exception? exception, LogMessageGenerator messageFunc)
		{
			if (logger.IsWarnEnabled)
			{
				Guard.ThrowIfNull(messageFunc, "messageFunc");
				logger.Warn(exception, messageFunc());
			}
		}

		public static void Error(this ILogger logger, Exception? exception, LogMessageGenerator messageFunc)
		{
			if (logger.IsErrorEnabled)
			{
				Guard.ThrowIfNull(messageFunc, "messageFunc");
				logger.Error(exception, messageFunc());
			}
		}

		public static void Fatal(this ILogger logger, Exception? exception, LogMessageGenerator messageFunc)
		{
			if (logger.IsFatalEnabled)
			{
				Guard.ThrowIfNull(messageFunc, "messageFunc");
				logger.Fatal(exception, messageFunc());
			}
		}
	}
	internal interface IObjectTypeTransformer
	{
		object? TryTransformObject(object obj);
	}
	[Obsolete("ISuppress should be replaced with ILogger. Marked obsolete with NLog v5.3")]
	[EditorBrowsable(EditorBrowsableState.Never)]
	public interface ISuppress
	{
		void Swallow(Action action);

		T? Swallow<T>(Func<T?> func);

		T? Swallow<T>(Func<T?> func, T? fallback);

		void Swallow(Task task);

		Task SwallowAsync(Task task);

		Task SwallowAsync(Func<Task> asyncAction);

		Task<TResult?> SwallowAsync<TResult>(Func<Task<TResult?>> asyncFunc);

		Task<TResult?> SwallowAsync<TResult>(Func<Task<TResult?>> asyncFunc, TResult? fallback);
	}
	public interface IValueFormatter
	{
		bool FormatValue(object? value, string? format, CaptureType captureType, IFormatProvider? formatProvider, StringBuilder builder);
	}
	public static class LayoutTypedExtensions
	{
		public static T? RenderValue<T>(this Layout<T>? layout, LogEventInfo logEvent, T? defaultValue = default(T?))
		{
			if (layout != null)
			{
				return layout.RenderTypedValue(logEvent, defaultValue);
			}
			return defaultValue;
		}
	}
	[CLSCompliant(false)]
	public struct LogEventBuilder
	{
		private readonly ILogger _logger;

		private readonly LogEventInfo? _logEvent;

		public ILogger Logger => _logger;

		public LogEventInfo? LogEvent
		{
			get
			{
				if (_logEvent != null)
				{
					return ResolveLogEvent(_logEvent);
				}
				return null;
			}
		}

		public LogEventBuilder(ILogger logger)
		{
			_logger = Guard.ThrowIfNull(logger, "logger");
			_logEvent = new LogEventInfo
			{
				LoggerName = _logger.Name
			};
		}

		public LogEventBuilder(ILogger logger, LogLevel logLevel)
		{
			_logger = Guard.ThrowIfNull(logger, "logger");
			Guard.ThrowIfNull(logLevel, "logLevel");
			if (logger.IsEnabled(logLevel))
			{
				_logEvent = new LogEventInfo
				{
					LoggerName = _logger.Name,
					Level = logLevel
				};
			}
			else
			{
				_logEvent = null;
			}
		}

		public LogEventBuilder Property<T>(string propertyName, T? propertyValue)
		{
			Guard.ThrowIfNull(propertyName, "propertyName");
			if (_logEvent != null)
			{
				_logEvent.Properties[propertyName] = propertyValue;
			}
			return this;
		}

		public LogEventBuilder Properties(IEnumerable<KeyValuePair<string, object?>> properties)
		{
			Guard.ThrowIfNull(properties, "properties");
			if (_logEvent != null)
			{
				foreach (KeyValuePair<string, object> property in properties)
				{
					_logEvent.Properties[property.Key] = property.Value;
				}
			}
			return this;
		}

		public LogEventBuilder Properties(IReadOnlyCollection<KeyValuePair<string, object?>> properties)
		{
			Guard.ThrowIfNull(properties, "properties");
			if (_logEvent != null && properties.Count > 0)
			{
				PropertiesDictionary propertiesDictionary = _logEvent.CreatePropertiesInternal(null, properties.Count);
				foreach (KeyValuePair<string, object> property in properties)
				{
					propertiesDictionary[property.Key] = property.Value;
				}
			}
			return this;
		}

		public LogEventBuilder Properties(ReadOnlySpan<(string, object?)> properties)
		{
			if (_logEvent != null && !properties.IsEmpty)
			{
				PropertiesDictionary propertiesDictionary = _logEvent.CreatePropertiesInternal(null, properties.Length);
				ReadOnlySpan<(string, object)> readOnlySpan = properties;
				for (int i = 0; i < readOnlySpan.Length; i++)
				{
					(string, object) tuple = readOnlySpan[i];
					propertiesDictionary[tuple.Item1] = tuple.Item2;
				}
			}
			return this;
		}

		public LogEventBuilder Exception(Exception? exception)
		{
			if (_logEvent != null)
			{
				_logEvent.Exception = exception;
			}
			return this;
		}

		public LogEventBuilder TimeStamp(DateTime timeStamp)
		{
			if (_logEvent != null)
			{
				_logEvent.TimeStamp = timeStamp;
			}
			return this;
		}

		public LogEventBuilder Message([Localizable(false)] string message)
		{
			if (_logEvent != null)
			{
				_logEvent.Parameters = null;
				_logEvent.Message = message;
			}
			return this;
		}

		[MessageTemplateFormatMethod("message")]
		public LogEventBuilder Message<TArgument>([Localizable(false)][StructuredMessageTemplate] string message, TArgument? argument)
		{
			if (_logEvent != null)
			{
				_logEvent.Message = message;
				_logEvent.Parameters = new object[1] { argument };
			}
			return this;
		}

		[MessageTemplateFormatMethod("message")]
		public LogEventBuilder Message<TArgument1, TArgument2>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2)
		{
			if (_logEvent != null)
			{
				_logEvent.Message = message;
				_logEvent.Parameters = new object[2] { argument1, argument2 };
			}
			return this;
		}

		[MessageTemplateFormatMethod("message")]
		public LogEventBuilder Message<TArgument1, TArgument2, TArgument3>([Localizable(false)][StructuredMessageTemplate] string message, TArgument1? argument1, TArgument2? argument2, TArgument3? argument3)
		{
			if (_logEvent != null)
			{
				_logEvent.Message = message;
				_logEvent.Parameters = new object[3] { argument1, argument2, argument3 };
			}
			return this;
		}

		[MessageTemplateFormatMethod("message")]
		public LogEventBuilder Message([Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			if (_logEvent != null)
			{
				_logEvent.Message = message;
				_logEvent.Parameters = args;
			}
			return this;
		}

		[MessageTemplateFormatMethod("message")]
		public LogEventBuilder Message([Localizable(false)][StructuredMessageTemplate] string message, [ParamCollection] scoped ReadOnlySpan<object?> args)
		{
			if (_logEvent != null)
			{
				_logEvent.Message = message;
				_logEvent.Parameters = (args.IsEmpty ? null : args.ToArray());
			}
			return this;
		}

		[MessageTemplateFormatMethod("message")]
		public LogEventBuilder Message(IFormatProvider formatProvider, [Localizable(false)][StructuredMessageTemplate] string message, params object?[] args)
		{
			if (_logEvent != null)
			{
				_logEvent.FormatProvider = formatProvider;
				_logEvent.Message = message;
				_logEvent.Parameters = args;
			}
			return this;
		}

		public LogEventBuilder Callsite(string? callerClassName = null, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
		{
			if (_logEvent != null)
			{
				_logEvent.SetCallerInfo(callerClassName, callerMemberName, callerFilePath, callerLineNumber);
			}
			return this;
		}

		public void Log(LogLevel? logLevel = null, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
		{
			if (_logEvent != null)
			{
				LogEventInfo logEventInfo = ResolveLogEvent(_logEvent, logLevel);
				if (logEventInfo.CallSiteInformation == null && _logger.IsEnabled(logEventInfo.Level))
				{
					_logEvent.SetCallerInfo(null, callerMemberName, callerFilePath, callerLineNumber);
				}
				_logger.Log(logEventInfo);
			}
		}

		public void Log(Type wrapperType)
		{
			if (_logEvent != null)
			{
				LogEventInfo logEvent = ResolveLogEvent(_logEvent);
				_logger.Log(wrapperType, logEvent);
			}
		}

		private LogEventInfo ResolveLogEvent(LogEventInfo logEvent, LogLevel? logLevel = null)
		{
			if ((object)logLevel == null)
			{
				if ((object)logEvent.Level == null)
				{
					logEvent.Level = ((logEvent.Exception != null) ? LogLevel.Error : LogLevel.Info);
				}
			}
			else
			{
				logEvent.Level = logLevel;
			}
			if ((logEvent.Message == null || (object)logEvent.Message == string.Empty) && logEvent.Exception != null && _logger.IsEnabled(logEvent.Level))
			{
				logEvent.FormatProvider = ExceptionMessageFormatProvider.Instance;
				logEvent.Message = "{0}";
				logEvent.Parameters = new object[1] { logEvent.Exception };
			}
			return logEvent;
		}
	}
	public class LogEventInfo
	{
		private sealed class LayoutCacheLinkedNode
		{
			public readonly Layout Key;

			public readonly object? Value;

			public LayoutCacheLinkedNode? Next;

			public LayoutCacheLinkedNode(Layout key, object? value)
			{
				Key = key;
				Value = value;
			}
		}

		public static readonly DateTime ZeroDate = DateTime.UtcNow;

		private static int globalSequenceId;

		private string? _formattedMessage;

		private string _message;

		private object?[]? _parameters;

		private IFormatProvider? _formatProvider;

		private LogMessageFormatter? _messageFormatter;

		private LayoutCacheLinkedNode? _layoutCache;

		private PropertiesDictionary? _properties;

		private int _sequenceId;

		[Obsolete("Use ${counter:sequence=global} instead of ${sequenceid}. Marked obsolete with NLog 6.0")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public int SequenceID
		{
			get
			{
				if (_sequenceId == 0)
				{
					Interlocked.CompareExchange(ref _sequenceId, Interlocked.Increment(ref globalSequenceId), 0);
				}
				return _sequenceId;
			}
		}

		public DateTime TimeStamp { get; set; }

		public LogLevel Level { get; set; }

		internal CallSiteInformation? CallSiteInformation { get; private set; }

		public bool HasStackTrace => CallSiteInformation?.StackTrace != null;

		[Obsolete("Instead use ${callsite} or CallerMemberName. Marked obsolete with NLog 5.3")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public StackFrame? UserStackFrame => CallSiteInformation?.UserStackFrame;

		[Obsolete("Instead use ${callsite} or CallerMemberName. Marked obsolete with NLog 5.4")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public int UserStackFrameNumber => CallSiteInformation?.UserStackFrameNumberLegacy ?? CallSiteInformation?.UserStackFrameNumber ?? 0;

		public StackTrace? StackTrace => CallSiteInformation?.StackTrace;

		public string? CallerClassName => CallSiteInformation?.GetCallerClassName(null, includeNameSpace: true, cleanAsyncMoveNext: true, cleanAnonymousDelegates: true);

		public string? CallerMemberName => CallSiteInformation?.GetCallerMethodName(null, includeMethodInfo: false, cleanAsyncMoveNext: true, cleanAnonymousDelegates: true);

		public string? CallerFilePath => CallSiteInformation?.GetCallerFilePath(0);

		public int CallerLineNumber => CallSiteInformation?.GetCallerLineNumber(0) ?? 0;

		public Exception? Exception { get; set; }

		public string LoggerName { get; set; }

		public string Message
		{
			get
			{
				return _message;
			}
			set
			{
				bool parseMessageTemplateParameters = ResetMessageTemplateParameters();
				_message = value;
				ResetFormattedMessage(parseMessageTemplateParameters);
			}
		}

		public object?[]? Parameters
		{
			get
			{
				return _parameters;
			}
			set
			{
				bool parseMessageTemplateParameters = ResetMessageTemplateParameters();
				_parameters = value;
				ResetFormattedMessage(parseMessageTemplateParameters);
			}
		}

		public IFormatProvider? FormatProvider
		{
			get
			{
				return _formatProvider;
			}
			set
			{
				if (_formatProvider != value)
				{
					_formatProvider = value;
					ResetFormattedMessage(parseMessageTemplateParameters: false);
				}
			}
		}

		public LogMessageFormatter MessageFormatter
		{
			get
			{
				return _messageFormatter ?? LogManager.LogFactory.ActiveMessageFormatter;
			}
			set
			{
				LogMessageFormatter logMessageFormatter = value ?? LogMessageStringFormatter.Default.MessageFormatter;
				if ((object)_messageFormatter != logMessageFormatter)
				{
					_messageFormatter = logMessageFormatter;
					_formattedMessage = null;
					ResetFormattedMessage(parseMessageTemplateParameters: false);
				}
			}
		}

		public string FormattedMessage
		{
			get
			{
				if (_formattedMessage == null)
				{
					CalcFormattedMessage();
				}
				return _formattedMessage ?? Message;
			}
		}

		public bool HasProperties
		{
			get
			{
				if (_properties == null)
				{
					PropertiesDictionary? propertiesDictionary = TryCreatePropertiesInternal();
					if (propertiesDictionary == null)
					{
						return false;
					}
					return propertiesDictionary.Count > 0;
				}
				return _properties.Count > 0;
			}
		}

		public IDictionary<object, object?> Properties => _properties ?? CreatePropertiesInternal();

		private bool HasMessageTemplateParameters
		{
			get
			{
				if (_formattedMessage == null)
				{
					object?[]? parameters = _parameters;
					if (parameters != null && parameters.Length != 0)
					{
						return (MessageFormatter.Target as ILogMessageFormatter)?.HasProperties(this) ?? false;
					}
				}
				return false;
			}
		}

		public MessageTemplateParameters MessageTemplateParameters
		{
			get
			{
				PropertiesDictionary? properties = _properties;
				if (properties != null && properties.MessageProperties.Count > 0)
				{
					return new MessageTemplateParameters(_properties.MessageProperties);
				}
				object?[]? parameters = _parameters;
				if (parameters != null && parameters.Length != 0)
				{
					return new MessageTemplateParameters(_message, _parameters);
				}
				return NLog.MessageTemplates.MessageTemplateParameters.Empty;
			}
		}

		public LogEventInfo()
		{
			TimeStamp = TimeSource.Current.Time;
			_message = string.Empty;
			LoggerName = string.Empty;
			Level = LogLevel.Off;
		}

		public LogEventInfo(LogLevel level, string? loggerName, [Localizable(false)] string message)
			: this(level, loggerName, null, message, null, null)
		{
		}

		public LogEventInfo(LogLevel level, string? loggerName, [Localizable(false)] string message, IList<MessageTemplateParameter>? messageTemplateParameters)
			: this(level, loggerName, null, message, null, null)
		{
			if (messageTemplateParameters == null)
			{
				return;
			}
			int count = messageTemplateParameters.Count;
			if (count > 0)
			{
				MessageTemplateParameter[] array = new MessageTemplateParameter[count];
				for (int i = 0; i < count; i++)
				{
					array[i] = messageTemplateParameters[i];
				}
				_properties = new PropertiesDictionary(array);
			}
		}

		public LogEventInfo(LogLevel level, string? loggerName, [Localizable(false)] string formattedMessage, [Localizable(false)] string messageTemplate, IList<MessageTemplateParameter>? messageTemplateParameters)
			: this(level, loggerName, messageTemplate, messageTemplateParameters)
		{
			_formattedMessage = formattedMessage;
			_me