Decompiled source of Multipeglin v0.1.10
LiteNetLib.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
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 agousing 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
The result has been truncated due to the large size, download it to view full contents!
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
The result has been truncated due to the large size, download it to view full contents!
#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