Decompiled source of OmniBonk v1.0.0
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.Diagnostics.CodeAnalysis; 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.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; 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(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyMetadata("IsTrimmable", "True")] [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<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] 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: {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 value) { NetDebug.WriteError($"[S] {value}"); 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 value) { NetDebug.WriteError($"[S][MCAST] {value}"); 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 +
MemoryPack.Core.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.Buffers; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Collections.ObjectModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using MemoryPack.Compression; using MemoryPack.Formatters; using MemoryPack.Internal; 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("Cysharp")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("© Cysharp, Inc.")] [assembly: AssemblyDescription("Core libraries(attribute, logics) of MemoryPack.")] [assembly: AssemblyFileVersion("1.21.4.0")] [assembly: AssemblyInformationalVersion("1.21.4+0f2fe0827907940768293b7bb81b9605a7d8cba8")] [assembly: AssemblyProduct("MemoryPack.Core")] [assembly: AssemblyTitle("MemoryPack.Core")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Cysharp/MemoryPack")] [assembly: InternalsVisibleTo("MemoryPack.Streaming, PublicKey=00240000048000009400000006020000002400005253413100040000010001000144ec28f1e9ef7b17dacc47425a7a153aea0a7baa590743a2d1a86f4b3e10a8a12712c6e647966bfd8bd6e830048b23bd42bbc56f179585c15b8c19cf86c0eed1b73c993dd7a93a30051dd50fdda0e4d6b65e6874e30f1c37cf8bcbc7fe02c7f2e6a0a3327c0ccc1631bf645f40732521fa0b41a30c178d08f7dd779d42a1ee")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.21.4.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] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } internal sealed class IsExternalInit { } } namespace MemoryPack { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackableAttribute : Attribute { public GenerateType GenerateType { get; } public SerializeLayout SerializeLayout { get; } public MemoryPackableAttribute(GenerateType generateType = GenerateType.Object) { GenerateType = generateType; SerializeLayout = ((generateType == GenerateType.VersionTolerant || generateType == GenerateType.CircularReference) ? SerializeLayout.Explicit : SerializeLayout.Sequential); } public MemoryPackableAttribute(SerializeLayout serializeLayout) { GenerateType = GenerateType.Object; SerializeLayout = serializeLayout; } public MemoryPackableAttribute(GenerateType generateType, SerializeLayout serializeLayout) { GenerateType = generateType; SerializeLayout = serializeLayout; } } public enum GenerateType { Object, VersionTolerant, CircularReference, Collection, NoGenerate } public enum SerializeLayout { Sequential, Explicit } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] public sealed class MemoryPackUnionAttribute : Attribute { public ushort Tag { get; } public Type Type { get; } public MemoryPackUnionAttribute(ushort tag, Type type) { Tag = tag; Type = type; } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackUnionFormatterAttribute : Attribute { public Type Type { get; } public MemoryPackUnionFormatterAttribute(Type type) { Type = type; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackAllowSerializeAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackOrderAttribute : Attribute { public int Order { get; } public MemoryPackOrderAttribute(int order) { Order = order; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public abstract class MemoryPackCustomFormatterAttribute<T> : Attribute { public abstract IMemoryPackFormatter<T> GetFormatter(); } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public abstract class MemoryPackCustomFormatterAttribute<TFormatter, T> : Attribute where TFormatter : IMemoryPackFormatter<T> { public abstract TFormatter GetFormatter(); } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackIgnoreAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackIncludeAttribute : Attribute { } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackConstructorAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackOnSerializingAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackOnSerializedAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackOnDeserializingAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public sealed class MemoryPackOnDeserializedAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] public sealed class GenerateTypeScriptAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public sealed class SuppressDefaultInitializationAttribute : Attribute { } public sealed class Utf8StringFormatterAttribute : MemoryPackCustomFormatterAttribute<Utf8StringFormatter, string> { public override Utf8StringFormatter GetFormatter() { return Utf8StringFormatter.Default; } } public sealed class Utf16StringFormatterAttribute : MemoryPackCustomFormatterAttribute<Utf16StringFormatter, string> { public override Utf16StringFormatter GetFormatter() { return Utf16StringFormatter.Default; } } public sealed class OrdinalIgnoreCaseStringDictionaryFormatter<TValue> : MemoryPackCustomFormatterAttribute<DictionaryFormatter<string, TValue?>, Dictionary<string, TValue?>> { private static readonly DictionaryFormatter<string, TValue?> formatter = new DictionaryFormatter<string, TValue>(StringComparer.OrdinalIgnoreCase); public override DictionaryFormatter<string, TValue?> GetFormatter() { return formatter; } } public sealed class InternStringFormatterAttribute : MemoryPackCustomFormatterAttribute<InternStringFormatter, string> { public override InternStringFormatter GetFormatter() { return InternStringFormatter.Default; } } public sealed class BitPackFormatterAttribute : MemoryPackCustomFormatterAttribute<BitPackFormatter, bool[]> { public override BitPackFormatter GetFormatter() { return BitPackFormatter.Default; } } public sealed class BrotliFormatterAttribute : MemoryPackCustomFormatterAttribute<BrotliFormatter, byte[]> { public CompressionLevel CompressionLevel { get; } public int Window { get; } public int DecompressionSizeLimit { get; } public BrotliFormatterAttribute(CompressionLevel compressionLevel = CompressionLevel.Fastest, int window = 22, int decompressionSizeLimit = 134217728) { CompressionLevel = compressionLevel; Window = window; DecompressionSizeLimit = decompressionSizeLimit; } public override BrotliFormatter GetFormatter() { return new BrotliFormatter(CompressionLevel, Window, DecompressionSizeLimit); } } public sealed class BrotliFormatterAttribute<T> : MemoryPackCustomFormatterAttribute<BrotliFormatter<T>, T> { public CompressionLevel CompressionLevel { get; } public int Window { get; } public BrotliFormatterAttribute(CompressionLevel compressionLevel = CompressionLevel.Fastest, int window = 22) { CompressionLevel = compressionLevel; Window = window; } public override BrotliFormatter<T> GetFormatter() { return new BrotliFormatter<T>(CompressionLevel, Window); } } public sealed class BrotliStringFormatterAttribute : MemoryPackCustomFormatterAttribute<BrotliStringFormatter, string> { public CompressionLevel CompressionLevel { get; } public int Window { get; } public int DecompressionSizeLimit { get; } public BrotliStringFormatterAttribute(CompressionLevel compressionLevel = CompressionLevel.Fastest, int window = 22, int decompressionSizeLimit = 134217728) { CompressionLevel = compressionLevel; Window = window; DecompressionSizeLimit = decompressionSizeLimit; } public override BrotliStringFormatter GetFormatter() { return new BrotliStringFormatter(CompressionLevel, Window, DecompressionSizeLimit); } } public sealed class MemoryPoolFormatterAttribute<T> : MemoryPackCustomFormatterAttribute<MemoryPoolFormatter<T>, Memory<T?>> { private static readonly MemoryPoolFormatter<T> formatter = new MemoryPoolFormatter<T>(); public override MemoryPoolFormatter<T> GetFormatter() { return formatter; } } public sealed class ReadOnlyMemoryPoolFormatterAttribute<T> : MemoryPackCustomFormatterAttribute<ReadOnlyMemoryPoolFormatter<T>, ReadOnlyMemory<T?>> { private static readonly ReadOnlyMemoryPoolFormatter<T> formatter = new ReadOnlyMemoryPoolFormatter<T>(); public override ReadOnlyMemoryPoolFormatter<T> GetFormatter() { return formatter; } } public static class MemoryPackFormatterProvider { private static class Check<T> { public static bool registered; } private static class Cache<T> { public static MemoryPackFormatter<T> formatter; static Cache() { if (Check<T>.registered) { return; } try { Type typeFromHandle = typeof(T); if (TryInvokeRegisterFormatter(typeFromHandle)) { return; } if (TypeHelpers.IsAnonymous(typeFromHandle)) { formatter = new ErrorMemoryPackFormatter<T>("Serialize anonymous type is not supported, use record or tuple instead."); } else { bool typeIsReferenceOrContainsReferences = RuntimeHelpers.IsReferenceOrContainsReferences<T>(); formatter = (CreateGenericFormatter(typeFromHandle, typeIsReferenceOrContainsReferences) as MemoryPackFormatter<T>) ?? new ErrorMemoryPackFormatter<T>(); } } catch (Exception exception) { formatter = new ErrorMemoryPackFormatter<T>(exception); } formatters[typeof(T)] = formatter; Check<T>.registered = true; } } private static readonly Dictionary<Type, Type> ArrayLikeFormatters; private static readonly Dictionary<Type, Type> CollectionFormatters; private static readonly Dictionary<Type, Type> ImmutableCollectionFormatters; private static readonly Dictionary<Type, Type> InterfaceCollectionFormatters; private static readonly ConcurrentDictionary<Type, IMemoryPackFormatter> formatters; private static readonly ConcurrentDictionary<Type, Type> genericFormatterFactory; private static readonly ConcurrentDictionary<Type, Type> genericCollectionFormatterFactory; private static readonly Dictionary<Type, Type> KnownGenericTypeFormatters; static MemoryPackFormatterProvider() { ArrayLikeFormatters = new Dictionary<Type, Type>(4) { { typeof(ArraySegment<>), typeof(ArraySegmentFormatter<>) }, { typeof(Memory<>), typeof(MemoryFormatter<>) }, { typeof(ReadOnlyMemory<>), typeof(ReadOnlyMemoryFormatter<>) }, { typeof(ReadOnlySequence<>), typeof(ReadOnlySequenceFormatter<>) } }; CollectionFormatters = new Dictionary<Type, Type>(18) { { typeof(List<>), typeof(ListFormatter<>) }, { typeof(Stack<>), typeof(StackFormatter<>) }, { typeof(Queue<>), typeof(QueueFormatter<>) }, { typeof(LinkedList<>), typeof(LinkedListFormatter<>) }, { typeof(HashSet<>), typeof(HashSetFormatter<>) }, { typeof(SortedSet<>), typeof(SortedSetFormatter<>) }, { typeof(ObservableCollection<>), typeof(ObservableCollectionFormatter<>) }, { typeof(Collection<>), typeof(CollectionFormatter<>) }, { typeof(ConcurrentQueue<>), typeof(ConcurrentQueueFormatter<>) }, { typeof(ConcurrentStack<>), typeof(ConcurrentStackFormatter<>) }, { typeof(ConcurrentBag<>), typeof(ConcurrentBagFormatter<>) }, { typeof(Dictionary<, >), typeof(DictionaryFormatter<, >) }, { typeof(SortedDictionary<, >), typeof(SortedDictionaryFormatter<, >) }, { typeof(SortedList<, >), typeof(SortedListFormatter<, >) }, { typeof(ConcurrentDictionary<, >), typeof(ConcurrentDictionaryFormatter<, >) }, { typeof(ReadOnlyCollection<>), typeof(ReadOnlyCollectionFormatter<>) }, { typeof(ReadOnlyObservableCollection<>), typeof(ReadOnlyObservableCollectionFormatter<>) }, { typeof(BlockingCollection<>), typeof(BlockingCollectionFormatter<>) } }; ImmutableCollectionFormatters = new Dictionary<Type, Type> { { typeof(ImmutableArray<>), typeof(ImmutableArrayFormatter<>) }, { typeof(ImmutableList<>), typeof(ImmutableListFormatter<>) }, { typeof(ImmutableQueue<>), typeof(ImmutableQueueFormatter<>) }, { typeof(ImmutableStack<>), typeof(ImmutableStackFormatter<>) }, { typeof(ImmutableDictionary<, >), typeof(ImmutableDictionaryFormatter<, >) }, { typeof(ImmutableSortedDictionary<, >), typeof(ImmutableSortedDictionaryFormatter<, >) }, { typeof(ImmutableSortedSet<>), typeof(ImmutableSortedSetFormatter<>) }, { typeof(ImmutableHashSet<>), typeof(ImmutableHashSetFormatter<>) }, { typeof(IImmutableList<>), typeof(InterfaceImmutableListFormatter<>) }, { typeof(IImmutableQueue<>), typeof(InterfaceImmutableQueueFormatter<>) }, { typeof(IImmutableStack<>), typeof(InterfaceImmutableStackFormatter<>) }, { typeof(IImmutableDictionary<, >), typeof(InterfaceImmutableDictionaryFormatter<, >) }, { typeof(IImmutableSet<>), typeof(InterfaceImmutableSetFormatter<>) } }; InterfaceCollectionFormatters = new Dictionary<Type, Type>(11) { { typeof(IEnumerable<>), typeof(InterfaceEnumerableFormatter<>) }, { typeof(ICollection<>), typeof(InterfaceCollectionFormatter<>) }, { typeof(IReadOnlyCollection<>), typeof(InterfaceReadOnlyCollectionFormatter<>) }, { typeof(IList<>), typeof(InterfaceListFormatter<>) }, { typeof(IReadOnlyList<>), typeof(InterfaceReadOnlyListFormatter<>) }, { typeof(IDictionary<, >), typeof(InterfaceDictionaryFormatter<, >) }, { typeof(IReadOnlyDictionary<, >), typeof(InterfaceReadOnlyDictionaryFormatter<, >) }, { typeof(ILookup<, >), typeof(InterfaceLookupFormatter<, >) }, { typeof(IGrouping<, >), typeof(InterfaceGroupingFormatter<, >) }, { typeof(ISet<>), typeof(InterfaceSetFormatter<>) } }; formatters = new ConcurrentDictionary<Type, IMemoryPackFormatter>(Environment.ProcessorCount, 150); genericFormatterFactory = new ConcurrentDictionary<Type, Type>(); genericCollectionFormatterFactory = new ConcurrentDictionary<Type, Type>(); KnownGenericTypeFormatters = new Dictionary<Type, Type>(3) { { typeof(KeyValuePair<, >), typeof(KeyValuePairFormatter<, >) }, { typeof(Lazy<>), typeof(LazyFormatter<>) }, { typeof(Nullable<>), typeof(NullableFormatter<>) } }; RegisterWellKnownTypesFormatters(); } public static bool IsRegistered<T>() { return Check<T>.registered; } public static void Register<T>(MemoryPackFormatter<T> formatter) { Check<T>.registered = true; formatters[typeof(T)] = formatter; Cache<T>.formatter = formatter; } public static void RegisterGenericType(Type genericType, Type genericFormatterType) { if (genericType.IsGenericType && genericFormatterType.IsGenericType) { genericFormatterFactory[genericType] = genericFormatterType; } else { MemoryPackSerializationException.ThrowMessage("Registered type is not generic type. genericType:" + genericType.FullName + ", formatterType:" + genericFormatterType.FullName); } } public static void RegisterCollection<TCollection, TElement>() where TCollection : ICollection<TElement?>, new() { Register(new GenericCollectionFormatter<TCollection, TElement>()); } public static void RegisterCollection(Type genericCollectionType) { if (genericCollectionType.IsGenericType && genericCollectionType.GetGenericArguments().Length == 1) { genericCollectionFormatterFactory[genericCollectionType] = typeof(GenericCollectionFormatter<, >); } else { MemoryPackSerializationException.ThrowMessage("Registered generic collection is not filled generic formatter constraint. type: " + genericCollectionType.FullName); } } public static void RegisterSet<TSet, TElement>() where TSet : ISet<TElement?>, new() { Register(new GenericSetFormatter<TSet, TElement>()); } public static void RegisterSet(Type genericSetType) { if (genericSetType.IsGenericType && genericSetType.GetGenericArguments().Length == 1) { genericCollectionFormatterFactory[genericSetType] = typeof(GenericSetFormatter<, >); } else { MemoryPackSerializationException.ThrowMessage("Registered generic set is not filled generic formatter constraint. type: " + genericSetType.FullName); } } public static void RegisterDictionary<TDictionary, TKey, TValue>() where TDictionary : IDictionary<TKey, TValue?>, new() where TKey : notnull { Register(new GenericDictionaryFormatter<TDictionary, TKey, TValue>()); } public static void RegisterDictionary(Type genericDictionaryType) { if (genericDictionaryType.IsGenericType && genericDictionaryType.GetGenericArguments().Length == 2) { genericCollectionFormatterFactory[genericDictionaryType] = typeof(GenericDictionaryFormatter<, , >); } else { MemoryPackSerializationException.ThrowMessage("Registered generic collection is not filled generic formatter constraint. type: " + genericDictionaryType.FullName); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static MemoryPackFormatter<T> GetFormatter<T>() { return Cache<T>.formatter; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static IMemoryPackFormatter GetFormatter(Type type) { if (formatters.TryGetValue(type, out IMemoryPackFormatter value)) { return value; } if (TryInvokeRegisterFormatter(type) && formatters.TryGetValue(type, out value)) { return value; } if (TypeHelpers.IsAnonymous(type)) { value = new ErrorMemoryPackFormatter(type, "Serialize anonymous type is not supported, use record or tuple instead."); } else { IMemoryPackFormatter memoryPackFormatter = CreateGenericFormatter(type, typeIsReferenceOrContainsReferences: true) as IMemoryPackFormatter; if (memoryPackFormatter == null) { memoryPackFormatter = new ErrorMemoryPackFormatter(type); } value = memoryPackFormatter; } formatters[type] = value; return value; } private static bool TryInvokeRegisterFormatter(Type type) { if (typeof(IMemoryPackFormatterRegister).IsAssignableFrom(type)) { MethodInfo method = type.GetMethod("MemoryPack.IMemoryPackFormatterRegister.RegisterFormatter", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { method = type.GetMethod("RegisterFormatter", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } if (method == null) { throw new InvalidOperationException("Type implements IMemoryPackFormatterRegister but can not found RegisterFormatter. Type: " + type.FullName); } method.Invoke(null, null); return true; } return false; } internal static object? CreateGenericFormatter(Type type, bool typeIsReferenceOrContainsReferences) { Type type2 = null; if (type.IsArray) { if (type.IsSZArray) { type2 = (typeIsReferenceOrContainsReferences ? typeof(ArrayFormatter<>).MakeGenericType(type.GetElementType()) : typeof(DangerousUnmanagedArrayFormatter<>).MakeGenericType(type.GetElementType())); } else { switch (type.GetArrayRank()) { case 2: type2 = typeof(TwoDimensionalArrayFormatter<>).MakeGenericType(type.GetElementType()); break; case 3: type2 = typeof(ThreeDimensionalArrayFormatter<>).MakeGenericType(type.GetElementType()); break; case 4: type2 = typeof(FourDimensionalArrayFormatter<>).MakeGenericType(type.GetElementType()); break; default: return null; } } } else if (type.IsEnum || !typeIsReferenceOrContainsReferences) { type2 = typeof(DangerousUnmanagedFormatter<>).MakeGenericType(type); } else { type2 = TryCreateGenericFormatterType(type, TupleFormatterTypes.TupleFormatters); if (!(type2 != null)) { type2 = TryCreateGenericFormatterType(type, KnownGenericTypeFormatters); if (!(type2 != null)) { type2 = TryCreateGenericFormatterType(type, ArrayLikeFormatters); if (!(type2 != null)) { type2 = TryCreateGenericFormatterType(type, CollectionFormatters); if (!(type2 != null)) { type2 = TryCreateGenericFormatterType(type, ImmutableCollectionFormatters); if (!(type2 != null)) { type2 = TryCreateGenericFormatterType(type, InterfaceCollectionFormatters); if (!(type2 != null)) { type2 = TryCreateGenericFormatterType(type, genericFormatterFactory); if (!(type2 != null)) { type2 = TryCreateGenericCollectionFormatterType(type); if (!(type2 != null)) { return null; } } } } } } } } } return Activator.CreateInstance(type2); } private static Type? TryCreateGenericFormatterType(Type type, IDictionary<Type, Type> knownTypes) { if (type.IsGenericType) { Type genericTypeDefinition = type.GetGenericTypeDefinition(); if (knownTypes.TryGetValue(genericTypeDefinition, out Type value)) { return value.MakeGenericType(type.GetGenericArguments()); } } return null; } private static Type? TryCreateGenericCollectionFormatterType(Type type) { if (type.IsGenericType && genericCollectionFormatterFactory.TryGetValue(type, out Type value)) { Type[] genericArguments = type.GetGenericTypeDefinition().GetGenericArguments(); return value.MakeGenericType(genericArguments.Prepend(type).ToArray()); } return null; } internal static void RegisterWellKnownTypesFormatters() { Register(new UnmanagedFormatter<sbyte>()); Register(new UnmanagedArrayFormatter<sbyte>()); Register(new NullableFormatter<sbyte>()); Register(new UnmanagedFormatter<byte>()); Register(new UnmanagedArrayFormatter<byte>()); Register(new NullableFormatter<byte>()); Register(new UnmanagedFormatter<short>()); Register(new UnmanagedArrayFormatter<short>()); Register(new NullableFormatter<short>()); Register(new UnmanagedFormatter<ushort>()); Register(new UnmanagedArrayFormatter<ushort>()); Register(new NullableFormatter<ushort>()); Register(new UnmanagedFormatter<int>()); Register(new UnmanagedArrayFormatter<int>()); Register(new NullableFormatter<int>()); Register(new UnmanagedFormatter<uint>()); Register(new UnmanagedArrayFormatter<uint>()); Register(new NullableFormatter<uint>()); Register(new UnmanagedFormatter<long>()); Register(new UnmanagedArrayFormatter<long>()); Register(new NullableFormatter<long>()); Register(new UnmanagedFormatter<ulong>()); Register(new UnmanagedArrayFormatter<ulong>()); Register(new NullableFormatter<ulong>()); Register(new UnmanagedFormatter<char>()); Register(new UnmanagedArrayFormatter<char>()); Register(new NullableFormatter<char>()); Register(new UnmanagedFormatter<float>()); Register(new UnmanagedArrayFormatter<float>()); Register(new NullableFormatter<float>()); Register(new UnmanagedFormatter<double>()); Register(new UnmanagedArrayFormatter<double>()); Register(new NullableFormatter<double>()); Register(new UnmanagedFormatter<decimal>()); Register(new UnmanagedArrayFormatter<decimal>()); Register(new NullableFormatter<decimal>()); Register(new UnmanagedFormatter<bool>()); Register(new UnmanagedArrayFormatter<bool>()); Register(new NullableFormatter<bool>()); Register(new UnmanagedFormatter<IntPtr>()); Register(new UnmanagedArrayFormatter<IntPtr>()); Register(new NullableFormatter<IntPtr>()); Register(new UnmanagedFormatter<UIntPtr>()); Register(new UnmanagedArrayFormatter<UIntPtr>()); Register(new NullableFormatter<UIntPtr>()); Register(new UnmanagedFormatter<DateTime>()); Register(new UnmanagedArrayFormatter<DateTime>()); Register(new NullableFormatter<DateTime>()); Register(new UnmanagedFormatter<DateTimeOffset>()); Register(new UnmanagedArrayFormatter<DateTimeOffset>()); Register(new NullableFormatter<DateTimeOffset>()); Register(new UnmanagedFormatter<TimeSpan>()); Register(new UnmanagedArrayFormatter<TimeSpan>()); Register(new NullableFormatter<TimeSpan>()); Register(new UnmanagedFormatter<Guid>()); Register(new UnmanagedArrayFormatter<Guid>()); Register(new NullableFormatter<Guid>()); Register(new UnmanagedFormatter<Complex>()); Register(new UnmanagedArrayFormatter<Complex>()); Register(new NullableFormatter<Complex>()); Register(new UnmanagedFormatter<Plane>()); Register(new UnmanagedArrayFormatter<Plane>()); Register(new NullableFormatter<Plane>()); Register(new UnmanagedFormatter<Quaternion>()); Register(new UnmanagedArrayFormatter<Quaternion>()); Register(new NullableFormatter<Quaternion>()); Register(new UnmanagedFormatter<Matrix3x2>()); Register(new UnmanagedArrayFormatter<Matrix3x2>()); Register(new NullableFormatter<Matrix3x2>()); Register(new UnmanagedFormatter<Matrix4x4>()); Register(new UnmanagedArrayFormatter<Matrix4x4>()); Register(new NullableFormatter<Matrix4x4>()); Register(new UnmanagedFormatter<Vector2>()); Register(new UnmanagedArrayFormatter<Vector2>()); Register(new NullableFormatter<Vector2>()); Register(new UnmanagedFormatter<Vector3>()); Register(new UnmanagedArrayFormatter<Vector3>()); Register(new NullableFormatter<Vector3>()); Register(new UnmanagedFormatter<Vector4>()); Register(new UnmanagedArrayFormatter<Vector4>()); Register(new NullableFormatter<Vector4>()); Register(new StringFormatter()); Register(new ArrayFormatter<string>()); Register(new VersionFormatter()); Register(new ArrayFormatter<Version>()); Register(new UriFormatter()); Register(new ArrayFormatter<Uri>()); Register(new TimeZoneInfoFormatter()); Register(new ArrayFormatter<TimeZoneInfo>()); Register(new BigIntegerFormatter()); Register(new ArrayFormatter<BigInteger>()); Register(new BitArrayFormatter()); Register(new ArrayFormatter<BitArray>()); Register(new StringBuilderFormatter()); Register(new ArrayFormatter<StringBuilder>()); Register(new TypeFormatter()); Register(new ArrayFormatter<Type>()); Register(new CultureInfoFormatter()); Register(new ArrayFormatter<CultureInfo>()); } } public interface IMemoryPackFormatterRegister { } public interface IMemoryPackable<T> : IMemoryPackFormatterRegister { } [Preserve] public interface IMemoryPackFormatter { [Preserve] void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref object? value) where TBufferWriter : class, IBufferWriter<byte>; [Preserve] void Deserialize(ref MemoryPackReader reader, scoped ref object? value); } [Preserve] public interface IMemoryPackFormatter<T> { [Preserve] void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref T? value) where TBufferWriter : class, IBufferWriter<byte>; [Preserve] void Deserialize(ref MemoryPackReader reader, scoped ref T? value); } [Preserve] public abstract class MemoryPackFormatter<T> : IMemoryPackFormatter<T>, IMemoryPackFormatter { [Preserve] public abstract void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref T? value) where TBufferWriter : class, IBufferWriter<byte>; [Preserve] public abstract void Deserialize(ref MemoryPackReader reader, scoped ref T? value); [Preserve] void IMemoryPackFormatter.Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref object? value) { T value2 = ((value == null) ? default(T) : ((T)value)); Serialize(ref writer, ref value2); } [Preserve] void IMemoryPackFormatter.Deserialize(ref MemoryPackReader reader, scoped ref object? value) { T value2 = ((value == null) ? default(T) : ((T)value)); Deserialize(ref reader, ref value2); value = value2; } } public static class MemoryPackCode { public const int NullCollection = -1; public const byte WideTag = 250; public const byte ReferenceId = 250; public const byte Reserved1 = 250; public const byte Reserved2 = 251; public const byte Reserved3 = 252; public const byte Reserved4 = 253; public const byte Reserved5 = 254; public const byte NullObject = byte.MaxValue; internal static ReadOnlySpan<byte> NullCollectionData => new byte[4] { 255, 255, 255, 255 }; internal static ReadOnlySpan<byte> ZeroCollectionData => new byte[4] { 0, 0, 0, 0 }; } internal sealed class ErrorMemoryPackFormatter : IMemoryPackFormatter { private readonly Type type; private readonly string? message; public ErrorMemoryPackFormatter(Type type) { this.type = type; message = null; } public ErrorMemoryPackFormatter(Type type, string message) { this.type = type; this.message = message; } public void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref object? value) where TBufferWriter : class, IBufferWriter<byte> { Throw(); } public void Deserialize(ref MemoryPackReader reader, scoped ref object? value) { Throw(); } [DoesNotReturn] private void Throw() { if (message != null) { MemoryPackSerializationException.ThrowMessage(message); } else { MemoryPackSerializationException.ThrowNotRegisteredInProvider(type); } } } internal sealed class ErrorMemoryPackFormatter<T> : MemoryPackFormatter<T> { private readonly Exception? exception; private readonly string? message; public ErrorMemoryPackFormatter() { exception = null; message = null; } public ErrorMemoryPackFormatter(Exception exception) { this.exception = exception; message = null; } public ErrorMemoryPackFormatter(string message) { exception = null; this.message = message; } public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref T? value) { Throw(); } public override void Deserialize(ref MemoryPackReader reader, scoped ref T? value) { Throw(); } [DoesNotReturn] private void Throw() { if (exception != null) { MemoryPackSerializationException.ThrowRegisterInProviderFailed(typeof(T), exception); } else if (message != null) { MemoryPackSerializationException.ThrowMessage(message); } else { MemoryPackSerializationException.ThrowNotRegisteredInProvider(typeof(T)); } } } [StructLayout(LayoutKind.Auto)] public ref struct MemoryPackReader { private ReadOnlySequence<byte> bufferSource; private readonly long totalLength; private ReadOnlySpan<byte> bufferReference; private int bufferLength; private byte[]? rentBuffer; private int advancedCount; private int consumed; private readonly MemoryPackReaderOptionalState optionalState; public int Consumed => consumed; public long Remaining => totalLength - consumed; public MemoryPackReaderOptionalState OptionalState => optionalState; public MemoryPackSerializerOptions Options => optionalState.Options; public MemoryPackReader(in ReadOnlySequence<byte> sequence, MemoryPackReaderOptionalState optionalState) { bufferSource = (sequence.IsSingleSegment ? ReadOnlySequence<byte>.Empty : sequence); ReadOnlySpan<byte> readOnlySpan = (bufferReference = sequence.FirstSpan); bufferLength = readOnlySpan.Length; advancedCount = 0; consumed = 0; rentBuffer = null; totalLength = sequence.Length; this.optionalState = optionalState; } public MemoryPackReader(ReadOnlySpan<byte> buffer, MemoryPackReaderOptionalState optionalState) { bufferSource = ReadOnlySequence<byte>.Empty; bufferReference = buffer; bufferLength = buffer.Length; advancedCount = 0; consumed = 0; rentBuffer = null; totalLength = buffer.Length; this.optionalState = optionalState; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref byte GetSpanReference(int sizeHint) { if (sizeHint <= bufferLength) { return ref MemoryMarshal.GetReference(bufferReference); } return ref GetNextSpan(sizeHint); } [MethodImpl(MethodImplOptions.NoInlining)] private ref byte GetNextSpan(int sizeHint) { if (rentBuffer != null) { ArrayPool<byte>.Shared.Return(rentBuffer); rentBuffer = null; } if (Remaining == 0L) { MemoryPackSerializationException.ThrowSequenceReachedEnd(); } try { bufferSource = bufferSource.Slice(advancedCount); } catch (ArgumentOutOfRangeException) { MemoryPackSerializationException.ThrowSequenceReachedEnd(); } advancedCount = 0; if (sizeHint <= Remaining) { if (sizeHint <= bufferSource.FirstSpan.Length) { bufferReference = bufferSource.FirstSpan; bufferLength = bufferSource.FirstSpan.Length; return ref MemoryMarshal.GetReference(bufferReference); } rentBuffer = ArrayPool<byte>.Shared.Rent(sizeHint); ReadOnlySequence<byte> source = bufferSource.Slice(0, sizeHint); BuffersExtensions.CopyTo(in source, rentBuffer); Span<byte> span = rentBuffer.AsSpan(0, sizeHint); bufferReference = span; bufferLength = span.Length; return ref MemoryMarshal.GetReference(bufferReference); } MemoryPackSerializationException.ThrowSequenceReachedEnd(); return ref MemoryMarshal.GetReference(bufferReference); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Advance(int count) { if (count != 0) { int num = bufferLength - count; if (num >= 0 || !TryAdvanceSequence(count)) { bufferLength = num; bufferReference = bufferReference.Slice(count); advancedCount += count; consumed += count; } } } [MethodImpl(MethodImplOptions.NoInlining)] private bool TryAdvanceSequence(int count) { if (bufferSource.Length - count < 0) { MemoryPackSerializationException.ThrowInvalidAdvance(); } bufferSource = bufferSource.Slice(advancedCount + count); bufferReference = bufferSource.FirstSpan; bufferLength = bufferSource.FirstSpan.Length; advancedCount = 0; consumed += count; return true; } public void GetRemainingSource(out ReadOnlySpan<byte> singleSource, out ReadOnlySequence<byte> remainingSource) { if (bufferSource.IsEmpty) { remainingSource = ReadOnlySequence<byte>.Empty; singleSource = bufferReference; return; } if (bufferSource.IsSingleSegment) { remainingSource = ReadOnlySequence<byte>.Empty; singleSource = bufferSource.FirstSpan.Slice(advancedCount); return; } singleSource = default(ReadOnlySpan<byte>); remainingSource = bufferSource.Slice(advancedCount); if (remainingSource.IsSingleSegment) { singleSource = remainingSource.FirstSpan; remainingSource = ReadOnlySequence<byte>.Empty; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { if (rentBuffer != null) { ArrayPool<byte>.Shared.Return(rentBuffer); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public IMemoryPackFormatter GetFormatter(Type type) { return MemoryPackFormatterProvider.GetFormatter(type); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public IMemoryPackFormatter<T> GetFormatter<T>() { return MemoryPackFormatterProvider.GetFormatter<T>(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryReadObjectHeader(out byte memberCount) { memberCount = GetSpanReference(1); Advance(1); return memberCount != byte.MaxValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryReadUnionHeader(out ushort tag) { byte spanReference = GetSpanReference(1); Advance(1); if (spanReference < 250) { tag = spanReference; return true; } if (spanReference == 250) { ReadUnmanaged<ushort>(out tag); return true; } tag = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryReadCollectionHeader(out int length) { length = Unsafe.ReadUnaligned<int>(ref GetSpanReference(4)); Advance(4); if (Remaining < length) { MemoryPackSerializationException.ThrowInsufficientBufferUnless(length); } return length != -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool PeekIsNull() { return GetSpanReference(1) == byte.MaxValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryPeekObjectHeader(out byte memberCount) { memberCount = GetSpanReference(1); return memberCount != byte.MaxValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryPeekUnionHeader(out ushort tag) { byte spanReference = GetSpanReference(1); if (spanReference < 250) { tag = spanReference; return true; } if (spanReference == 250) { tag = Unsafe.ReadUnaligned<ushort>(ref Unsafe.Add(ref GetSpanReference(3), 1)); return true; } tag = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryPeekCollectionHeader(out int length) { length = Unsafe.ReadUnaligned<int>(ref GetSpanReference(4)); if (Remaining < length) { MemoryPackSerializationException.ThrowInsufficientBufferUnless(length); } return length != -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool DangerousTryReadCollectionHeader(out int length) { length = Unsafe.ReadUnaligned<int>(ref GetSpanReference(4)); Advance(4); return length != -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public string? ReadString() { if (!TryReadCollectionHeader(out var length)) { return null; } if (length == 0) { return ""; } if (length > 0) { return ReadUtf16(length); } return ReadUtf8(length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private string ReadUtf16(int length) { int num = checked(length * 2); string result = new string(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<byte, char>(ref GetSpanReference(num)), length)); Advance(num); return result; } [MethodImpl(MethodImplOptions.NoInlining)] private string ReadUtf8(int utf8Length) { utf8Length = ~utf8Length; ref byte spanReference = ref GetSpanReference(utf8Length + 4); int num = Unsafe.ReadUnaligned<int>(ref spanReference); string @string; if (num <= 0) { ReadOnlySpan<byte> bytes = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.Add(ref spanReference, 4), utf8Length); @string = Encoding.UTF8.GetString(bytes); } else { long num2 = (Remaining + 1) * 3; if (num2 < 0) { num2 = 2147483647L; } if (num2 < num) { MemoryPackSerializationException.ThrowInsufficientBufferUnless(utf8Length); } ReadOnlySpan<byte> bytes2 = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.Add(ref spanReference, 4), utf8Length); @string = Encoding.UTF8.GetString(bytes2); } Advance(utf8Length + 4); return @string; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T1 ReadUnmanaged<T1>() where T1 : unmanaged { int num = Unsafe.SizeOf<T1>(); T1 result = Unsafe.ReadUnaligned<T1>(ref GetSpanReference(num)); Advance(num); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadPackable<T>(scoped ref T? value) where T : IMemoryPackable<T> { ReadValue(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T? ReadPackable<T>() where T : IMemoryPackable<T> { return ReadValue<T>(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadValue<T>(scoped ref T? value) { GetFormatter<T>().Deserialize(ref this, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T? ReadValue<T>() { T value = default(T); GetFormatter<T>().Deserialize(ref this, ref value); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadValue(Type type, ref object? value) { GetFormatter(type).Deserialize(ref this, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public object? ReadValue(Type type) { object value = null; GetFormatter(type).Deserialize(ref this, ref value); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadValueWithFormatter<TFormatter, T>(TFormatter formatter, scoped ref T? value) where TFormatter : IMemoryPackFormatter<T> { formatter.Deserialize(ref this, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T? ReadValueWithFormatter<TFormatter, T>(TFormatter formatter) where TFormatter : IMemoryPackFormatter<T> { T value = default(T); formatter.Deserialize(ref this, ref value); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T?[]? ReadArray<T>() { T[] value = null; ReadArray(ref value); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadArray<T>(scoped ref T?[]? value) { if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { DangerousReadUnmanagedArray(ref value); return; } if (!TryReadCollectionHeader(out var length)) { value = null; return; } if (length == 0) { value = Array.Empty<T>(); return; } if (value == null || value.Length != length) { value = new T[length]; } IMemoryPackFormatter<T> formatter = GetFormatter<T>(); for (int i = 0; i < length; i++) { formatter.Deserialize(ref this, ref value[i]); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadSpan<T>(scoped ref Span<T?> value) { if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { DangerousReadUnmanagedSpan(ref value); return; } if (!TryReadCollectionHeader(out var length)) { value = default(Span<T>); return; } if (length == 0) { value = Array.Empty<T>(); return; } if (value.Length != length) { value = new T[length]; } IMemoryPackFormatter<T> formatter = GetFormatter<T>(); for (int i = 0; i < length; i++) { formatter.Deserialize(ref this, ref value[i]); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T?[]? ReadPackableArray<T>() where T : IMemoryPackable<T> { T[] value = null; ReadPackableArray(ref value); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadPackableArray<T>(scoped ref T?[]? value) where T : IMemoryPackable<T> { ReadArray(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadPackableSpan<T>(scoped ref Span<T?> value) where T : IMemoryPackable<T> { ReadSpan(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T[]? ReadUnmanagedArray<T>() where T : unmanaged { return DangerousReadUnmanagedArray<T>(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanagedArray<T>(scoped ref T[]? value) where T : unmanaged { DangerousReadUnmanagedArray(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanagedSpan<T>(scoped ref Span<T> value) where T : unmanaged { DangerousReadUnmanagedSpan(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T[]? DangerousReadUnmanagedArray<T>() { if (!TryReadCollectionHeader(out var length)) { return null; } if (length == 0) { return Array.Empty<T>(); } int num = length * Unsafe.SizeOf<T>(); ref byte spanReference = ref GetSpanReference(num); T[] array = MemoryMarshalEx.AllocateUninitializedArray<T>(length); Unsafe.CopyBlockUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshalEx.GetArrayDataReference(array)), ref spanReference, (uint)num); Advance(num); return array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanagedArray<T>(scoped ref T[]? value) { if (!TryReadCollectionHeader(out var length)) { value = null; return; } if (length == 0) { value = Array.Empty<T>(); return; } int num = length * Unsafe.SizeOf<T>(); ref byte spanReference = ref GetSpanReference(num); if (value == null || value.Length != length) { value = MemoryMarshalEx.AllocateUninitializedArray<T>(length); } Unsafe.CopyBlockUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshalEx.GetArrayDataReference(value)), ref spanReference, (uint)num); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanagedSpan<T>(scoped ref Span<T> value) { if (!TryReadCollectionHeader(out var length)) { value = default(Span<T>); return; } if (length == 0) { value = Array.Empty<T>(); return; } int num = length * Unsafe.SizeOf<T>(); ref byte spanReference = ref GetSpanReference(num); if (value == null || value.Length != length) { value = MemoryMarshalEx.AllocateUninitializedArray<T>(length); } Unsafe.CopyBlockUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), ref spanReference, (uint)num); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadSpanWithoutReadLengthHeader<T>(int length, scoped ref Span<T?> value) { if (length == 0) { value = Array.Empty<T>(); } else if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { if (value.Length != length) { value = MemoryMarshalEx.AllocateUninitializedArray<T>(length); } int num = length * Unsafe.SizeOf<T>(); ref byte spanReference = ref GetSpanReference(num); Unsafe.CopyBlockUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), ref spanReference, (uint)num); Advance(num); } else { if (value.Length != length) { value = new T[length]; } IMemoryPackFormatter<T> formatter = GetFormatter<T>(); for (int i = 0; i < length; i++) { formatter.Deserialize(ref this, ref value[i]); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadPackableSpanWithoutReadLengthHeader<T>(int length, scoped ref Span<T?> value) where T : IMemoryPackable<T> { ReadSpanWithoutReadLengthHeader(length, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanagedSpanView<T>(out bool isNull, out ReadOnlySpan<byte> view) { if (!TryReadCollectionHeader(out var length)) { isNull = true; view = default(ReadOnlySpan<byte>); return; } isNull = false; if (length == 0) { view = Array.Empty<byte>(); return; } int num = length * Unsafe.SizeOf<T>(); ReadOnlySpan<byte> readOnlySpan = MemoryMarshal.CreateReadOnlySpan(ref GetSpanReference(num), num); Advance(num); view = readOnlySpan; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1>(out T1 value1) where T1 : unmanaged { int num = Unsafe.SizeOf<T1>(); value1 = Unsafe.ReadUnaligned<T1>(ref GetSpanReference(num)); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2>(out T1 value1, out T2 value2) where T1 : unmanaged where T2 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3>(out T1 value1, out T2 value2, out T3 value3) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4>(out T1 value1, out T2 value2, out T3 value3, out T4 value4) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged where T7 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged where T7 : unmanaged where T8 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged where T7 : unmanaged where T8 : unmanaged where T9 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged where T7 : unmanaged where T8 : unmanaged where T9 : unmanaged where T10 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged where T7 : unmanaged where T8 : unmanaged where T9 : unmanaged where T10 : unmanaged where T11 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged where T7 : unmanaged where T8 : unmanaged where T9 : unmanaged where T10 : unmanaged where T11 : unmanaged where T12 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>())); value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged where T7 : unmanaged where T8 : unmanaged where T9 : unmanaged where T10 : unmanaged where T11 : unmanaged where T12 : unmanaged where T13 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>())); value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>())); value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13, out T14 value14) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged where T7 : unmanaged where T8 : unmanaged where T9 : unmanaged where T10 : unmanaged where T11 : unmanaged where T12 : unmanaged where T13 : unmanaged where T14 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>() + Unsafe.SizeOf<T14>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>())); value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>())); value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>())); value14 = Unsafe.ReadUnaligned<T14>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13, out T14 value14, out T15 value15) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged where T5 : unmanaged where T6 : unmanaged where T7 : unmanaged where T8 : unmanaged where T9 : unmanaged where T10 : unmanaged where T11 : unmanaged where T12 : unmanaged where T13 : unmanaged where T14 : unmanaged where T15 : unmanaged { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>() + Unsafe.SizeOf<T14>() + Unsafe.SizeOf<T15>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>())); value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>())); value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>())); value14 = Unsafe.ReadUnaligned<T14>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>())); value15 = Unsafe.ReadUnaligned<T15>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>() + Unsafe.SizeOf<T14>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1>(out T1 value1) { int num = Unsafe.SizeOf<T1>(); value1 = Unsafe.ReadUnaligned<T1>(ref GetSpanReference(num)); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2>(out T1 value1, out T2 value2) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3>(out T1 value1, out T2 value2, out T3 value3) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4>(out T1 value1, out T2 value2, out T3 value3, out T4 value4) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4, T5>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>())); value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>())); Advance(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13) { int num = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>(); ref byte spanReference = ref GetSpanReference(num); value1 = Unsafe.ReadUnaligned<T1>(ref spanReference); value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>())); value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>())); value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>())); value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>())); value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>())); value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>())); value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>())); value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>())); value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>())); value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>())); value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>())); value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanReference, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<
OmniBonk.Common.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.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net.WebSockets; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using System.Threading.Tasks; using MemoryPack; using MemoryPack.Formatters; using MemoryPack.Internal; using Microsoft.CodeAnalysis; using OmniBonk.Common.Messages; using OmniBonk.Common.Messages.GameNetworkMessages; using OmniBonk.Common.Messages.WsMessages; using OmniBonk.Common.Models; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("OmniBonk.Common")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+f19f416d7cb174ea0ff085fa86fde3f3c8fc056d")] [assembly: AssemblyProduct("OmniBonk.Common")] [assembly: AssemblyTitle("OmniBonk.Common")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace OmniBonk.Common { public static class Protocol { public const int Version = 1; public const string VersionKey = "omnibonk_protocol"; public static bool IsCompatible(string? publishedVersion) { if (int.TryParse(publishedVersion, out var result)) { return result == 1; } return false; } } public static class SteamConnectionId { public static uint FromSteamId(ulong steamId) { if (steamId == 0L) { return 0u; } return (uint)(steamId & 0xFFFFFFFFu); } } } namespace OmniBonk.Common.Models { [MemoryPackable(/*Could not decode attribute arguments.*/)] public class BossOrbModel : IMemoryPackable<BossOrbModel>, IMemoryPackFormatterRegister { [Preserve] private sealed class BossOrbModelFormatter : MemoryPackFormatter<BossOrbModel> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref BossOrbModel value) { BossOrbModel.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref BossOrbModel value) { BossOrbModel.Deserialize(ref reader, ref value); } } public QuantizedVector3 Position = new QuantizedVector3(); public uint Id { get; set; } static BossOrbModel() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<BossOrbModel>()) { MemoryPackFormatterProvider.Register<BossOrbModel>((MemoryPackFormatter<BossOrbModel>)(object)new BossOrbModelFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<BossOrbModel[]>()) { MemoryPackFormatterProvider.Register<BossOrbModel[]>((MemoryPackFormatter<BossOrbModel[]>)(object)new ArrayFormatter<BossOrbModel>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref BossOrbModel? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint id = value.Id; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint>((byte)2, ref id); Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<QuantizedVector3>>(ref writer).WritePackable<QuantizedVector3>(ref value.Position); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref BossOrbModel? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint id = default(uint); QuantizedVector3 position; if (b == 2) { if (value != null) { id = value.Id; position = value.Position; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); goto IL_009b; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); position = ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(BossOrbModel), (byte)2, b); return; } if (value == null) { id = 0u; position = null; } else { id = value.Id; position = value.Position; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); _ = 2; } } if (value != null) { goto IL_009b; } } value = new BossOrbModel { Id = id, Position = position }; return; IL_009b: value.Id = id; value.Position = position; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class EnemyModel : IMemoryPackable<EnemyModel>, IMemoryPackFormatterRegister { [Preserve] private sealed class EnemyModelFormatter : MemoryPackFormatter<EnemyModel> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref EnemyModel value) { EnemyModel.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref EnemyModel value) { EnemyModel.Deserialize(ref reader, ref value); } } public uint Id { get; set; } public float Hp { get; set; } public QuantizedVector3 Position { get; set; } = new QuantizedVector3(); public QuantizedRotation Yaw { get; set; } = new QuantizedRotation(); static EnemyModel() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<EnemyModel>()) { MemoryPackFormatterProvider.Register<EnemyModel>((MemoryPackFormatter<EnemyModel>)(object)new EnemyModelFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<EnemyModel[]>()) { MemoryPackFormatterProvider.Register<EnemyModel[]>((MemoryPackFormatter<EnemyModel[]>)(object)new ArrayFormatter<EnemyModel>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref EnemyModel? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint id = value.Id; float hp = value.Hp; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, float>((byte)4, ref id, ref hp); QuantizedVector3 position = value.Position; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<QuantizedVector3>>(ref writer).WritePackable<QuantizedVector3>(ref position); QuantizedRotation yaw = value.Yaw; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<QuantizedRotation>>(ref writer).WritePackable<QuantizedRotation>(ref yaw); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref EnemyModel? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint id = default(uint); float hp = default(float); QuantizedVector3 position; QuantizedRotation yaw; if (b == 4) { if (value != null) { id = value.Id; hp = value.Hp; position = value.Position; yaw = value.Yaw; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref hp); ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedRotation>(ref yaw); goto IL_00fb; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, float>(ref id, ref hp); position = ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(); yaw = ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedRotation>(); } else { if (b > 4) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(EnemyModel), (byte)4, b); return; } if (value == null) { id = 0u; hp = 0f; position = null; yaw = null; } else { id = value.Id; hp = value.Hp; position = value.Position; yaw = value.Yaw; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref hp); if (b != 2) { ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); if (b != 3) { ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedRotation>(ref yaw); _ = 4; } } } } if (value != null) { goto IL_00fb; } } value = new EnemyModel { Id = id, Hp = hp, Position = position, Yaw = yaw }; return; IL_00fb: value.Id = id; value.Hp = hp; value.Position = position; value.Yaw = yaw; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class InventoryInfo : IMemoryPackable<InventoryInfo>, IMemoryPackFormatterRegister { [Preserve] private sealed class InventoryInfoFormatter : MemoryPackFormatter<InventoryInfo> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref InventoryInfo value) { InventoryInfo.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref InventoryInfo value) { InventoryInfo.Deserialize(ref reader, ref value); } } public ICollection<WeaponInfo> WeaponInfos { get; set; } = new List<WeaponInfo>(); public ICollection<TomeInfo> TomeInfos { get; set; } = new List<TomeInfo>(); static InventoryInfo() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<InventoryInfo>()) { MemoryPackFormatterProvider.Register<InventoryInfo>((MemoryPackFormatter<InventoryInfo>)(object)new InventoryInfoFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<InventoryInfo[]>()) { MemoryPackFormatterProvider.Register<InventoryInfo[]>((MemoryPackFormatter<InventoryInfo[]>)(object)new ArrayFormatter<InventoryInfo>()); } if (!MemoryPackFormatterProvider.IsRegistered<ICollection<WeaponInfo>>()) { MemoryPackFormatterProvider.Register<ICollection<WeaponInfo>>((MemoryPackFormatter<ICollection<WeaponInfo>>)(object)new InterfaceCollectionFormatter<WeaponInfo>()); } if (!MemoryPackFormatterProvider.IsRegistered<ICollection<TomeInfo>>()) { MemoryPackFormatterProvider.Register<ICollection<TomeInfo>>((MemoryPackFormatter<ICollection<TomeInfo>>)(object)new InterfaceCollectionFormatter<TomeInfo>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref InventoryInfo? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } writer.WriteObjectHeader((byte)2); ICollection<WeaponInfo> weaponInfos = value.WeaponInfos; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<ICollection<WeaponInfo>>>(ref writer).WriteValue<ICollection<WeaponInfo>>(ref weaponInfos); ICollection<TomeInfo> tomeInfos = value.TomeInfos; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<ICollection<TomeInfo>>>(ref writer).WriteValue<ICollection<TomeInfo>>(ref tomeInfos); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref InventoryInfo? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } ICollection<WeaponInfo> weaponInfos; ICollection<TomeInfo> tomeInfos; if (b == 2) { if (value != null) { weaponInfos = value.WeaponInfos; tomeInfos = value.TomeInfos; ((MemoryPackReader)(ref reader)).ReadValue<ICollection<WeaponInfo>>(ref weaponInfos); ((MemoryPackReader)(ref reader)).ReadValue<ICollection<TomeInfo>>(ref tomeInfos); goto IL_009a; } weaponInfos = ((MemoryPackReader)(ref reader)).ReadValue<ICollection<WeaponInfo>>(); tomeInfos = ((MemoryPackReader)(ref reader)).ReadValue<ICollection<TomeInfo>>(); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(InventoryInfo), (byte)2, b); return; } if (value == null) { weaponInfos = null; tomeInfos = null; } else { weaponInfos = value.WeaponInfos; tomeInfos = value.TomeInfos; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadValue<ICollection<WeaponInfo>>(ref weaponInfos); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadValue<ICollection<TomeInfo>>(ref tomeInfos); _ = 2; } } if (value != null) { goto IL_009a; } } value = new InventoryInfo { WeaponInfos = weaponInfos, TomeInfos = tomeInfos }; return; IL_009a: value.WeaponInfos = weaponInfos; value.TomeInfos = tomeInfos; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class WeaponInfo : IMemoryPackable<WeaponInfo>, IMemoryPackFormatterRegister { [Preserve] private sealed class WeaponInfoFormatter : MemoryPackFormatter<WeaponInfo> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref WeaponInfo value) { WeaponInfo.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref WeaponInfo value) { WeaponInfo.Deserialize(ref reader, ref value); } } public uint EWeapon; public uint Level; static WeaponInfo() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<WeaponInfo>()) { MemoryPackFormatterProvider.Register<WeaponInfo>((MemoryPackFormatter<WeaponInfo>)(object)new WeaponInfoFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<WeaponInfo[]>()) { MemoryPackFormatterProvider.Register<WeaponInfo[]>((MemoryPackFormatter<WeaponInfo[]>)(object)new ArrayFormatter<WeaponInfo>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref WeaponInfo? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); } else { Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, uint>((byte)2, ref value.EWeapon, ref value.Level); } } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref WeaponInfo? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint eWeapon = default(uint); uint level = default(uint); if (b == 2) { if (value != null) { eWeapon = value.EWeapon; level = value.Level; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref eWeapon); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref level); goto IL_0096; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, uint>(ref eWeapon, ref level); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(WeaponInfo), (byte)2, b); return; } if (value == null) { eWeapon = 0u; level = 0u; } else { eWeapon = value.EWeapon; level = value.Level; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref eWeapon); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref level); _ = 2; } } if (value != null) { goto IL_0096; } } value = new WeaponInfo { EWeapon = eWeapon, Level = level }; return; IL_0096: value.EWeapon = eWeapon; value.Level = level; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class TomeInfo : IMemoryPackable<TomeInfo>, IMemoryPackFormatterRegister { [Preserve] private sealed class TomeInfoFormatter : MemoryPackFormatter<TomeInfo> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref TomeInfo value) { TomeInfo.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref TomeInfo value) { TomeInfo.Deserialize(ref reader, ref value); } } public uint ETome; public uint Level; static TomeInfo() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<TomeInfo>()) { MemoryPackFormatterProvider.Register<TomeInfo>((MemoryPackFormatter<TomeInfo>)(object)new TomeInfoFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<TomeInfo[]>()) { MemoryPackFormatterProvider.Register<TomeInfo[]>((MemoryPackFormatter<TomeInfo[]>)(object)new ArrayFormatter<TomeInfo>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref TomeInfo? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); } else { Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, uint>((byte)2, ref value.ETome, ref value.Level); } } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref TomeInfo? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint eTome = default(uint); uint level = default(uint); if (b == 2) { if (value != null) { eTome = value.ETome; level = value.Level; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref eTome); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref level); goto IL_0096; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, uint>(ref eTome, ref level); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(TomeInfo), (byte)2, b); return; } if (value == null) { eTome = 0u; level = 0u; } else { eTome = value.ETome; level = value.Level; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref eTome); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref level); _ = 2; } } if (value != null) { goto IL_0096; } } value = new TomeInfo { ETome = eTome, Level = level }; return; IL_0096: value.ETome = eTome; value.Level = level; } } public enum NetworkModeType { Random, Friendlies } public enum Role { Host, Client } public class NetworkMode { public NetworkModeType Mode { get; set; } public Role Role { get; set; } public string RoomCode { get; set; } = ""; public bool? EnabledSharedExperience { get; set; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class PickupModel : IMemoryPackable<PickupModel>, IMemoryPackFormatterRegister { [Preserve] private sealed class PickupModelFormatter : MemoryPackFormatter<PickupModel> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref PickupModel value) { PickupModel.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref PickupModel value) { PickupModel.Deserialize(ref reader, ref value); } } public Vector3 Position = Vector3.Zero; public uint Id { get; set; } static PickupModel() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<PickupModel>()) { MemoryPackFormatterProvider.Register<PickupModel>((MemoryPackFormatter<PickupModel>)(object)new PickupModelFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<PickupModel[]>()) { MemoryPackFormatterProvider.Register<PickupModel[]>((MemoryPackFormatter<PickupModel[]>)(object)new ArrayFormatter<PickupModel>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref PickupModel? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint id = value.Id; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, Vector3>((byte)2, ref id, ref value.Position); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref PickupModel? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint id = default(uint); Vector3 position = default(Vector3); if (b == 2) { if (value != null) { id = value.Id; position = value.Position; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); ((MemoryPackReader)(ref reader)).ReadUnmanaged<Vector3>(ref position); goto IL_009c; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, Vector3>(ref id, ref position); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(PickupModel), (byte)2, b); return; } if (value == null) { id = 0u; position = default(Vector3); } else { id = value.Id; position = value.Position; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<Vector3>(ref position); _ = 2; } } if (value != null) { goto IL_009c; } } value = new PickupModel { Id = id, Position = position }; return; IL_009c: value.Id = id; value.Position = position; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class Player : IMemoryPackable<Player>, IMemoryPackFormatterRegister { [Preserve] private sealed class PlayerFormatter : MemoryPackFormatter<Player> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref Player value) { Player.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref Player value) { Player.Deserialize(ref reader, ref value); } } public uint ConnectionId; public bool IsHost; public uint Character; public string Skin = ""; public bool IsReady; public string Name = "Player"; public QuantizedVector3 Position = new QuantizedVector3(); public uint Hp = 100u; public uint MaxHp = 100u; public uint Shield; public uint MaxShield; public uint Hat; public AnimatorState AnimatorState { get; set; } = new AnimatorState(); public MovementState MovementState { get; set; } = new MovementState(); public InventoryInfo Inventory { get; set; } = new InventoryInfo(); static Player() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<Player>()) { MemoryPackFormatterProvider.Register<Player>((MemoryPackFormatter<Player>)(object)new PlayerFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<Player[]>()) { MemoryPackFormatterProvider.Register<Player[]>((MemoryPackFormatter<Player[]>)(object)new ArrayFormatter<Player>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref Player? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, bool, uint>((byte)15, ref value.ConnectionId, ref value.IsHost, ref value.Character); writer.WriteString(value.Skin); Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<bool>>(ref writer).WriteUnmanaged<bool>(ref value.IsReady); writer.WriteString(value.Name); Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<QuantizedVector3>>(ref writer).WritePackable<QuantizedVector3>(ref value.Position); AnimatorState animatorState = value.AnimatorState; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<AnimatorState>>(ref writer).WritePackable<AnimatorState>(ref animatorState); MovementState movementState = value.MovementState; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<MovementState>>(ref writer).WritePackable<MovementState>(ref movementState); InventoryInfo inventory = value.Inventory; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<InventoryInfo>>(ref writer).WritePackable<InventoryInfo>(ref inventory); Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanaged<uint, uint, uint, uint, uint>(ref value.Hp, ref value.MaxHp, ref value.Shield, ref value.MaxShield, ref value.Hat); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref Player? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint connectionId = default(uint); bool isHost = default(bool); uint character = default(uint); bool isReady = default(bool); QuantizedVector3 position; AnimatorState animatorState; MovementState movementState; InventoryInfo inventory; uint hp = default(uint); uint maxHp = default(uint); uint shield = default(uint); uint maxShield = default(uint); uint hat = default(uint); string skin; string name; if (b == 15) { if (value != null) { connectionId = value.ConnectionId; isHost = value.IsHost; character = value.Character; skin = value.Skin; isReady = value.IsReady; name = value.Name; position = value.Position; animatorState = value.AnimatorState; movementState = value.MovementState; inventory = value.Inventory; hp = value.Hp; maxHp = value.MaxHp; shield = value.Shield; maxShield = value.MaxShield; hat = value.Hat; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref connectionId); ((MemoryPackReader)(ref reader)).ReadUnmanaged<bool>(ref isHost); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref character); skin = ((MemoryPackReader)(ref reader)).ReadString(); ((MemoryPackReader)(ref reader)).ReadUnmanaged<bool>(ref isReady); name = ((MemoryPackReader)(ref reader)).ReadString(); ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); ((MemoryPackReader)(ref reader)).ReadPackable<AnimatorState>(ref animatorState); ((MemoryPackReader)(ref reader)).ReadPackable<MovementState>(ref movementState); ((MemoryPackReader)(ref reader)).ReadPackable<InventoryInfo>(ref inventory); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref hp); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref maxHp); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref shield); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref maxShield); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref hat); goto IL_0317; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, bool, uint>(ref connectionId, ref isHost, ref character); skin = ((MemoryPackReader)(ref reader)).ReadString(); ((MemoryPackReader)(ref reader)).ReadUnmanaged<bool>(ref isReady); name = ((MemoryPackReader)(ref reader)).ReadString(); position = ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(); animatorState = ((MemoryPackReader)(ref reader)).ReadPackable<AnimatorState>(); movementState = ((MemoryPackReader)(ref reader)).ReadPackable<MovementState>(); inventory = ((MemoryPackReader)(ref reader)).ReadPackable<InventoryInfo>(); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, uint, uint, uint, uint>(ref hp, ref maxHp, ref shield, ref maxShield, ref hat); } else { if (b > 15) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(Player), (byte)15, b); return; } if (value == null) { connectionId = 0u; isHost = false; character = 0u; skin = null; isReady = false; name = null; position = null; animatorState = null; movementState = null; inventory = null; hp = 0u; maxHp = 0u; shield = 0u; maxShield = 0u; hat = 0u; } else { connectionId = value.ConnectionId; isHost = value.IsHost; character = value.Character; skin = value.Skin; isReady = value.IsReady; name = value.Name; position = value.Position; animatorState = value.AnimatorState; movementState = value.MovementState; inventory = value.Inventory; hp = value.Hp; maxHp = value.MaxHp; shield = value.Shield; maxShield = value.MaxShield; hat = value.Hat; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref connectionId); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<bool>(ref isHost); if (b != 2) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref character); if (b != 3) { skin = ((MemoryPackReader)(ref reader)).ReadString(); if (b != 4) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<bool>(ref isReady); if (b != 5) { name = ((MemoryPackReader)(ref reader)).ReadString(); if (b != 6) { ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); if (b != 7) { ((MemoryPackReader)(ref reader)).ReadPackable<AnimatorState>(ref animatorState); if (b != 8) { ((MemoryPackReader)(ref reader)).ReadPackable<MovementState>(ref movementState); if (b != 9) { ((MemoryPackReader)(ref reader)).ReadPackable<InventoryInfo>(ref inventory); if (b != 10) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref hp); if (b != 11) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref maxHp); if (b != 12) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref shield); if (b != 13) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref maxShield); if (b != 14) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref hat); _ = 15; } } } } } } } } } } } } } } } if (value != null) { goto IL_0317; } } value = new Player { ConnectionId = connectionId, IsHost = isHost, Character = character, Skin = skin, IsReady = isReady, Name = name, Position = position, AnimatorState = animatorState, MovementState = movementState, Inventory = inventory, Hp = hp, MaxHp = maxHp, Shield = shield, MaxShield = maxShield, Hat = hat }; return; IL_0317: value.ConnectionId = connectionId; value.IsHost = isHost; value.Character = character; value.Skin = skin; value.IsReady = isReady; value.Name = name; value.Position = position; value.AnimatorState = animatorState; value.MovementState = movementState; value.Inventory = inventory; value.Hp = hp; value.MaxHp = maxHp; value.Shield = shield; value.MaxShield = maxShield; value.Hat = hat; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class Projectile : IMemoryPackable<Projectile>, IMemoryPackFormatterRegister { [Preserve] private sealed class ProjectileFormatter : MemoryPackFormatter<Projectile> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref Projectile value) { Projectile.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref Projectile value) { Projectile.Deserialize(ref reader, ref value); } } public QuantizedVector3 Position = new QuantizedVector3(); public QuantizedVector3 FordwardVector = new QuantizedVector3(); public uint Id { get; set; } static Projectile() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<Projectile>()) { MemoryPackFormatterProvider.Register<Projectile>((MemoryPackFormatter<Projectile>)(object)new ProjectileFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<Projectile[]>()) { MemoryPackFormatterProvider.Register<Projectile[]>((MemoryPackFormatter<Projectile[]>)(object)new ArrayFormatter<Projectile>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref Projectile? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint id = value.Id; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint>((byte)3, ref id); Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<QuantizedVector3>>(ref writer).WritePackable<QuantizedVector3>(ref value.Position); Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<QuantizedVector3>>(ref writer).WritePackable<QuantizedVector3>(ref value.FordwardVector); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref Projectile? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint id = default(uint); QuantizedVector3 position; QuantizedVector3 fordwardVector; if (b == 3) { if (value != null) { id = value.Id; position = value.Position; fordwardVector = value.FordwardVector; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref fordwardVector); goto IL_00c8; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); position = ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(); fordwardVector = ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(); } else { if (b > 3) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(Projectile), (byte)3, b); return; } if (value == null) { id = 0u; position = null; fordwardVector = null; } else { id = value.Id; position = value.Position; fordwardVector = value.FordwardVector; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref id); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); if (b != 2) { ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref fordwardVector); _ = 3; } } } if (value != null) { goto IL_00c8; } } value = new Projectile { Id = id, Position = position, FordwardVector = fordwardVector }; return; IL_00c8: value.Id = id; value.Position = position; value.FordwardVector = fordwardVector; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class QuantizedRotation : IMemoryPackable<QuantizedRotation>, IMemoryPackFormatterRegister { [Preserve] private sealed class QuantizedRotationFormatter : MemoryPackFormatter<QuantizedRotation> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref QuantizedRotation value) { QuantizedRotation.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref QuantizedRotation value) { QuantizedRotation.Deserialize(ref reader, ref value); } } public ushort QuantizedYaw { get; set; } static QuantizedRotation() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<QuantizedRotation>()) { MemoryPackFormatterProvider.Register<QuantizedRotation>((MemoryPackFormatter<QuantizedRotation>)(object)new QuantizedRotationFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<QuantizedRotation[]>()) { MemoryPackFormatterProvider.Register<QuantizedRotation[]>((MemoryPackFormatter<QuantizedRotation[]>)(object)new ArrayFormatter<QuantizedRotation>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref QuantizedRotation? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } ushort quantizedYaw = value.QuantizedYaw; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<ushort>>(ref writer).WriteUnmanagedWithObjectHeader<ushort>((byte)1, ref quantizedYaw); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref QuantizedRotation? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } ushort quantizedYaw = default(ushort); if (b == 1) { if (value != null) { quantizedYaw = value.QuantizedYaw; ((MemoryPackReader)(ref reader)).ReadUnmanaged<ushort>(ref quantizedYaw); goto IL_006b; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<ushort>(ref quantizedYaw); } else { if (b > 1) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(QuantizedRotation), (byte)1, b); return; } quantizedYaw = (ushort)((value != null) ? value.QuantizedYaw : 0); if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<ushort>(ref quantizedYaw); _ = 1; } if (value != null) { goto IL_006b; } } value = new QuantizedRotation { QuantizedYaw = quantizedYaw }; return; IL_006b: value.QuantizedYaw = quantizedYaw; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class QuantizedVector2 : IMemoryPackable<QuantizedVector2>, IMemoryPackFormatterRegister { [Preserve] private sealed class QuantizedVector2Formatter : MemoryPackFormatter<QuantizedVector2> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref QuantizedVector2 value) { QuantizedVector2.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref QuantizedVector2 value) { QuantizedVector2.Deserialize(ref reader, ref value); } } public short QuantizedX { get; set; } public short QuantizedY { get; set; } static QuantizedVector2() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<QuantizedVector2>()) { MemoryPackFormatterProvider.Register<QuantizedVector2>((MemoryPackFormatter<QuantizedVector2>)(object)new QuantizedVector2Formatter()); } if (!MemoryPackFormatterProvider.IsRegistered<QuantizedVector2[]>()) { MemoryPackFormatterProvider.Register<QuantizedVector2[]>((MemoryPackFormatter<QuantizedVector2[]>)(object)new ArrayFormatter<QuantizedVector2>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref QuantizedVector2? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } short quantizedX = value.QuantizedX; short quantizedY = value.QuantizedY; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<short>>(ref writer).WriteUnmanagedWithObjectHeader<short, short>((byte)2, ref quantizedX, ref quantizedY); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref QuantizedVector2? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } short quantizedX = default(short); short quantizedY = default(short); if (b == 2) { if (value != null) { quantizedX = value.QuantizedX; quantizedY = value.QuantizedY; ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedX); ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedY); goto IL_0096; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<short, short>(ref quantizedX, ref quantizedY); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(QuantizedVector2), (byte)2, b); return; } if (value == null) { quantizedX = 0; quantizedY = 0; } else { quantizedX = value.QuantizedX; quantizedY = value.QuantizedY; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedX); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedY); _ = 2; } } if (value != null) { goto IL_0096; } } value = new QuantizedVector2 { QuantizedX = quantizedX, QuantizedY = quantizedY }; return; IL_0096: value.QuantizedX = quantizedX; value.QuantizedY = quantizedY; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class QuantizedVector3 : IMemoryPackable<QuantizedVector3>, IMemoryPackFormatterRegister { [Preserve] private sealed class QuantizedVector3Formatter : MemoryPackFormatter<QuantizedVector3> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref QuantizedVector3 value) { QuantizedVector3.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref QuantizedVector3 value) { QuantizedVector3.Deserialize(ref reader, ref value); } } public short QuantizedX { get; set; } public short QuantizedY { get; set; } public short QuantizedZ { get; set; } static QuantizedVector3() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<QuantizedVector3>()) { MemoryPackFormatterProvider.Register<QuantizedVector3>((MemoryPackFormatter<QuantizedVector3>)(object)new QuantizedVector3Formatter()); } if (!MemoryPackFormatterProvider.IsRegistered<QuantizedVector3[]>()) { MemoryPackFormatterProvider.Register<QuantizedVector3[]>((MemoryPackFormatter<QuantizedVector3[]>)(object)new ArrayFormatter<QuantizedVector3>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref QuantizedVector3? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } short quantizedX = value.QuantizedX; short quantizedY = value.QuantizedY; short quantizedZ = value.QuantizedZ; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<short>>(ref writer).WriteUnmanagedWithObjectHeader<short, short, short>((byte)3, ref quantizedX, ref quantizedY, ref quantizedZ); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref QuantizedVector3? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } short quantizedX = default(short); short quantizedY = default(short); short quantizedZ = default(short); if (b == 3) { if (value != null) { quantizedX = value.QuantizedX; quantizedY = value.QuantizedY; quantizedZ = value.QuantizedZ; ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedX); ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedY); ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedZ); goto IL_00be; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<short, short, short>(ref quantizedX, ref quantizedY, ref quantizedZ); } else { if (b > 3) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(QuantizedVector3), (byte)3, b); return; } if (value == null) { quantizedX = 0; quantizedY = 0; quantizedZ = 0; } else { quantizedX = value.QuantizedX; quantizedY = value.QuantizedY; quantizedZ = value.QuantizedZ; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedX); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedY); if (b != 2) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedZ); _ = 3; } } } if (value != null) { goto IL_00be; } } value = new QuantizedVector3 { QuantizedX = quantizedX, QuantizedY = quantizedY, QuantizedZ = quantizedZ }; return; IL_00be: value.QuantizedX = quantizedX; value.QuantizedY = quantizedY; value.QuantizedZ = quantizedZ; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class QuantizedVector4 : IMemoryPackable<QuantizedVector4>, IMemoryPackFormatterRegister { [Preserve] private sealed class QuantizedVector4Formatter : MemoryPackFormatter<QuantizedVector4> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref QuantizedVector4 value) { QuantizedVector4.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref QuantizedVector4 value) { QuantizedVector4.Deserialize(ref reader, ref value); } } public short QuantizedX { get; set; } public short QuantizedY { get; set; } public short QuantizedZ { get; set; } public short QuantizedW { get; set; } static QuantizedVector4() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<QuantizedVector4>()) { MemoryPackFormatterProvider.Register<QuantizedVector4>((MemoryPackFormatter<QuantizedVector4>)(object)new QuantizedVector4Formatter()); } if (!MemoryPackFormatterProvider.IsRegistered<QuantizedVector4[]>()) { MemoryPackFormatterProvider.Register<QuantizedVector4[]>((MemoryPackFormatter<QuantizedVector4[]>)(object)new ArrayFormatter<QuantizedVector4>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref QuantizedVector4? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } short quantizedX = value.QuantizedX; short quantizedY = value.QuantizedY; short quantizedZ = value.QuantizedZ; short quantizedW = value.QuantizedW; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<short>>(ref writer).WriteUnmanagedWithObjectHeader<short, short, short, short>((byte)4, ref quantizedX, ref quantizedY, ref quantizedZ, ref quantizedW); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref QuantizedVector4? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } short quantizedX = default(short); short quantizedY = default(short); short quantizedZ = default(short); short quantizedW = default(short); if (b == 4) { if (value != null) { quantizedX = value.QuantizedX; quantizedY = value.QuantizedY; quantizedZ = value.QuantizedZ; quantizedW = value.QuantizedW; ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedX); ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedY); ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedZ); ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedW); goto IL_00e9; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<short, short, short, short>(ref quantizedX, ref quantizedY, ref quantizedZ, ref quantizedW); } else { if (b > 4) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(QuantizedVector4), (byte)4, b); return; } if (value == null) { quantizedX = 0; quantizedY = 0; quantizedZ = 0; quantizedW = 0; } else { quantizedX = value.QuantizedX; quantizedY = value.QuantizedY; quantizedZ = value.QuantizedZ; quantizedW = value.QuantizedW; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedX); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedY); if (b != 2) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedZ); if (b != 3) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<short>(ref quantizedW); _ = 4; } } } } if (value != null) { goto IL_00e9; } } value = new QuantizedVector4 { QuantizedX = quantizedX, QuantizedY = quantizedY, QuantizedZ = quantizedZ, QuantizedW = quantizedW }; return; IL_00e9: value.QuantizedX = quantizedX; value.QuantizedY = quantizedY; value.QuantizedZ = quantizedZ; value.QuantizedW = quantizedW; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class TumbleWeedModel : IMemoryPackable<TumbleWeedModel>, IMemoryPackFormatterRegister { [Preserve] private sealed class TumbleWeedModelFormatter : MemoryPackFormatter<TumbleWeedModel> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref TumbleWeedModel value) { TumbleWeedModel.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref TumbleWeedModel value) { TumbleWeedModel.Deserialize(ref reader, ref value); } } public uint NetplayId { get; set; } public QuantizedVector3 Position { get; set; } static TumbleWeedModel() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<TumbleWeedModel>()) { MemoryPackFormatterProvider.Register<TumbleWeedModel>((MemoryPackFormatter<TumbleWeedModel>)(object)new TumbleWeedModelFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<TumbleWeedModel[]>()) { MemoryPackFormatterProvider.Register<TumbleWeedModel[]>((MemoryPackFormatter<TumbleWeedModel[]>)(object)new ArrayFormatter<TumbleWeedModel>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref TumbleWeedModel? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint netplayId = value.NetplayId; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint>((byte)2, ref netplayId); QuantizedVector3 position = value.Position; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<QuantizedVector3>>(ref writer).WritePackable<QuantizedVector3>(ref position); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref TumbleWeedModel? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint netplayId = default(uint); QuantizedVector3 position; if (b == 2) { if (value != null) { netplayId = value.NetplayId; position = value.Position; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref netplayId); ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); goto IL_009b; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref netplayId); position = ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(TumbleWeedModel), (byte)2, b); return; } if (value == null) { netplayId = 0u; position = null; } else { netplayId = value.NetplayId; position = value.Position; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref netplayId); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadPackable<QuantizedVector3>(ref position); _ = 2; } } if (value != null) { goto IL_009b; } } value = new TumbleWeedModel { NetplayId = netplayId, Position = position }; return; IL_009b: value.NetplayId = netplayId; value.Position = position; } } } namespace OmniBonk.Common.Messages { [MemoryPackable(/*Could not decode attribute arguments.*/)] public class ChestOpened : IGameNetworkMessage, IMemoryPackFormatterRegister, IMemoryPackable<ChestOpened> { [Preserve] private sealed class ChestOpenedFormatter : MemoryPackFormatter<ChestOpened> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref ChestOpened value) { ChestOpened.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref ChestOpened value) { ChestOpened.Deserialize(ref reader, ref value); } } public uint ChestId { get; set; } public uint OwnerId { get; set; } static ChestOpened() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<ChestOpened>()) { MemoryPackFormatterProvider.Register<ChestOpened>((MemoryPackFormatter<ChestOpened>)(object)new ChestOpenedFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<ChestOpened[]>()) { MemoryPackFormatterProvider.Register<ChestOpened[]>((MemoryPackFormatter<ChestOpened[]>)(object)new ArrayFormatter<ChestOpened>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref ChestOpened? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint chestId = value.ChestId; uint ownerId = value.OwnerId; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, uint>((byte)2, ref chestId, ref ownerId); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref ChestOpened? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint chestId = default(uint); uint ownerId = default(uint); if (b == 2) { if (value != null) { chestId = value.ChestId; ownerId = value.OwnerId; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref chestId); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref ownerId); goto IL_0096; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, uint>(ref chestId, ref ownerId); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(ChestOpened), (byte)2, b); return; } if (value == null) { chestId = 0u; ownerId = 0u; } else { chestId = value.ChestId; ownerId = value.OwnerId; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref chestId); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref ownerId); _ = 2; } } if (value != null) { goto IL_0096; } } value = new ChestOpened { ChestId = chestId, OwnerId = ownerId }; return; IL_0096: value.ChestId = chestId; value.OwnerId = ownerId; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class ClientInGameReady : IGameNetworkMessage, IMemoryPackFormatterRegister, IMemoryPackable<ClientInGameReady> { [Preserve] private sealed class ClientInGameReadyFormatter : MemoryPackFormatter<ClientInGameReady> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref ClientInGameReady value) { ClientInGameReady.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref ClientInGameReady value) { ClientInGameReady.Deserialize(ref reader, ref value); } } public uint ConnectionId { get; set; } static ClientInGameReady() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<ClientInGameReady>()) { MemoryPackFormatterProvider.Register<ClientInGameReady>((MemoryPackFormatter<ClientInGameReady>)(object)new ClientInGameReadyFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<ClientInGameReady[]>()) { MemoryPackFormatterProvider.Register<ClientInGameReady[]>((MemoryPackFormatter<ClientInGameReady[]>)(object)new ArrayFormatter<ClientInGameReady>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref ClientInGameReady? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint connectionId = value.ConnectionId; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint>((byte)1, ref connectionId); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref ClientInGameReady? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint connectionId = default(uint); if (b == 1) { if (value != null) { connectionId = value.ConnectionId; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref connectionId); goto IL_006b; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref connectionId); } else { if (b > 1) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(ClientInGameReady), (byte)1, b); return; } connectionId = ((value != null) ? value.ConnectionId : 0u); if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref connectionId); _ = 1; } if (value != null) { goto IL_006b; } } value = new ClientInGameReady { ConnectionId = connectionId }; return; IL_006b: value.ConnectionId = connectionId; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class ClientReadyMessage : IWsMessage, IMemoryPackFormatterRegister, IMemoryPackable<ClientReadyMessage> { [Preserve] private sealed class ClientReadyMessageFormatter : MemoryPackFormatter<ClientReadyMessage> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref ClientReadyMessage value) { ClientReadyMessage.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref ClientReadyMessage value) { ClientReadyMessage.Deserialize(ref reader, ref value); } } static ClientReadyMessage() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<ClientReadyMessage>()) { MemoryPackFormatterProvider.Register<ClientReadyMessage>((MemoryPackFormatter<ClientReadyMessage>)(object)new ClientReadyMessageFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<ClientReadyMessage[]>()) { MemoryPackFormatterProvider.Register<ClientReadyMessage[]>((MemoryPackFormatter<ClientReadyMessage[]>)(object)new ArrayFormatter<ClientReadyMessage>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref ClientReadyMessage? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); } else { writer.WriteObjectHeader((byte)0); } } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref ClientReadyMessage? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } if (b == 0) { if (value != null) { return; } } else { if (b > 0) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(ClientReadyMessage), (byte)0, b); return; } _ = value; if (value != null) { return; } } value = new ClientReadyMessage(); } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class EnemyDamaged : IGameNetworkMessage, IMemoryPackFormatterRegister, IMemoryPackable<EnemyDamaged> { [Preserve] private sealed class EnemyDamagedFormatter : MemoryPackFormatter<EnemyDamaged> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref EnemyDamaged value) { EnemyDamaged.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref EnemyDamaged value) { EnemyDamaged.Deserialize(ref reader, ref value); } } public uint EnemyId { get; set; } public float Damage { get; set; } public int DamageEffect { get; set; } public int DamageBlockedByArmor { get; set; } public string DamageSource { get; set; } public float DamageProcCoefficient { get; set; } public int DamageElement { get; set; } public int DamageFlags { get; set; } public float DamageKnockback { get; set; } public bool DamageIsCrit { get; set; } public uint AttackerId { get; set; } static EnemyDamaged() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<EnemyDamaged>()) { MemoryPackFormatterProvider.Register<EnemyDamaged>((MemoryPackFormatter<EnemyDamaged>)(object)new EnemyDamagedFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<EnemyDamaged[]>()) { MemoryPackFormatterProvider.Register<EnemyDamaged[]>((MemoryPackFormatter<EnemyDamaged[]>)(object)new ArrayFormatter<EnemyDamaged>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref EnemyDamaged? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint enemyId = value.EnemyId; float damage = value.Damage; int damageEffect = value.DamageEffect; int damageBlockedByArmor = value.DamageBlockedByArmor; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, float, int, int>((byte)11, ref enemyId, ref damage, ref damageEffect, ref damageBlockedByArmor); writer.WriteString(value.DamageSource); float damageProcCoefficient = value.DamageProcCoefficient; int damageElement = value.DamageElement; int damageFlags = value.DamageFlags; float damageKnockback = value.DamageKnockback; bool damageIsCrit = value.DamageIsCrit; uint attackerId = value.AttackerId; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<float>>(ref writer).WriteUnmanaged<float, int, int, float, bool, uint>(ref damageProcCoefficient, ref damageElement, ref damageFlags, ref damageKnockback, ref damageIsCrit, ref attackerId); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref EnemyDamaged? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint enemyId = default(uint); float damage = default(float); int damageEffect = default(int); int damageBlockedByArmor = default(int); float damageProcCoefficient = default(float); int damageElement = default(int); int damageFlags = default(int); float damageKnockback = default(float); bool damageIsCrit = default(bool); uint attackerId = default(uint); string damageSource; if (b == 11) { if (value != null) { enemyId = value.EnemyId; damage = value.Damage; damageEffect = value.DamageEffect; damageBlockedByArmor = value.DamageBlockedByArmor; damageSource = value.DamageSource; damageProcCoefficient = value.DamageProcCoefficient; damageElement = value.DamageElement; damageFlags = value.DamageFlags; damageKnockback = value.DamageKnockback; damageIsCrit = value.DamageIsCrit; attackerId = value.AttackerId; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref enemyId); ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref damage); ((MemoryPackReader)(ref reader)).ReadUnmanaged<int>(ref damageEffect); ((MemoryPackReader)(ref reader)).ReadUnmanaged<int>(ref damageBlockedByArmor); damageSource = ((MemoryPackReader)(ref reader)).ReadString(); ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref damageProcCoefficient); ((MemoryPackReader)(ref reader)).ReadUnmanaged<int>(ref damageElement); ((MemoryPackReader)(ref reader)).ReadUnmanaged<int>(ref damageFlags); ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref damageKnockback); ((MemoryPackReader)(ref reader)).ReadUnmanaged<bool>(ref damageIsCrit); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref attackerId); goto IL_023d; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, float, int, int>(ref enemyId, ref damage, ref damageEffect, ref damageBlockedByArmor); damageSource = ((MemoryPackReader)(ref reader)).ReadString(); ((MemoryPackReader)(ref reader)).ReadUnmanaged<float, int, int, float, bool, uint>(ref damageProcCoefficient, ref damageElement, ref damageFlags, ref damageKnockback, ref damageIsCrit, ref attackerId); } else { if (b > 11) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(EnemyDamaged), (byte)11, b); return; } if (value == null) { enemyId = 0u; damage = 0f; damageEffect = 0; damageBlockedByArmor = 0; damageSource = null; damageProcCoefficient = 0f; damageElement = 0; damageFlags = 0; damageKnockback = 0f; damageIsCrit = false; attackerId = 0u; } else { enemyId = value.EnemyId; damage = value.Damage; damageEffect = value.DamageEffect; damageBlockedByArmor = value.DamageBlockedByArmor; damageSource = value.DamageSource; damageProcCoefficient = value.DamageProcCoefficient; damageElement = value.DamageElement; damageFlags = value.DamageFlags; damageKnockback = value.DamageKnockback; damageIsCrit = value.DamageIsCrit; attackerId = value.AttackerId; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref enemyId); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref damage); if (b != 2) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<int>(ref damageEffect); if (b != 3) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<int>(ref damageBlockedByArmor); if (b != 4) { damageSource = ((MemoryPackReader)(ref reader)).ReadString(); if (b != 5) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref damageProcCoefficient); if (b != 6) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<int>(ref damageElement); if (b != 7) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<int>(ref damageFlags); if (b != 8) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref damageKnockback); if (b != 9) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<bool>(ref damageIsCrit); if (b != 10) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref attackerId); _ = 11; } } } } } } } } } } } if (value != null) { goto IL_023d; } } value = new EnemyDamaged { EnemyId = enemyId, Damage = damage, DamageEffect = damageEffect, DamageBlockedByArmor = damageBlockedByArmor, DamageSource = damageSource, DamageProcCoefficient = damageProcCoefficient, DamageElement = damageElement, DamageFlags = damageFlags, DamageKnockback = damageKnockback, DamageIsCrit = damageIsCrit, AttackerId = attackerId }; return; IL_023d: value.EnemyId = enemyId; value.Damage = damage; value.DamageEffect = damageEffect; value.DamageBlockedByArmor = damageBlockedByArmor; value.DamageSource = damageSource; value.DamageProcCoefficient = damageProcCoefficient; value.DamageElement = damageElement; value.DamageFlags = damageFlags; value.DamageKnockback = damageKnockback; value.DamageIsCrit = damageIsCrit; value.AttackerId = attackerId; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class EnemyDied : IGameNetworkMessage, IMemoryPackFormatterRegister, IMemoryPackable<EnemyDied> { [Preserve] private sealed class EnemyDiedFormatter : MemoryPackFormatter<EnemyDied> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref EnemyDied value) { EnemyDied.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref EnemyDied value) { EnemyDied.Deserialize(ref reader, ref value); } } public uint EnemyId { get; set; } public uint DiedByOwnerId { get; set; } public float DamageProcCoefficient { get; set; } public string DamageSource { get; set; } static EnemyDied() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<EnemyDied>()) { MemoryPackFormatterProvider.Register<EnemyDied>((MemoryPackFormatter<EnemyDied>)(object)new EnemyDiedFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<EnemyDied[]>()) { MemoryPackFormatterProvider.Register<EnemyDied[]>((MemoryPackFormatter<EnemyDied[]>)(object)new ArrayFormatter<EnemyDied>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref EnemyDied? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint enemyId = value.EnemyId; uint diedByOwnerId = value.DiedByOwnerId; float damageProcCoefficient = value.DamageProcCoefficient; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, uint, float>((byte)4, ref enemyId, ref diedByOwnerId, ref damageProcCoefficient); writer.WriteString(value.DamageSource); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref EnemyDied? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint enemyId = default(uint); uint diedByOwnerId = default(uint); float damageProcCoefficient = default(float); string damageSource; if (b == 4) { if (value != null) { enemyId = value.EnemyId; diedByOwnerId = value.DiedByOwnerId; damageProcCoefficient = value.DamageProcCoefficient; damageSource = value.DamageSource; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref enemyId); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref diedByOwnerId); ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref damageProcCoefficient); damageSource = ((MemoryPackReader)(ref reader)).ReadString(); goto IL_00f6; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, uint, float>(ref enemyId, ref diedByOwnerId, ref damageProcCoefficient); damageSource = ((MemoryPackReader)(ref reader)).ReadString(); } else { if (b > 4) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(EnemyDied), (byte)4, b); return; } if (value == null) { enemyId = 0u; diedByOwnerId = 0u; damageProcCoefficient = 0f; damageSource = null; } else { enemyId = value.EnemyId; diedByOwnerId = value.DiedByOwnerId; damageProcCoefficient = value.DamageProcCoefficient; damageSource = value.DamageSource; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref enemyId); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref diedByOwnerId); if (b != 2) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<float>(ref damageProcCoefficient); if (b != 3) { damageSource = ((MemoryPackReader)(ref reader)).ReadString(); _ = 4; } } } } if (value != null) { goto IL_00f6; } } value = new EnemyDied { EnemyId = enemyId, DiedByOwnerId = diedByOwnerId, DamageProcCoefficient = damageProcCoefficient, DamageSource = damageSource }; return; IL_00f6: value.EnemyId = enemyId; value.DiedByOwnerId = diedByOwnerId; value.DamageProcCoefficient = damageProcCoefficient; value.DamageSource = damageSource; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class EnemyExploder : IGameNetworkMessage, IMemoryPackFormatterRegister, IMemoryPackable<EnemyExploder> { [Preserve] private sealed class EnemyExploderFormatter : MemoryPackFormatter<EnemyExploder> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref EnemyExploder value) { EnemyExploder.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref EnemyExploder value) { EnemyExploder.Deserialize(ref reader, ref value); } } public uint EnemyId { get; set; } public uint SenderId { get; set; } static EnemyExploder() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<EnemyExploder>()) { MemoryPackFormatterProvider.Register<EnemyExploder>((MemoryPackFormatter<EnemyExploder>)(object)new EnemyExploderFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<EnemyExploder[]>()) { MemoryPackFormatterProvider.Register<EnemyExploder[]>((MemoryPackFormatter<EnemyExploder[]>)(object)new ArrayFormatter<EnemyExploder>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref EnemyExploder? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint enemyId = value.EnemyId; uint senderId = value.SenderId; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, uint>((byte)2, ref enemyId, ref senderId); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref EnemyExploder? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint enemyId = default(uint); uint senderId = default(uint); if (b == 2) { if (value != null) { enemyId = value.EnemyId; senderId = value.SenderId; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref enemyId); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref senderId); goto IL_0096; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, uint>(ref enemyId, ref senderId); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(EnemyExploder), (byte)2, b); return; } if (value == null) { enemyId = 0u; senderId = 0u; } else { enemyId = value.EnemyId; senderId = value.SenderId; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref enemyId); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref senderId); _ = 2; } } if (value != null) { goto IL_0096; } } value = new EnemyExploder { EnemyId = enemyId, SenderId = senderId }; return; IL_0096: value.EnemyId = enemyId; value.SenderId = senderId; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class FinalBossOrbDestroyed : IGameNetworkMessage, IMemoryPackFormatterRegister, IMemoryPackable<FinalBossOrbDestroyed> { [Preserve] private sealed class FinalBossOrbDestroyedFormatter : MemoryPackFormatter<FinalBossOrbDestroyed> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref FinalBossOrbDestroyed value) { FinalBossOrbDestroyed.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref FinalBossOrbDestroyed value) { FinalBossOrbDestroyed.Deserialize(ref reader, ref value); } } public uint OrbId { get; set; } public uint SenderId { get; set; } static FinalBossOrbDestroyed() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<FinalBossOrbDestroyed>()) { MemoryPackFormatterProvider.Register<FinalBossOrbDestroyed>((MemoryPackFormatter<FinalBossOrbDestroyed>)(object)new FinalBossOrbDestroyedFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<FinalBossOrbDestroyed[]>()) { MemoryPackFormatterProvider.Register<FinalBossOrbDestroyed[]>((MemoryPackFormatter<FinalBossOrbDestroyed[]>)(object)new ArrayFormatter<FinalBossOrbDestroyed>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref FinalBossOrbDestroyed? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } uint orbId = value.OrbId; uint senderId = value.SenderId; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<uint>>(ref writer).WriteUnmanagedWithObjectHeader<uint, uint>((byte)2, ref orbId, ref senderId); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref FinalBossOrbDestroyed? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } uint orbId = default(uint); uint senderId = default(uint); if (b == 2) { if (value != null) { orbId = value.OrbId; senderId = value.SenderId; ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref orbId); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref senderId); goto IL_0096; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint, uint>(ref orbId, ref senderId); } else { if (b > 2) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(FinalBossOrbDestroyed), (byte)2, b); return; } if (value == null) { orbId = 0u; senderId = 0u; } else { orbId = value.OrbId; senderId = value.SenderId; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref orbId); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref senderId); _ = 2; } } if (value != null) { goto IL_0096; } } value = new FinalBossOrbDestroyed { OrbId = orbId, SenderId = senderId }; return; IL_0096: value.OrbId = orbId; value.SenderId = senderId; } } [MemoryPackable(/*Could not decode attribute arguments.*/)] public class FinalBossOrbSpawned : IGameNetworkMessage, IMemoryPackFormatterRegister, IMemoryPackable<FinalBossOrbSpawned> { [Preserve] private sealed class FinalBossOrbSpawnedFormatter : MemoryPackFormatter<FinalBossOrbSpawned> { [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref FinalBossOrbSpawned value) { FinalBossOrbSpawned.Serialize(ref writer, ref value); } [Preserve] public override void Deserialize(ref MemoryPackReader reader, ref FinalBossOrbSpawned value) { FinalBossOrbSpawned.Deserialize(ref reader, ref value); } } public Orb OrbType { get; set; } public uint Target { get; set; } public uint OrbId { get; set; } static FinalBossOrbSpawned() { RegisterFormatter(); } [Preserve] public static void RegisterFormatter() { if (!MemoryPackFormatterProvider.IsRegistered<FinalBossOrbSpawned>()) { MemoryPackFormatterProvider.Register<FinalBossOrbSpawned>((MemoryPackFormatter<FinalBossOrbSpawned>)(object)new FinalBossOrbSpawnedFormatter()); } if (!MemoryPackFormatterProvider.IsRegistered<FinalBossOrbSpawned[]>()) { MemoryPackFormatterProvider.Register<FinalBossOrbSpawned[]>((MemoryPackFormatter<FinalBossOrbSpawned[]>)(object)new ArrayFormatter<FinalBossOrbSpawned>()); } if (!MemoryPackFormatterProvider.IsRegistered<Orb>()) { MemoryPackFormatterProvider.Register<Orb>((MemoryPackFormatter<Orb>)(object)new UnmanagedFormatter<Orb>()); } } [Preserve] public static void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref FinalBossOrbSpawned? value) where TBufferWriter : class, IBufferWriter<byte> { if (value == null) { writer.WriteNullObjectHeader(); return; } Orb orbType = value.OrbType; uint target = value.Target; uint orbId = value.OrbId; Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<Orb>>(ref writer).WriteUnmanagedWithObjectHeader<Orb, uint, uint>((byte)3, ref orbType, ref target, ref orbId); } [Preserve] public static void Deserialize(ref MemoryPackReader reader, ref FinalBossOrbSpawned? value) { byte b = default(byte); if (!((MemoryPackReader)(ref reader)).TryReadObjectHeader(ref b)) { value = null; return; } Orb orbType = default(Orb); uint target = default(uint); uint orbId = default(uint); if (b == 3) { if (value != null) { orbType = value.OrbType; target = value.Target; orbId = value.OrbId; ((MemoryPackReader)(ref reader)).ReadUnmanaged<Orb>(ref orbType); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref target); ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref orbId); goto IL_00be; } ((MemoryPackReader)(ref reader)).ReadUnmanaged<Orb, uint, uint>(ref orbType, ref target, ref orbId); } else { if (b > 3) { MemoryPackSerializationException.ThrowInvalidPropertyCount(typeof(FinalBossOrbSpawned), (byte)3, b); return; } if (value == null) { orbType = Orb.Bleed; target = 0u; orbId = 0u; } else { orbType = value.OrbType; target = value.Target; orbId = value.OrbId; } if (b != 0) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<Orb>(ref orbType); if (b != 1) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref target); if (b != 2) { ((MemoryPackReader)(ref reader)).ReadUnmanaged<uint>(ref orbId); _ = 3; } } } if (value != null) { goto IL_00be; } } value = new FinalBossOrbSpawned { OrbType = orbType, Target = target, OrbId = orbId }; return; IL_00be: value.OrbType = orbType; value.Target = target; value.OrbId = orbId; } } public enum Orb { Bleed, Following, Shooty } [MemoryPackable(/*Could not decode attribute arguments.*/)] [MemoryPackUnion(0, typeof(LobbyUpdates))] [MemoryPackUnion(1, typeof(ClientInGameReady))] [MemoryPackUnion(2, typeof(SpawnedObject))] [MemoryPackUnion(3, typeof(PlayerUpdate))] [MemoryPackUnion(4, typeof(SpawnedEnemy))] [MemoryPackUnion(5, typeof(SelectedCharacter))] [MemoryPackUnion(6, typeof(EnemyDied))] [MemoryPackUnion(7, typeof(SpawnedProjectile))] [MemoryPackUnion(8, typeof(ProjectileDone))] [MemoryPackUnion(9, typeof(SpawnedPickupOrb))] [MemoryPackUnion(10, typeof(SpawnedPickup))] [MemoryPackUnion(11, typeof(PickupApplied))] [MemoryPackUnion(12, typeof(PickupFollowingPlayer))] [MemoryPackUnion(13, typeof(SpawnedChest))] [MemoryPackUnion(14, typeof(ChestOpened))] [MemoryPackUnion(15, typeof(WeaponAdded))] [MemoryPackUnion(16, typeof(InteractableUsed))] [MemoryPackUnion(17, typeof(StartingChargingShrine))] [MemoryPackUnion(18, typeof(StoppingChargingShrine))] [MemoryPackUnion(19, typeof(EnemyExploder))] [MemoryPackUnion(20, typeof(EnemyDamaged))] [MemoryPackUnion(21, typeof(SpawnedEnemySpecialAttack))] [MemoryPackUnion(22, typeof(StartingChargingPylon))] [MemoryPackUnion(23, typeof(StoppingChargingPylon))] [MemoryPackUnion(24, typeof(FinalBossOrbSpawned))] [MemoryPackUnion(25, typeof(FinalBossOrbDestroyed))] [MemoryPackUnion(26, typeof(StartedSwarmEvent))] [MemoryPackUnion(27, typeof(GameOver))] [MemoryPackUnion(28, typeof(PlayerDied))] [MemoryPackUnion(29, typeof(RetargetedEnemies))] [MemoryPackUnion(30, typeof(Introduced))] [MemoryPackUnion(31, typeof(PlayerDisconnected))] [MemoryPackUnion(32, typeof(RunStarted))] [MemoryPackUnion(33, typeof(SpawnedAxeProjectile))] [MemoryPackUnion(34, typeof(SpawnedBlackHoleProjectile))] [MemoryPackUnion(35, typeof(SpawnedCringeSwordProjectile))] [MemoryPackUnion(36, typeof(SpawnedFireFieldProjectile))] [MemoryPackUnion(37, typeof(SpawnedHeroSwordProjectile))] [MemoryPackUnion(38, typeof(SpawnedRocketProjectile))] [MemoryPackUnion(39, typeof(ProjectilesUpdate))] [MemoryPackUnion(40, typeof(TomeAdded))] [MemoryPackUnion(41, typeof(LightningStrike))] [MemoryPackUnion(42, typeof(TornadoesSpawned))] [MemoryPackUnion(43, typeof(StormStarted))] [MemoryPackUnion(44, typeof(StormStopped))] [MemoryPackUnion(45, typeof(TumbleWeedSpawned))] [MemoryPackUnion(46, typeof(TumbleWeedsUpdate))] [MemoryPackUnion(47, typeof(TumbleWeedDespawned))] [MemoryPackUnion(48, typeof(InteractableCharacterFightEnemySpawned))] [MemoryPackUnion(49, typeof(WantToStartFollowingPickup))] [MemoryPackUnion(50, typeof(SpawnedShotgunProjectile))] [MemoryPackUnion(51, typeof(SpawnedDexecutionerProjectile))] [MemoryPackUnion(52, typeof(ItemAdded))] [MemoryPackUnion(53, typeof(ItemRemoved))] [MemoryPackUnion(54, typeof(WeaponToggled))] [MemoryPackUnion(55, typeof(SpawnedObjectInCrypt))] [MemoryPackUnion(56, typeof(StartingChargingLamp))] [MemoryPackUnion(57, typeof(StoppingChargingLamp))] [MemoryPackUnion(58, typeof(TimerStarted))] [MemoryPackUnion(59, typeof(HatChanged))] [MemoryPackUnion(60, typeof(SpawnedRevolverProjectile))] [MemoryPackUnion(61, typeof(SpawnedSniperProjectile))] [MemoryPackUnion(62, typeof(SpawnedReviver))] [MemoryPackUnion(63, typeof(PlayerRespawned))] [MemoryPackUnion(64, typeof(AddXp))] [MemoryPackUnion(65, typeof(EncounterClosed))] [MemoryPackUnion(66, typeof(CloseEncounter))] [MemoryPackUnion(67, typeof(GoldChanged))] [MemoryPackUnion(68, typeof(PlayersStateUpdate))] [MemoryPackUnion(69, typeof(EncounterClosedStamped))] [MemoryPackUnion(70, typeof(CloseEncounterStamped))] [MemoryPackUnion(71, typeof(ReadinessRoundStarted))] [MemoryPackUnion(72, typeof(ClientReadyStamped))] [MemoryPackUnion(73, typeof(LobbyReadyChanged))] [MemoryPackUnion(74, typeof(LobbyReadyState))] [MemoryPackUnion(75, typeof(LobbyStartRequested))] [MemoryPackUnion(76, typeof(EnemyMaxHpScaled))] [MemoryPackUnion(77, typeof(PlayerStatsChanged))] [MemoryPackUnion(78, typeof(StateDigest))] [MemoryPackUnion(79, typeof(ChargeShrineCompleted))] [MemoryPackUnion(80, typeof(LobbySettings))] [MemoryPackUnion(81, typeof(EndlessNextRoom))] [MemoryPackUnion(82, typeof(LobbyRoster))] [MemoryPackUnion(83, typeof(ProtocolHello))] [MemoryPackUnion(84, typeof(EnemyDamagedBatch))] [MemoryPackUnion(85, typeof(ItemProjectilesSpawned))] [MemoryPackUnion(86, typeof(MineExploded))] [MemoryPackUnion(87, typeof(FlaskExploded))] [MemoryPackUnion(88, typeof(EnemyHitEffects))] [MemoryPackUnion(89, typeof(ItemVisualEffects))] [MemoryPackUnion(90, typeof(ShrineChargersChanged))] public interface IGameNetworkMessage : IMemoryPackFormatterRegister { [Preserve] public sealed class IGameNetworkMessageFormatter : MemoryPackFormatter<IGameNetworkMessage> { private static readonly Dictionary<Type, ushort> __typeToTag = new Dictionary<Type, ushort>(91) { { typeof(LobbyUpdates), 0 }, { typeof(ClientInGameReady), 1 }, { typeof(SpawnedObject), 2 }, { typeof(PlayerUpdate), 3 }, { typeof(SpawnedEnemy), 4 }, { typeof(SelectedCharacter), 5 }, { typeof(EnemyDied), 6 }, { typeof(SpawnedProjectile), 7 }, { typeof(ProjectileDone), 8 }, { typeof(SpawnedPickupOrb), 9 }, { typeof(SpawnedPickup), 10 }, { typeof(PickupApplied), 11 }, { typeof(PickupFollowingPlayer), 12 }, { typeof(SpawnedChest), 13 }, { typeof(ChestOpened), 14 }, { typeof(WeaponAdded), 15 }, { typeof(InteractableUsed), 16 }, { typeof(StartingChargingShrine), 17 }, { typeof(StoppingChargingShrine), 18 }, { typeof(EnemyExploder), 19 }, { typeof(EnemyDamaged), 20 }, { typeof(SpawnedEnemySpecialAttack), 21 }, { typeof(StartingChargingPylon), 22 }, { typeof(StoppingChargingPylon), 23 }, { typeof(FinalBossOrbSpawned), 24 }, { typeof(FinalBossOrbDestroyed), 25 }, { typeof(StartedSwarmEvent), 26 }, { typeof(GameOver), 27 }, { typeof(PlayerDied), 28 }, { typeof(RetargetedEnemies), 29 }, { typeof(Introduced), 30 }, { typeof(PlayerDisconnected), 31 }, { typeof(RunStarted), 32 }, { typeof(SpawnedAxeProjectile), 33 }, { typeof(SpawnedBlackHoleProjectile), 34 }, { typeof(SpawnedCringeSwordProjectile), 35 }, { typeof(SpawnedFireFieldProjectile), 36 }, { typeof(SpawnedHeroSwordProjectile), 37 }, { typeof(SpawnedRocketProjectile), 38 }, { typeof(ProjectilesUpdate), 39 }, { typeof(TomeAdded), 40 }, { typeof(LightningStrike), 41 }, { typeof(TornadoesSpawned), 42 }, { typeof(StormStarted), 43 }, { typeof(StormStopped), 44 }, { typeof(TumbleWeedSpawned), 45 }, { typeof(TumbleWeedsUpdate), 46 }, { typeof(TumbleWeedDespawned), 47 }, { typeof(InteractableCharacterFightEnemySpawned), 48 }, { typeof(WantToStartFollowingPickup), 49 }, { typeof(SpawnedShotgunProjectile), 50 }, { typeof(SpawnedDexecutionerProjectile), 51 }, { typeof(ItemAdded), 52 }, { typeof(ItemRemoved), 53 }, { typeof(WeaponToggled), 54 }, { typeof(SpawnedObjectInCrypt), 55 }, { typeof(StartingChargingLamp), 56 }, { typeof(StoppingChargingLamp), 57 }, { typeof(TimerStarted), 58 }, { typeof(HatChanged), 59 }, { typeof(SpawnedRevolverProjectile), 60 }, { typeof(SpawnedSniperProjectile), 61 }, { typeof(SpawnedReviver), 62 }, { typeof(PlayerRespawned), 63 }, { typeof(AddXp), 64 }, { typeof(EncounterClosed), 65 }, { typeof(CloseEncounter), 66 }, { typeof(GoldChanged), 67 }, { typeof(PlayersStateUpdate), 68 }, { typeof(EncounterClosedStamped), 69 }, { typeof(CloseEncounterStamped), 70 }, { typeof(ReadinessRoundStarted), 71 }, { typeof(ClientReadyStamped), 72 }, { typeof(LobbyReadyChanged), 73 }, { typeof(LobbyReadyState), 74 }, { typeof(LobbyStartRequested), 75 }, { typeof(EnemyMaxHpScaled), 76 }, { typeof(PlayerStatsChanged), 77 }, { typeof(StateDigest), 78 }, { typeof(ChargeShrineCompleted), 79 }, { typeof(LobbySettings), 80 }, { typeof(EndlessNextRoom), 81 }, { typeof(LobbyRoster), 82 }, { typeof(ProtocolHello), 83 }, { typeof(EnemyDamagedBatch), 84 }, { typeof(ItemProjectilesSpawned), 85 }, { typeof(MineExploded), 86 }, { typeof(FlaskExploded), 87 }, { typeof(EnemyHitEffects), 88 }, { typeof(ItemVisualEffects), 89 }, { typeof(ShrineChargersChanged), 90 } }; [Preserve] public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, ref IGameNetworkMessage? value) { ushort value2; if (value == null) { writer.WriteNullUnionHeader(); } else if (__typeToTag.TryGetValue(value.GetType(), out value2)) { writer.WriteUnionHeader(value2); switch (value2) { case 0: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<LobbyUpdates>>(ref writer).WritePackable<LobbyUpdates>(ref Unsafe.As<IGameNetworkMessage, LobbyUpdates>(ref value)); break; case 1: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<ClientInGameReady>>(ref writer).WritePackable<ClientInGameReady>(ref Unsafe.As<IGameNetworkMessage, ClientInGameReady>(ref value)); break; case 2: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<SpawnedObject>>(ref writer).WritePackable<SpawnedObject>(ref Unsafe.As<IGameNetworkMessage, SpawnedObject>(ref value)); break; case 3: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<PlayerUpdate>>(ref writer).WritePackable<PlayerUpdate>(ref Unsafe.As<IGameNetworkMessage, PlayerUpdate>(ref value)); break; case 4: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<SpawnedEnemy>>(ref writer).WritePackable<SpawnedEnemy>(ref Unsafe.As<IGameNetworkMessage, SpawnedEnemy>(ref value)); break; case 5: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<SelectedCharacter>>(ref writer).WritePackable<SelectedCharacter>(ref Unsafe.As<IGameNetworkMessage, SelectedCharacter>(ref value)); break; case 6: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<EnemyDied>>(ref writer).WritePackable<EnemyDied>(ref Unsafe.As<IGameNetworkMessage, EnemyDied>(ref value)); break; case 7: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<SpawnedProjectile>>(ref writer).WritePackable<SpawnedProjectile>(ref Unsafe.As<IGameNetworkMessage, SpawnedProjectile>(ref value)); break; case 8: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<ProjectileDone>>(ref writer).WritePackable<ProjectileDone>(ref Unsafe.As<IGameNetworkMessage, ProjectileDone>(ref value)); break; case 9: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<SpawnedPickupOrb>>(ref writer).WritePackable<SpawnedPickupOrb>(ref Unsafe.As<IGameNetworkMessage, SpawnedPickupOrb>(ref value)); break; case 10: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<SpawnedPickup>>(ref writer).WritePackable<SpawnedPickup>(ref Unsafe.As<IGameNetworkMessage, SpawnedPickup>(ref value)); break; case 11: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<PickupApplied>>(ref writer).WritePackable<PickupApplied>(ref Unsafe.As<IGameNetworkMessage, PickupApplied>(ref value)); break; case 12: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<PickupFollowingPlayer>>(ref writer).WritePackable<PickupFollowingPlayer>(ref Unsafe.As<IGameNetworkMessage, PickupFollowingPlayer>(ref value)); break; case 13: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<SpawnedChest>>(ref writer).WritePackable<SpawnedChest>(ref Unsafe.As<IGameNetworkMessage, SpawnedChest>(ref value)); break; case 14: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<ChestOpened>>(ref writer).WritePackable<ChestOpened>(ref Unsafe.As<IGameNetworkMessage, ChestOpened>(ref value)); break; case 15: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<WeaponAdded>>(ref writer).WritePackable<WeaponAdded>(ref Unsafe.As<IGameNetworkMessage, WeaponAdded>(ref value)); break; case 16: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<InteractableUsed>>(ref writer).WritePackable<InteractableUsed>(ref Unsafe.As<IGameNetworkMessage, InteractableUsed>(ref value)); break; case 17: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<StartingChargingShrine>>(ref writer).WritePackable<StartingChargingShrine>(ref Unsafe.As<IGameNetworkMessage, StartingChargingShrine>(ref value)); break; case 18: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<StoppingChargingShrine>>(ref writer).WritePackable<StoppingChargingShrine>(ref Unsafe.As<IGameNetworkMessage, StoppingChargingShrine>(ref value)); break; case 19: Unsafe.As<MemoryPackWriter<TBufferWriter>, MemoryPackWriter<EnemyExploder>>(ref writer).WritePackable<EnemyExploder>(ref U
OmniBonk.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.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Sockets; using System.Net.WebSockets; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Actors.Enemies; using Assets.Scripts.Actors; using Assets.Scripts.Actors.Enemies; using Assets.Scripts.Actors.Player; using Assets.Scripts.Camera; using Assets.Scripts.Game.Combat; using Assets.Scripts.Game.Combat.ConstantAttacks; using Assets.Scripts.Game.Combat.EnemyDebuffs; using Assets.Scripts.Game.Combat.EnemyDebuffs.Implementations; using Assets.Scripts.Game.Combat.EnemySpecialAttacks; using Assets.Scripts.Game.Combat.EnemySpecialAttacks.Implementations; using Assets.Scripts.Game.MapGeneration; using Assets.Scripts.Game.MapGeneration.MapEvents; using Assets.Scripts.Game.Other; using Assets.Scripts.Game.Spawning; using Assets.Scripts.Game.Spawning.New; using Assets.Scripts.Game.Spawning.New.Summoners; using Assets.Scripts.Game.Spawning.New.Timelines; using Assets.Scripts.Inventory.Stats; using Assets.Scripts.Inventory__Items__Pickups; using Assets.Scripts.Inventory__Items__Pickups.AbilitiesPassive; using Assets.Scripts.Inventory__Items__Pickups.AbilitiesPassive.Implementations; using Assets.Scripts.Inventory__Items__Pickups.Chests; using Assets.Scripts.Inventory__Items__Pickups.GoldAndMoney; using Assets.Scripts.Inventory__Items__Pickups.Interactables; using Assets.Scripts.Inventory__Items__Pickups.Items; using Assets.Scripts.Inventory__Items__Pickups.Items.ItemImplementations; using Assets.Scripts.Inventory__Items__Pickups.Items.ItemProjectiles; using Assets.Scripts.Inventory__Items__Pickups.Pickups; using Assets.Scripts.Inventory__Items__Pickups.Stats; using Assets.Scripts.Inventory__Items__Pickups.Weapons; using Assets.Scripts.Inventory__Items__Pickups.Weapons.Attacks; using Assets.Scripts.Inventory__Items__Pickups.Weapons.Projectiles; using Assets.Scripts.Inventory__Items__Pickups.Weapons.WeaponPassives; using Assets.Scripts.Managers; using Assets.Scripts.MapGeneration.ProceduralTiles; using Assets.Scripts.Menu.Shop; using Assets.Scripts.Objects.Particles___Effects.ParticleOpacity; using Assets.Scripts.Objects.Pooling; using Assets.Scripts.Saves___Serialization.Progression.Achievements; using Assets.Scripts.Saves___Serialization.Progression.Stats; using Assets.Scripts.Settings___Saves.SaveFiles; using Assets.Scripts.Settings___Saves.SaveFiles.ConfigSaves; using Assets.Scripts.Steam; using Assets.Scripts.UI.HUD; using Assets.Scripts.UI.InGame.Levelup; using Assets.Scripts.UI.InGame.Rewards; using Assets.Scripts.UI.Localization; using Assets.Scripts.Utility; using Assets.Scripts._Data.Hats; using Assets.Scripts._Data.MapsAndStages; using Assets.Scripts._Data.Tomes; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.UnityEngine; using BepInEx.Unity.IL2CPP.Utils; using Coffee.UIExtensions; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.IO; using Inventory__Items__Pickups.Xp_and_Levels; using LiteNetLib; using LiteNetLib.Layers; using LiteNetLib.Utils; using MemoryPack; using Microsoft.CodeAnalysis; using Microsoft.Extensions.DependencyInjection; using MonoMod.Utils; using OmniBonk.Common; using OmniBonk.Common.Messages; using OmniBonk.Common.Messages.GameNetworkMessages; using OmniBonk.Common.Messages.WsMessages; using OmniBonk.Common.Models; using OmniBonk.Configuration; using OmniBonk.Extensions; using OmniBonk.Helpers; using OmniBonk.Patches; using OmniBonk.Patches.Enemies; using OmniBonk.Patches.Items; using OmniBonk.Patches.Projectiles; using OmniBonk.Patches.Unity; using OmniBonk.Scripts; using OmniBonk.Scripts.Button; using OmniBonk.Scripts.Enemies; using OmniBonk.Scripts.Interactables; using OmniBonk.Scripts.Modal; using OmniBonk.Scripts.NetPlayer; using OmniBonk.Scripts.Snapshot; using OmniBonk.Services; using Steamworks; using TMPro; using Tomlyn; using Tomlyn.Model; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Localization; using UnityEngine.Localization.Components; using UnityEngine.Localization.Tables; using UnityEngine.Pool; using UnityEngine.UI; using Utility; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("OmniBonk")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+f19f416d7cb174ea0ff085fa86fde3f3c8fc056d")] [assembly: AssemblyProduct("OmniBonk")] [assembly: AssemblyTitle("OmniBonk")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object? IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Length; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Length; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object? value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object? value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object? value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object? value) { throw new NotSupportedException(); } void IList.Remove(object? value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return ((ICollection<T>)_items).Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { ((ICollection<T>)_items).CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return ((IList<T>)_items).IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlyList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Count; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object? IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Count; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Count; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyList(List<T> items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object? value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object? value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object? value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object? value) { throw new NotSupportedException(); } void IList.Remove(object? value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return _items.Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { _items.CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return _items.IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T> { object IEnumerator.Current => _item; T IEnumerator<T>.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object? IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => 1; T IReadOnlyList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection<T>.Count => 1; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object? value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object? value) { return EqualityComparer<T>.Default.Equals(_item, (T)value); } int IList.IndexOf(object? value) { if (!EqualityComparer<T>.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object? value) { throw new NotSupportedException(); } void IList.Remove(object? value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(_item); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return EqualityComparer<T>.Default.Equals(_item, item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { if (!EqualityComparer<T>.Default.Equals(_item, item)) { return -1; } return 0; } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace OmniBonk { public enum DistanceToPlayer { Close, Medium, Far } [BepInPlugin("OmniBonk", "OmniBonk", "1.0.0")] [BepInIncompatibility("MegabonkTogether")] public class Plugin : BasePlugin { public readonly struct OutboundSuppression : IDisposable { private readonly bool previous; internal OutboundSuppression(bool previous) { this.previous = previous; } public void Dispose() { CAN_SEND_MESSAGES = previous; } } public static Plugin Instance = null; public NetworkHandler NetworkHandler; public Dictionary<ECharacter, RawImage> CharactersIcon = new Dictionary<ECharacter, RawImage>(); public NetPlayersDisplayer NetPlayersDisplayer; public CameraSwitcher CameraSwitcher; public PlayTogetherButton PlayTogetherButton; public AchievementPopup AchievementPopup; public NotificationQueueManager NotificationQueueManager; private MainMenu MainMenu; private MapEventsManager mapEventsManager; private MapEventsDesert mapEventsDesert; private LoadingModal modal; public NetworkMode Mode = new NetworkMode(); internal static ManualLogSource Log; public static float PLAYER_FEET_OFFSET_Y = 1.5f; public static bool CAN_SPAWN_PICKUPS = false; public static bool CAN_SPAWN_CHESTS = false; public static bool CAN_SEND_MESSAGES = true; public static bool CAN_ENEMY_EXPLODE = false; public static bool CAN_ENEMY_USE_SPECIAL_ATTACK = false; public bool CAN_SPAWN_TORNADOES; public bool CAN_START_STOP_STORMS; public bool CAN_DAMAGE_ENEMIES; public bool IS_HOST_READY; public bool IS_MANUAL_INVINCIBLE; public bool IS_NETPLAYER_ADDING_TOME; public uint? CurrentReviver; public uint? CurrentReviverOwner; private Vector3 WorldSize = Vector3.zero; public Vector3 OriginalWorldSize = Vector3.zero; public bool HasDungeonTimerStarted; private readonly ConcurrentDictionary<string, GameObject> prefabs = new ConcurrentDictionary<string, GameObject>(); private Action originalDiedAction; private Action<WeaponBase> originalWeaponAddedAction; private Action<EStat> originalStatUpdateAction; private bool hasPreventedDeath; private bool hasSavedInventoryActions; private static int distanceTargetFrame = -1; private static Vector3 distanceTarget; public static IServiceProvider Services { get; private set; } = null; public static OutboundSuppression SuppressOutbound() { OutboundSuppression result = new OutboundSuppression(CAN_SEND_MESSAGES); CAN_SEND_MESSAGES = false; return result; } public override void Load() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Expected O, but got Unknown //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Expected O, but got Unknown //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Expected O, but got Unknown //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Expected O, but got Unknown //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Expected O, but got Unknown //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Expected O, but got Unknown //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Expected O, but got Unknown //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Expected O, but got Unknown //IL_034e: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BasePlugin)this).Log; ManualLogSource log = Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("OmniBonk"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!"); } log.LogInfo(val); ModConfig.Initialize(((BasePlugin)this).Config); UnityDiagnostics.EnableStackTraces(); ManualLogSource log2 = Log; val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Player name set to: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ModConfig.PlayerName.Value); } log2.LogInfo(val); try { UnityExceptionDiagnostics.Hook(); } catch (Exception ex) { ManualLogSource log3 = Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(61, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[unity-exc] Diagnostic unavailable, continuing without it: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log3.LogWarning(val2); } try { LogCaptureDiagnostics.Report(); } catch (Exception ex2) { ManualLogSource log4 = Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(63, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[log-capture] Diagnostic unavailable, continuing without it: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex2.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex2.Message); } log4.LogWarning(val2); } ClassInjector.RegisterTypeInIl2Cpp<NetPlayer>(); ClassInjector.RegisterTypeInIl2Cpp<CoroutineRunner>(); ClassInjector.RegisterTypeInIl2Cpp<MainThreadDispatcher>(); ClassInjector.RegisterTypeInIl2Cpp<NetworkHandler>(); ClassInjector.RegisterTypeInIl2Cpp<PlayerInterpolator>(); ClassInjector.RegisterTypeInIl2Cpp<EnemyInterpolator>(); ClassInjector.RegisterTypeInIl2Cpp<BossOrbInterpolator>(); ClassInjector.RegisterTypeInIl2Cpp<ProjectileInterpolator>(); ClassInjector.RegisterTypeInIl2Cpp<TumbleWeedInterpolator>(); ClassInjector.RegisterTypeInIl2Cpp<NetPlayersDisplayer>(); ClassInjector.RegisterTypeInIl2Cpp<NetPlayerCard>(); ClassInjector.RegisterTypeInIl2Cpp<DisplayBar>(); ClassInjector.RegisterTypeInIl2Cpp<CustomInventoryHud>(); ClassInjector.RegisterTypeInIl2Cpp<CameraSwitcher>(); ClassInjector.RegisterTypeInIl2Cpp<PlayTogetherButton>(); ClassInjector.RegisterTypeInIl2Cpp<CustomButton>(); ClassInjector.RegisterTypeInIl2Cpp<ModalBase>(); ClassInjector.RegisterTypeInIl2Cpp<LobbyPanel>(); ClassInjector.RegisterTypeInIl2Cpp<LoadingModal>(); ClassInjector.RegisterTypeInIl2Cpp<ChangelogModal>(); ClassInjector.RegisterTypeInIl2Cpp<TargetSwitcher>(); ClassInjector.RegisterTypeInIl2Cpp<TargetSwitcherManager>(); ClassInjector.RegisterTypeInIl2Cpp<EnemyInterpolatorManager>(); ClassInjector.RegisterTypeInIl2Cpp<SteamTicker>(); ClassInjector.RegisterTypeInIl2Cpp<SteamCallResult>(); ClassInjector.RegisterTypeInIl2Cpp<SteamCallback>(); ClassInjector.RegisterTypeInIl2Cpp<InteractableReviver>(); ClassInjector.RegisterTypeInIl2Cpp<NotificationQueueManager>(); ServiceCollection services = new ServiceCollection(); services.AddSingleton<ManualLogSource>(Log); services.AddSingleton<IWebsocketClientService, WebsocketClientService>(); services.AddSingleton<IUdpClientService, UdpClientService>(); services.AddSingleton((IServiceProvider sp) => (!ModConfig.UseSteamTransport.Value) ? ((INetTransport)sp.GetRequiredService<IUdpClientService>()) : ((INetTransport)sp.GetRequiredService<ISteamNetTransport>())); services.AddSingleton<INetMessageRouter, NetMessageRouter>(); services.AddSingleton<IStateBroadcastService, StateBroadcastService>(); services.AddSingleton<IPlayerManagerService, PlayerManagerService>(); services.AddSingleton<IEnemyManagerService, EnemyManagerService>(); services.AddSingleton<IPlayerStatsSyncService, PlayerStatsSyncService>(); services.AddSingleton<IDesyncDetectorService, DesyncDetectorService>(); services.AddSingleton<IProjectileManagerService, ProjectileManagerService>(); services.AddSingleton<ISynchronizationService, SynchronizationService>(); services.AddSingleton<IPickupManagerService, PickupManagerService>(); services.AddSingleton<IChestManagerService, ChestManagerService>(); services.AddSingleton<ISpawnedObjectManagerService, SpawnedObjectManagerService>(); services.AddSingleton<IFinalBossOrbManagerService, FinalBossOrbManagerService>(); services.AddSingleton<ILocalizationService, LocalizationService>(); services.AddSingleton<IGameBalanceService, GameBalanceService>(); services.AddSingleton<IChangelogService, ChangelogService>(); services.AddSingleton<IEncounterService, EncounterService>(); services.AddSingleton<IReadinessService, ReadinessService>(); services.AddSingleton<ILobbyViewService, LobbyViewService>(); services.AddSingleton<IUiAssetService, UiAssetService>(); services.AddSingleton<ITrackerService, TrackerService>(); services.AddSingleton<ILobbySettingsService, LobbySettingsService>(); services.AddSingleton<IItemProjectileVisualService, ItemProjectileVisualService>(); services.AddSingleton<IEndlessRunService, EndlessRunService>(); services.AddSingleton<ISteamService, SteamService>(); services.AddSingleton<ISteamLobbyService, SteamLobbyService>(); services.AddSingleton<ISteamAvatarService, SteamAvatarService>(); services.AddSingleton<ISteamNetTransport, SteamNetTransport>(); services.AddSingleton<ISteamNetSessionService, SteamNetSessionService>(); services.AddSingleton<SteamNetSelfTest>(); services.AddSingleton<SteamLobbySelfTest>(); services.AddSingleton<SteamLobbyPresenceService>(); services.AddSingleton<SteamInviteService>(); services.AddSingleton<SteamPersonaService>(); services.AddSingleton<INetplaySessionService, NetplaySessionService>(); Services = services.BuildServiceProvider(); Services.GetRequiredService<ILobbyViewService>().SubscribeToLobbyMessages(); Services.GetRequiredService<ISynchronizationService>(); Services.GetRequiredService<IItemProjectileVisualService>(); try { new Harmony("OmniBonk").PatchAll(); } catch (Exception ex3) { ManualLogSource log5 = Log; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Harmony patching failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex3); } log5.LogError(val3); } EncounterInputGrace.MarkRuntimeReady(); GameObject val4 = new GameObject("MainThreadDispatcher"); Object.DontDestroyOnLoad((Object)val4); val4.AddComponent<MainThreadDispatcher>(); GameObject val5 = new GameObject("NetworkHandler"); Object.DontDestroyOnLoad((Object)(object)val5); NetworkHandler = val5.AddComponent<NetworkHandler>(); GameObject val6 = new GameObject("NetPlayersDisplayer"); Object.DontDestroyOnLoad((Object)(object)val6); NetPlayersDisplayer = val6.AddComponent<NetPlayersDisplayer>(); GameObject val7 = new GameObject("CameraSwitcher"); Object.DontDestroyOnLoad((Object)(object)val7); CameraSwitcher = val7.AddComponent<CameraSwitcher>(); GameObject val8 = new GameObject("NotificationQueueManager"); Object.DontDestroyOnLoad((Object)(object)val8); NotificationQueueManager = val8.AddComponent<NotificationQueueManager>(); GameObject val9 = new GameObject("TargetSwitcherManager"); Object.DontDestroyOnLoad((Object)val9); val9.AddComponent<TargetSwitcherManager>(); GameObject val10 = new GameObject("EnemyInterpolatorManager"); Object.DontDestroyOnLoad((Object)val10); val10.AddComponent<EnemyInterpolatorManager>(); GameObject val11 = new GameObject("SteamTicker"); Object.DontDestroyOnLoad((Object)val11); val11.AddComponent<SteamTicker>(); } public void AddPrefab(GameObject prefab) { prefabs.TryAdd(((Object)prefab).name, prefab); } public GameObject GetPrefab(string name) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if (prefabs.TryGetValue(name.Trim(), out var value)) { return value; } ManualLogSource log = Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Prefab not found: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name); } log.LogWarning(val); return null; } public void ClearPrefabs() { prefabs.Clear(); } public void ClearCharacterIcons() { CharactersIcon.Clear(); } public void AddCharacterIcons(List<MyButtonCharacter> characterButtons) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (CharactersIcon.Count > 0) { Log.LogWarning((object)"Character icons already added"); return; } Enumerator<MyButtonCharacter> enumerator = characterButtons.GetEnumerator(); while (enumerator.MoveNext()) { MyButtonCharacter current = enumerator.Current; RawImage val = Object.Instantiate<RawImage>(current.i_icon); Object.DontDestroyOnLoad((Object)(object)val); CharactersIcon.Add(current.characterData.eCharacter, val); } } public void PreventDeath() { if (hasPreventedDeath) { Log.LogWarning((object)"Death already prevented"); return; } originalDiedAction = PlayerHealth.A_Died; hasPreventedDeath = true; PlayerHealth.A_Died = Action.op_Implicit((Action)OnPlayerDied); } private void OnPlayerDied() { if (!((Object)(object)CameraSwitcher == (Object)null) && !CameraSwitcher.IsFollowingTarget) { NetPlayer randomNetPlayer = Services.GetService<IPlayerManagerService>().GetRandomNetPlayer(); if ((Object)(object)randomNetPlayer != (Object)null) { CameraSwitcher.SwitchToTarget(randomNetPlayer.ConnectionId); } } } public void RestoreDeath(bool invokeDeathEvent) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown if (!hasPreventedDeath) { return; } if ((Object)(object)CameraSwitcher != (Object)null) { CameraSwitcher.ResetToLocalPlayer(); } Action val = (PlayerHealth.A_Died = originalDiedAction); originalDiedAction = null; hasPreventedDeath = false; if (!invokeDeathEvent) { return; } if ((Delegate)(object)val == (Delegate)null) { Log.LogWarning((object)"Cannot invoke the game's death handler: there was none installed when the session started."); return; } bool flag = default(bool); try { ((Component)GameManager.Instance.player.playerRenderer).gameObject.SetActive(true); } catch (Exception ex) { ManualLogSource log = Log; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(66, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Could not re-enable the player renderer before the death handler: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex); } log.LogWarning(val3); } try { InvokeDeathSubscribersIsolated(val); } catch (Exception ex2) { Log.LogWarning((object)($"Could not split the death subscriber list ({ex2.GetType().Name}: {ex2.Message}); " + "falling back to a single invoke.")); try { val.Invoke(); } catch (Exception ex3) { ManualLogSource log2 = Log; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(72, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("The game's death handler threw while being restored (invokeDeathEvent): "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex3); } log2.LogWarning(val3); } } } private static void InvokeDeathSubscribersIsolated(Action subscribers) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown Il2CppReferenceArray<Delegate> invocationList = ((Delegate)subscribers).GetInvocationList(); if (invocationList == null || ((Il2CppArrayBase<Delegate>)(object)invocationList).Length == 0) { subscribers.Invoke(); return; } bool flag = default(bool); for (int i = 0; i < ((Il2CppArrayBase<Delegate>)(object)invocationList).Length; i++) { Delegate obj = ((Il2CppArrayBase<Delegate>)(object)invocationList)[i]; Action val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast<Action>() : null); if ((Delegate)(object)val == (Delegate)null) { continue; } try { val.Invoke(); } catch (Exception ex) { ManualLogSource log = Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(55, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Death subscriber "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(i + 1); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" of "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(((Il2CppArrayBase<Delegate>)(object)invocationList).Length); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" threw; continuing with the rest: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex); } log.LogWarning(val2); } } } public AchievementPopup GetAchievementPopup() { if ((Object)(object)AchievementPopup == (Object)null) { GameObject val = ((IEnumerable<GameObject>)Il2CppFindHelper.FindAllGameObjects()).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => (Object)(object)go.GetComponent<AchievementPopup>() != (Object)null)); if ((Object)(object)val != (Object)null) { AchievementPopup = val.GetComponent<AchievementPopup>(); if ((Object)(object)AchievementPopup != (Object)null && (Object)(object)NotificationQueueManager != (Object)null) { NotificationQueueManager.Initialize(); } } } return AchievementPopup; } public MainMenu GetMainMenu() { return MainMenu; } public void SetMainMenu(MainMenu mainMenu) { MainMenu = mainMenu; } public static bool StartNotification((string tableReference, string tableEntryReference) localizedName, (string tableReference, string tableEntryReference) localizedDescription, IEnumerable<string> descriptionArgs, RandomSfx sfx = null, EItem item = (EItem)0) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance?.NotificationQueueManager == (Object)null) { Log.LogWarning((object)"NotificationQueueManager is not initialized"); return false; } Instance.NotificationQueueManager.EnqueueNotification(localizedName, localizedDescription, descriptionArgs, sfx, item); return true; } public static void GoToMainMenu() { if ((Object)(object)GameManager.Instance == (Object)null || (Object)(object)GameManager.Instance.player == (Object)null) { CharacterMenu val = WindowCast.AsCharacterMenu(WindowManager.activeWindow); if ((Object)(object)val != (Object)null) { ((UnityEvent)val.b_back.button.onClick).Invoke(); } if (((Object)WindowManager.activeWindow).name.Contains("Maps And Stats")) { MyButton? obj = ((IEnumerable<MyButton>)WindowManager.activeWindow.allButtons.ToArray()).FirstOrDefault((Func<MyButton, bool>)((MyButton b) => ((Object)b).name == "B_Back")); if (obj != null) { ((UnityEvent)obj.button.onClick).Invoke(); } CharacterMenu obj2 = WindowCast.AsCharacterMenu(WindowManager.activeWindow); if (obj2 != null) { ((UnityEvent)obj2.b_back.button.onClick).Invoke(); } } } else { TransitionUI.Instance.LoadMenu(); } } public void ShowModal(string message) { if ((Object)(object)modal != (Object)null) { modal.UpdateMessage(message); } else { modal = LoadingModal.Show(message); } } public void HideModal() { if ((Object)(object)modal != (Object)null) { modal.Close(); modal = null; } } public void SavePlayerInventoryActions() { if (hasSavedInventoryActions) { Log.LogWarning((object)"Player inventory actions already saved; not overwriting them with the silenced values."); return; } originalWeaponAddedAction = WeaponInventory.A_WeaponAdded; originalStatUpdateAction = PlayerStatsNew.A_StatUpdate; hasSavedInventoryActions = true; WeaponInventory.A_WeaponAdded = null; PlayerStatsNew.A_StatUpdate = null; } public void RestorePlayerInventoryActions() { if (!hasSavedInventoryActions) { Log.LogWarning((object)"Player inventory actions not saved"); return; } WeaponInventory.A_WeaponAdded = originalWeaponAddedAction; PlayerStatsNew.A_StatUpdate = originalStatUpdateAction; originalWeaponAddedAction = null; originalStatUpdateAction = null; hasSavedInventoryActions = false; } public MapEventsDesert GetMapEventsDesert() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if ((Object)(object)MapController.currentMap == (Object)null || (int)MapController.currentMap.eMap != 2) { return null; } if (mapEventsDesert == null) { MapEventsManager obj = GetMapEventsManager(); object obj2; if (obj == null) { obj2 = null; } else { MapEvents mapEvents = obj.mapEvents; obj2 = ((mapEvents != null) ? ((Il2CppObjectBase)mapEvents).TryCast<MapEventsDesert>() : null); } mapEventsDesert = (MapEventsDesert)obj2; } return mapEventsDesert; } private MapEventsManager GetMapEventsManager() { if ((Object)(object)mapEventsManager == (Object)null) { GameObject? obj = ((IEnumerable<GameObject>)Il2CppFindHelper.FindAllGameObjects()).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => (Object)(object)go.GetComponent<MapEventsManager>() != (Object)null)); mapEventsManager = ((obj != null) ? obj.GetComponent<MapEventsManager>() : null); } return mapEventsManager; } public void ClearMapEventsManager() { mapEventsManager = null; mapEventsDesert = null; } public void SetWorldSize(Vector3 size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) WorldSize = size; } public Vector3 GetWorldSize() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return WorldSize; } public void ResetWorldSize() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) WorldSize = Vector3.zero; OriginalWorldSize = Vector3.zero; } public static DistanceToPlayer GetDistanceToPlayer(Vector3 position) { //IL_007b: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if (Time.frameCount != distanceTargetFrame) { MyPlayer player = GameManager.Instance.player; if ((Object)(object)player == (Object)null) { return DistanceToPlayer.Far; } Vector3 position2 = ((Component)player).transform.position; if (player.IsDead()) { CameraSwitcher cameraSwitcher = Instance?.CameraSwitcher; if ((Object)(object)cameraSwitcher != (Object)null) { Transform currentTarget = cameraSwitcher.GetCurrentTarget(); if ((Object)(object)currentTarget != (Object)null) { position2 = currentTarget.position; } } } distanceTarget = position2; distanceTargetFrame = Time.frameCount; } float num = Vector3.Distance(position, distanceTarget); if (num < 25f) { return DistanceToPlayer.Close; } if (num < 60f) { return DistanceToPlayer.Medium; } return DistanceToPlayer.Far; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "OmniBonk"; public const string PLUGIN_NAME = "OmniBonk"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace OmniBonk.Services { internal static class AllocationDiagnostics { private const float REPORT_INTERVAL_SECONDS = 10f; private static float lastReportTime = -999f; private static long lastAllocatedBytes; private static int lastGen0; private static int lastGen1; private static int lastGen2; private static bool primed; internal static void Sample(bool enabled) { if (!enabled) { return; } float unscaledTime = Time.unscaledTime; if (!primed) { Prime(unscaledTime); return; } float num = unscaledTime - lastReportTime; if (!(num < 10f)) { long totalAllocatedBytes = GC.GetTotalAllocatedBytes(); int num2 = GC.CollectionCount(0); int num3 = GC.CollectionCount(1); int num4 = GC.CollectionCount(2); float num5 = (float)(totalAllocatedBytes - lastAllocatedBytes) / num; Plugin.Log.LogInfo((object)($"[alloc] {num5 / 1024f:F0} KB/s managed over {num:F1}s (gen0 +{num2 - lastGen0}, gen1 +{num3 - lastGen1}, gen2 +{num4 - lastGen2}, heap {(float)GC.GetTotalMemory(forceFullCollection: false) / 1048576f:F1} MB). " + "Mod allocations only - IL2CPP game allocations are not counted.")); lastReportTime = unscaledTime; lastAllocatedBytes = totalAllocatedBytes; lastGen0 = num2; lastGen1 = num3; lastGen2 = num4; } } private static void Prime(float now) { primed = true; lastReportTime = now; lastAllocatedBytes = GC.GetTotalAllocatedBytes(); lastGen0 = GC.CollectionCount(0); lastGen1 = GC.CollectionCount(1); lastGen2 = GC.CollectionCount(2); } internal static void Reset() { primed = false; lastReportTime = -999f; } } internal static class BandwidthDiagnostics { private sealed class Counter { public long Bytes; public long Sends; } private const float REPORT_INTERVAL_SECONDS = 10f; private const int TOP_N = 8; private static readonly ConcurrentDictionary<string, Counter> counters = new ConcurrentDictionary<string, Counter>(); private static volatile bool enabled; private static long aggregatedHits; private static long aggregatedEntries; private static long aggregatedMessages; private static float lastReportTime = -999f; private static bool primed; internal static void Record(string messageType, int payloadBytes, int recipients) { if (enabled) { Counter orAdd = counters.GetOrAdd(messageType, (string _) => new Counter()); Interlocked.Add(ref orAdd.Bytes, (long)payloadBytes * (long)recipients); Interlocked.Increment(ref orAdd.Sends); } } internal static void RecordEnemyDamageBatch(int hits, int entries) { if (enabled) { Interlocked.Add(ref aggregatedHits, hits); Interlocked.Add(ref aggregatedEntries, entries); Interlocked.Increment(ref aggregatedMessages); } } internal static void Sample(bool configEnabled, INetTransport udpClientService, IPlayerManagerService playerManagerService) { if (!configEnabled) { if (enabled) { enabled = false; counters.Clear(); ClearAggregation(); primed = false; } return; } enabled = true; float unscaledTime = Time.unscaledTime; if (!primed) { primed = true; lastReportTime = unscaledTime; counters.Clear(); ClearAggregation(); return; } float num = unscaledTime - lastReportTime; if (!(num < 10f)) { lastReportTime = unscaledTime; Report(num, udpClientService, playerManagerService); } } private static void Report(float elapsed, INetTransport udpClientService, IPlayerManagerService playerManagerService) { //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Expected O, but got Unknown List<(string, long, long)> list = (from kv in counters select (Type: kv.Key, Bytes: Interlocked.Exchange(ref kv.Value.Bytes, 0L), Sends: Interlocked.Exchange(ref kv.Value.Sends, 0L)) into x where x.Sends > 0 orderby x.Bytes descending select x).ToList(); if (list.Count == 0) { return; } long num = list.Sum<(string, long, long)>(((string Type, long Bytes, long Sends) x) => x.Bytes); int value = playerManagerService.GetAllPlayers().Count(); Plugin.Log.LogInfo((object)($"[bw] {(float)num / 1024f / elapsed:F1} KB/s payload out over {elapsed:F1}s at {value} player(s). " + "Payload only - excludes LiteNetLib, relay-envelope and UDP/IP overhead.")); bool flag = default(bool); foreach (var item in list.Take(8)) { string text = item.Item1.PadRight(32); string text2 = ((float)item.Item2 / 1024f / elapsed).ToString("F2").PadLeft(8); string text3 = ((float)item.Item3 / elapsed).ToString("F1").PadLeft(7); string text4 = ((double)item.Item2 / (double)item.Item3).ToString("F0").PadLeft(6); ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(26, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[bw] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" KB/s "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/s "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" B/send"); } log.LogInfo(val); } if (list.Count > 8) { List<(string, long, long)> list2 = list.Skip(8).ToList(); string text5 = $"({list2.Count} more types)".PadRight(32); string text6 = ((float)list2.Sum<(string, long, long)>(((string Type, long Bytes, long Sends) x) => x.Bytes) / 1024f / elapsed).ToString("F2").PadLeft(8); ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[bw] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text5); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text6); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" KB/s"); } log2.LogInfo(val); } ReportAggregation(elapsed); ReportLinkQuality(udpClientService, playerManagerService); } private static void ReportAggregation(float elapsed) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown long num = Interlocked.Exchange(ref aggregatedHits, 0L); long num2 = Interlocked.Exchange(ref aggregatedEntries, 0L); long num3 = Interlocked.Exchange(ref aggregatedMessages, 0L); if (num3 != 0L) { string text = ((float)num / elapsed).ToString("F1"); string text2 = ((float)num2 / elapsed).ToString("F1"); string text3 = ((float)num3 / elapsed).ToString("F1"); string text4 = ((num2 == 0L) ? "0" : ((double)num / (double)num2).ToString("F1")); string text5 = ((double)num2 / (double)num3).ToString("F1"); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(106, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[bw] EnemyDamaged aggregation: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" hits/s -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" entries/s -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" batches/s ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" hits per entry, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text5); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" entries per batch)"); } log.LogInfo(val); } } private static void ClearAggregation() { Interlocked.Exchange(ref aggregatedHits, 0L); Interlocked.Exchange(ref aggregatedEntries, 0L); Interlocked.Exchange(ref aggregatedMessages, 0L); } private static void ReportLinkQuality(INetTransport udpClientService, IPlayerManagerService playerManagerService) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown bool flag = default(bool); foreach (Player allPlayer in playerManagerService.GetAllPlayers()) { if (playerManagerService.IsLocalConnectionId(allPlayer.ConnectionId)) { continue; } try { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[bw] peer "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(allPlayer.ConnectionId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(udpClientService.DescribeLink(allPlayer.ConnectionId)); } log.LogInfo(val); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(39, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[bw] Could not read link quality for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<uint>(allPlayer.ConnectionId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log2.LogWarning(val2); } } } internal static void Reset() { primed = false; lastReportTime = -999f; counters.Clear(); ClearAggregation(); } } internal static class BossDiagnostics { private static float lastReportTime = -999f; internal static bool IsBoss(Enemy enemy) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if ((Object)(object)enemy != (Object)null) { return (enemy.enemyFlag & 0x36) > 0; } return false; } internal static void LogEvent(string what, uint id, Enemy enemy, float hp) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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) Vector3 val = (((Object)(object)enemy != (Object)null) ? ((Component)enemy).transform.position : Vector3.zero); string text = (((Object)(object)enemy != (Object)null && (Object)(object)enemy.enemyData != (Object)null) ? ((object)enemy.enemyData.enemyName/*cast due to .constrained prefix*/).ToString() : "?"); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(28, 7, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[boss] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(what); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": id "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<uint>(id); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" hp "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(hp, "F0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" at ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(val.x, "F0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(val.y, "F0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(val.z, "F0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")."); } log.LogInfo(val2); } internal static void Sample(IEnumerable<KeyValuePair<uint, Enemy>> enemies, bool isHost) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) float unscaledTime = Time.unscaledTime; if (unscaledTime - lastReportTime < 10f) { return; } lastReportTime = unscaledTime; bool flag = default(bool); foreach (KeyValuePair<uint, Enemy> enemy in enemies) { Enemy value = enemy.Value; if (IsBoss(value)) { Vector3 position = ((Component)value).transform.position; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(41, 9, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[boss] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(isHost ? "host" : "client"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" sees id "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(enemy.Key); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); EnemyData enemyData = value.enemyData; ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<EEnemy?>((enemyData != null) ? new EEnemy?(enemyData.enemyName) : ((EEnemy?)null)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("hp "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(value.hp, "F0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(value.maxHp, "F0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(position.x, "F0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(position.y, "F0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(position.z, "F0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") flag "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<EEnemyFlag>(value.enemyFlag); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogInfo(val); } } } internal static void Reset() { lastReportTime = -999f; } } public class VersionChanges { public string Version { get; set; } public ICollection<string> Changes { get; set; } = new List<string>(); } public interface IChangelogService { Task<ICollection<VersionChanges>> LoadChangelogAsync(); ICollection<VersionChanges> GetChangesBetweenVersions(ICollection<VersionChanges> changelog, string fromVersion, string toVersion); bool ShouldShowChangelog(); void MarkChangelogAsShown(); } public class ChangelogService(ManualLogSource logger) : IChangelogService { public const string CHANGELOG_FILENAME = "CHANGELOG.toml"; private const string CHANGELOG_URL = "https://raw.githubusercontent.com/CEOYap/OmniBonk/main/CHANGELOG.toml"; private static readonly TimeSpan CHANGELOG_FETCH_TIMEOUT = TimeSpan.FromSeconds(5.0); private static readonly HttpClient httpClient = new HttpClient(); public async Task<ICollection<VersionChanges>> LoadChangelogAsync() { _ = 1; bool flag = default(bool); try { string location = Assembly.GetExecutingAssembly().Location; string pluginDirectory = Path.GetDirectoryName(location); await RefreshChangelogAsync(pluginDirectory); string path = Path.Combine(pluginDirectory, "CHANGELOG.toml"); if (!File.Exists(path)) { ManualLogSource obj = logger; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 0, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Changelog file not found"); } obj.LogError(val); return new List<VersionChanges>(); } ManualLogSource obj2 = logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(20, 0, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Loading changelog..."); } obj2.LogInfo(val2); return ParseChangelog(await File.ReadAllTextAsync(path)); } catch (Exception ex) { ManualLogSource obj3 = logger; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error loading changelog: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } obj3.LogError(val); return new List<VersionChanges>(); } } private async Task RefreshChangelogAsync(string pluginDirectory) { string changelogPath = Path.Combine(pluginDirectory, "CHANGELOG.toml"); bool flag = default(bool); try { using CancellationTokenSource timeout = new CancellationTokenSource(CHANGELOG_FETCH_TIMEOUT); using HttpResponseMessage response = await httpClient.GetAsync("https://raw.githubusercontent.com/CEOYap/OmniBonk/main/CHANGELOG.toml", timeout.Token); if (!response.IsSuccessStatusCode) { ManualLogSource obj = logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(67, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not fetch the changelog from GitHub ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>((int)response.StatusCode); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); using the local copy."); } obj.LogWarning(val); return; } string text = await response.Content.ReadAsStringAsync(); if (!text.Contains("[version.")) { logger.LogWarning((object)"The changelog from GitHub has no version entries; using the local copy."); return; } await File.WriteAllTextAsync(changelogPath, text); logger.LogInfo((object)"Changelog updated from GitHub."); } catch (Exception ex) { ManualLogSource obj2 = logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(67, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not fetch the changelog from GitHub ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); using the local copy."); } obj2.LogWarning(val); } } private ICollection<VersionChanges> ParseChangelog(string content) { //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown List<VersionChanges> list = new List<VersionChanges>(); bool flag = default(bool); try { TomlTable val = Toml.ToModel(content, (string)null, (TomlModelOptions)null); if (!val.ContainsKey("version")) { logger.LogWarning((object)"No 'version' table found in changelog"); return list; } object obj = val["version"]; TomlTable val2 = (TomlTable)((obj is TomlTable) ? obj : null); if (val2 == null) { logger.LogWarning((object)"'version' is not a table"); return list; } foreach (KeyValuePair<string, object> item in val2) { string key = item.Key; object value = item.Value; TomlTable val3 = (TomlTable)((value is TomlTable) ? value : null); if (val3 == null) { ManualLogSource obj2 = logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Version "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(key); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" data is not a table"); } obj2.LogWarning(val4); continue; } if (!val3.ContainsKey("changes")) { ManualLogSource obj3 = logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Version "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(key); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" has no 'changes' array"); } obj3.LogWarning(val4); continue; } object obj4 = val3["changes"]; TomlArray val5 = (TomlArray)((obj4 is TomlArray) ? obj4 : null); if (val5 == null) { ManualLogSource obj5 = logger; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Version "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(key); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" 'changes' is not an array"); } obj5.LogWarning(val4); continue; } List<string> list2 = new List<string>(); foreach (object item2 in val5) { if (item2 is string text && !string.IsNullOrWhiteSpace(text)) { list2.Add(text.Trim()); } } if (list2.Count > 0) { list.Add(new VersionChanges { Version = key, Changes = list2 }); } } list = list.OrderByDescending(delegate(VersionChanges v) { try { return new Version(v.Version); } catch { return new Version(0, 0, 0); } }).ToList(); } catch (Exception ex) { ManualLogSource obj6 = logger; BepInExErrorLogInterpolatedStringHandler val6 = new BepInExErrorLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Error parsing changelog TOML: "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(ex.Message); } obj6.LogError(val6); } return list; } public ICollection<VersionChanges> GetChangesBetweenVersions(ICollection<VersionChanges> changelog, string fromVersion, string toVersion) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown if (changelog == null || changelog.Count == 0) { return new List<VersionChanges>(); } fromVersion = fromVersion?.TrimStart('v') ?? ""; toVersion = toVersion?.TrimStart('v') ?? ""; Version from = null; Version to = null; try { if (!string.IsNullOrEmpty(fromVersion)) { from = new Version(fromVersion); } if (!string.IsNullOrEmpty(toVersion)) { to = new Version(toVersion); } } catch { ManualLogSource obj2 = logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not parse versions: from="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fromVersion); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", to="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(toVersion); } obj2.LogWarning(val); List<VersionChanges> list = new List<VersionChanges>(); list.AddRange(changelog.Take(1)); return list; } if (from == null || to == null) { List<VersionChanges> list2 = new List<VersionChanges>(); list2.AddRange(changelog.Take(1)); return list2; } List<VersionChanges> list3 = new List<VersionChanges>(); list3.AddRange(changelog.Where(delegate(VersionChanges v) { try { Version version = new Version(v.Version); return version > from && version <= to; } catch { return false; } })); return list3; } public bool ShouldShowChangelog() { return ModConfig.ShowChangelog.Value; } public void MarkChangelogAsShown() { ModConfig.ShowChangelog.Value = false; ModConfig.Save(); logger.LogInfo((object)"Changelog marked as shown"); } } public interface IChestManagerService { uint AddChest(Object chestObject); void PushNextChestId(uint chestId); uint? SetNextChest(Object chestObject); Object? GetChest(uint chestId); void RemoveChest(uint chestId); KeyValuePair<uint, Object> GetChestByReference(OpenChest instance); void ResetForNextLevel(); } public class ChestManagerService : IChestManagerService { private readonly ConcurrentDictionary<uint, Object> chests = new ConcurrentDictionary<uint, Object>(); private readonly ConcurrentQueue<uint> nextIds = new ConcurrentQueue<uint>(); private uint nextChestId; public uint AddChest(Object chestObject) { uint num = nextChestId++; chests.TryAdd(num, chestObject); return num; } public void PushNextChestId(uint chestId) { nextIds.Enqueue(chestId); } public uint? SetNextChest(Object chestObject) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if (nextIds.TryDequeue(out var result)) { chests.TryAdd(result, chestObject); return result; } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(40, 0, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No chest id available for spawned chest."); } log.LogWarning(val); return null; } public Object? GetChest(uint chestId) { chests.TryGetValue(chestId, out var value); return value; } public void RemoveChest(uint chestId) { chests.TryRemove(chestId, out var _); } public KeyValuePair<uint, Object> GetChestByReference(OpenChest instance) { foreach (KeyValuePair<uint, Object> chest in chests) { if (chest.Value == (Object)(object)((Component)instance).gameObject) { return chest; } } return new KeyValuePair<uint, Object>(0u, null); } public void ResetForNextLevel() { nextChestId = 0u; nextIds.Clear(); chests.Clear(); } } public interface IDesyncDetectorService { void Tick(float deltaTime); void OnDigestReceived(StateDigest digest); void Reset(); } internal class DesyncDetectorService : IDesyncDetectorService { private const float DIGEST_INTERVAL_SECONDS = 5f; private const float IN_SYNC_SUMMARY_INTERVAL_SECONDS = 60f; private const int COUNT_TOLERANCE_ABSOLUTE = 3; private const float COUNT_TOLERANCE_RATIO = 0.1f; private readonly INetTransport transport; private readonly ISynchronizationService synchronizationService; private readonly IEnemyManagerService enemyManagerService; private readonly IPickupManagerService pickupManagerService; private readonly IEncounterService encounterService; private float accumulator; private uint sequence; private HashSet<string> previousMismatches = new HashSet<string>(); private HashSet<string> currentMismatches = new HashSet<string>(); private readonly List<string> reportLines = new List<string>(); private readonly Dictionary<string, int> localInteractables = new Dictionary<string, int>(); private int digestsCompared; private float lastInSyncSummary = -999f; private float lastSentReport = -999f; private float lastStaleReport = -999f; private static readonly HashSet<uint> diedReceived = new HashSet<uint>(); public DesyncDetectorService(INetTransport transport, ISynchronizationService synchronizationService, IEnemyManagerService enemyManagerService, IPickupManagerService pickupManagerService, IEncounterService encounterService) { this.transport = transport; this.synchronizationService = synchronizationService; this.enemyManagerService = enemyManagerService; this.pickupManagerService = pickupManagerService; this.encounterService = encounterService; } public void Tick(float deltaTime) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown if (!ModConfig.LogDesync.Value) { return; } accumulator += deltaTime; if (accumulator < 5f) { return; } accumulator = 0f; if (!synchronizationService.HasNetplaySessionStarted() || synchronizationService.IsServerMode() != true) { return; } StateDigest val; bool flag = default(bool); try { val = BuildDigest(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(37, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[desync] Could not build a digest: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log.LogWarning(val2); return; } transport.SendToAllClients<StateDigest>(val, NetDelivery.ReliableOrdered); float unscaledTime = Time.unscaledTime; if (unscaledTime - lastSentReport >= 60f) { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(44, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[desync] host sent digest #"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<uint>(val.Sequence); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (sent every "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(5f, "F0"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" s)."); } log2.LogInfo(val3); lastSentReport = unscaledTime; } } private StateDigest BuildDigest() { //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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown StateDigest val = new StateDigest { Sequence = ++sequence, TrackedEnemies = enemyManagerService.TrackedEnemyCount, TrackedPickups = pickupManagerService.TrackedPickupCount, BarrierSessionId = encounterService.SessionId, BarrierRoundId = encounterService.RoundId, PlayerLevel = ReadLocalLevel() }; ReadInteractables(val.InteractablesUsed); return val; } public void OnDigestReceived(StateDigest digest) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (!ModConfig.LogDesync.Value || digest == null) { return; } try { Compare(digest); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[desync] Could not compare digest #"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(digest.Sequence); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } log.LogWarning(val); } } private void Compare(StateDigest host) { //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Expected O, but got Unknown currentMismatches.Clear(); reportLines.Clear(); int trackedEnemyCount = enemyManagerService.TrackedEnemyCount; int trackedPickupCount = pickupManagerService.TrackedPickupCount; int num = ReadLocalLevel(); CheckCount("enemies", host.TrackedEnemies, trackedEnemyCount); CheckCount("pickups", host.TrackedPickups, trackedPickupCount); CheckExact("level", host.PlayerLevel, num); if (encounterService.SessionId != 0 && host.BarrierSessionId != 0) { CheckExact("barrier-session", host.BarrierSessionId, encounterService.SessionId); CheckExact("barrier-round", host.BarrierRoundId, encounterService.RoundId); } localInteractables.Clear(); ReadInteractables(localInteractables); foreach (KeyValuePair<string, int> item in host.InteractablesUsed) { if (!IsPerPlayerCounter(item.Key)) { localInteractables.TryGetValue(item.Key, out var value); CheckExact("counter '" + item.Key + "'", item.Value, value); } } foreach (KeyValuePair<string, int> localInteractable in localInteractables) { if (!IsPerPlayerCounter(localInteractable.Key) && !host.InteractablesUsed.ContainsKey(localInteractable.Key) && localInteractable.Value != 0) { CheckExact("counter '" + localInteractable.Key + "'", 0L, localInteractable.Value); } } digestsCompared++; bool flag = default(bool); if (reportLines.Count > 0) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(82, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[desync] digest #"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(host.Sequence); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(reportLines.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" field(s) disagree with the host "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("on two consecutive digests -- "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join("; ", reportLines)); } log.LogWarning(val); if (trackedEnemyCount > host.TrackedEnemies) { ReportStalestEnemies(trackedEnemyCount - host.TrackedEnemies); } } else { float unscaledTime = Time.unscaledTime; if (unscaledTime - lastInSyncSummary >= 60f) { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(96, 10, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[desync] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(digestsCompared); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" digest(s) compared, in sync at #"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<uint>(host.Sequence); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("(host/local: enemies "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(host.TrackedEnemies); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(trackedEnemyCount); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", pickups "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(host.TrackedPickups); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(trackedPickupCount); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", round "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<uint>(host.BarrierRoundId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<uint>(encounterService.RoundId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("level "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(host.PlayerLevel); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")."); } log2.LogInfo(val2); lastInSyncSummary = unscaledTime; } } HashSet<string> hashSet = currentMismatches; HashSet<string> hashSet2 = previousMismatches; previousMismatches = hashSet; currentMismatches = hashSet2; } internal static void ClearEnemyDiedReceived() { diedReceived.Clear(); } internal static void NoteEnemyDiedReceived(uint id) { if (diedReceived.Count > 20000) { diedReceived.Clear(); } diedReceived.Add(id); } private void ReportStalestEnemies(int extra) { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) float unscaledTime = Time.unscaledTime; if (unscaledTime - lastStaleReport < 60f) { return; } lastStaleReport = unscaledTime; List<(uint, string, float, float, bool)> list = new List<(uint, string, float, float, bool)>(); foreach (KeyValuePair<uint, Enemy> allRegisteredEnemy in enemyManagerService.GetAllRegisteredEnemies()) { Enemy value = allRegisteredEnemy.Value; if ((Object)(object)value == (Object)null) { list.Add((allRegisteredEnemy.Key, "<destroyed>", 0f, float.MaxValue, true)); continue; } EnemyInterpolator component = ((Component)value).GetComponent<EnemyInterpolator>(); float num = (((Object)(object)component == (Object)null) ? (-1f) : component.LastSnapshotAt); float item = ((num < 0f) ? float.MaxValue : (unscaledTime - num)); list.Add((allRegisteredEnemy.Key, ((Object)(object)value.enemyData != (Object)null) ? ((object)value.enemyData.enemyName/*cast due to .constrained prefix*/).ToString() : "?", value.hp, item, value.IsDead())); } list.Sort(((uint Id, string Name, float Hp, float Age, bool Dead) a, (uint Id, string Name, float Hp, float Age, bool Dead) b) => b.Age.CompareTo(a.Age)); int num2 = Math.Min(list.Count, Math.Max(extra, 5)); List<string> list2 = new List<string>(); for (int num3 = 0; num3 < num2; num3++) { (uint, string, float, float, bool) tuple = list[num3]; string value2 = ((tuple.Item4 == float.MaxValue) ? "never" : $"{tuple.Item4:F0}s"); list2.Add($"{tuple.Item1} {tuple.Item2} hp {tuple.Item3:F0}{(tuple.Item5 ? " DEAD" : "")} silent {value2}{(diedReceived.Contains(tuple.Item1) ? " died-msg-RECEIVED" : " no-died-msg")}"); } Plugin.Log.LogWarning((object)($"[desync] OB-51: {extra} more enemies here than on the host; the longest-silent entries: " + string.Join("; ", list2) + ".")); } private void CheckCount(string field, int host, int local) { int num = Math.Max(3, (int)((float)Math.Abs(host) * 0.1f)); if (Math.Abs(host - local) > num) { Flag(field, $"{field} host {host} / local {local}"); } } private void CheckExact(string field, long host, long local) { if (host != local) { Flag(field, $"{field} host {host} / local {local}"); } } private void Flag(string field, string line) { currentMismatches.Add(field); if (previousMismatches.Contains(field)) { reportLines.Add(line); } } private static int ReadLocalLevel() { GameManager instance = GameManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.player == (Object)null || instance.player.inventory == null) { return -1; } PlayerXp playerXp = instance.player.inventory.playerXp; if (playerXp != null) { return playerXp.level; } return -1; } private static bool IsPerPlayerCounter(string key) { return key == "Shady Guy"; } private static void ReadInteractables(Dictionary<string, int> into) { Dictionary<string, InteractableStatusContainer> interactablesByName = InteractablesStatus.interactablesByName; if (interactablesByName == null) { return; } Enumerator<string, InteractableStatusContainer> enumerator = interactablesByName.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<string, InteractableStatusContainer> current = enumerator.Current; if (current.Key != null && current.Value != null) { into[current.Key] = current.Value.numUsed; } } } public void Reset() { accumulator = 0f; sequence = 0u; previousMismatches.Clear(); currentMismatches.Clear(); digestsCompared = 0; lastInSyncSummary = -999f; lastSentReport = -999f; } } internal static class EncounterPauseDiagnostics { private static IEncounterService encounterService; private static bool primed; private static bool lastWindowOpen; private static bool lastPaused; private static int lastSimulationMode; internal static void Sample(bool enabled) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected I4, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown if (!enabled) { return; } if (encounterService == null) { encounterService = Plugin.Services.GetService<IEncounterService>(); } bool flag = encounterService?.IsSoloShop ?? false; bool flag2 = IsEncounterWindowOpen(); bool paused = MyTime.paused; int num = (int)Physics.simulationMode; if (!primed || flag2 != lastWindowOpen || paused != lastPaused || num != lastSimulationMode) { primed = true; lastWindowOpen = flag2; lastPaused = paused; lastSimulationMode = num; string text = ((flag && flag2) ? " (solo shop, unpaused on purpose: OB-67)" : ((flag2 && (!paused || num != 2)) ? " <-- WINDOW OPEN BUT NOT PAUSED (OB-13)" : string.Empty)); ManualLogSource log = Plugin.Log; bool flag3 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(66, 5, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[pause] encounterWindow="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(flag2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" MyTime.paused="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(paused); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Physics.simulationMode="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<SimulationMode>((SimulationMode)num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" t="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Time.unscaledTime, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); } log.LogInfo(val); } } private static bool IsEncounterWindowOpen() { UiManager instance = UiManager.Instance; if ((Object)(object)instance == (Object)null) { return false; } EncounterWindows encounterWindows = instance.encounterWindows; if ((Object)(object)encounterWindows == (Object)null) { return false; } return encounterWindows.encounterInProgress; } internal static void Reset() { primed = false; } } public interface IEncounterService { bool IsWaiting { get; } float WaitedSeconds { get; } float WaitFailsafeSeconds { get; } bool IsSoloShop { get; } uint SessionId { get; } uint RoundId { get; } bool IsClosable(); void AddClosedEncounterForPlayer(uint playerId); void ClearClosedEncounters(); void Close(); void Unclose(); void BeginWaiting(); bool HasWaitedTooLong(); void BeginSoloShop(); void EndSoloShop(); void EnsureSession(); void ResetSession(); bool IsCurrentStamp(uint sessionId, uint roundId); bool TryApplyRelease(uint sessionId, uint roundId); } internal class EncounterService(IPlayerManagerService playerManagerService) : IEncounterService { private readonly ConcurrentDictionary<uint, byte> closedEncounterPerPlayer = new ConcurrentDictionary<uint, byte>(); private bool forceClose; private float waitingSince = -1f; private long lastAppliedRoundId = -1L; public float WaitFailsafeSeconds => 20f; public bool IsWaiting => waitingSince >= 0f; public float WaitedSeconds { get { if (!(waitingSince < 0f)) { return Time.unscaledTime - waitingSince; } return 0f; } } public bool IsSoloShop { get; private set; } public uint SessionId { get; private set; } public uint RoundId { get; private set; } public void AddClosedEncounterForPlayer(uint playerId) { closedEncounterPerPlayer.TryAdd(playerId, 0); } public void ClearClosedEncounters() { closedEncounterPerPlayer.Clear(); forceClose = false; waitingSince = -1f; } public bool IsClosable() { int num = playerManagerService.GetAllPlayers().Count(); if (closedEncounterPerPlayer.Count < num) { return forceClose; } return true; } public void Close() { forceClose = true; } public void Unclose() { forceClose = false; } public void BeginWaiting() { if (waitingSince < 0f) { waitingSince = Time.unscaledTime; } } public void BeginSoloShop() { IsSoloShop = true; } public void EndSoloShop() { IsSoloShop = false; } public bool HasWaitedTooLong() { if (IsWaiting) { return WaitedSeconds >= WaitFailsafeSeconds; } return false; } public void EnsureSession() { if (SessionId == 0) { uint tickCount = (uint)Environment.TickCount; SessionId = ((tickCount == 0) ? 1u : tickCount); RoundId = 0u; lastAppliedRoundId = -1L; } } public void ResetSession() { IsSoloShop = false; SessionId = 0u; RoundId = 0u; lastAppliedRoundId = -1L; } public bool IsCurrentStamp(uint sessionId, uint roundId) { if (sessionId != 0 && SessionId != 0 && sessionId != SessionId) { return false; } return roundId == RoundId; } public bool TryApplyRelease(uint sessionId, uint roundId) { if (sessionId != 0 && SessionId != 0 && sessionId != SessionId) { return false; } if (SessionId == 0 && sessionId != 0) { SessionId = sessionId; } if (lastAppliedRoundId >= 0 && roundId <= lastAppliedRoundId) { return false; } lastAppliedRoundId = roundId; RoundId = roundId + 1; return true; } } public interface IEndlessRunService { bool Active { get; } EndlessRoom CurrentRoom { get; } int Transitions { get; } int CompletedLoops { get; } bool NextRoomKnown { get; } void BeginRun(bool isHost, RunConfig config); bool OnStageLoadRequested(bool finalStageRequested); bool TakeGraveyardArrival(out EndlessRoom room); bool TakeGraveyardActivation(out EndlessRoom room); void Reset(); } internal class EndlessRunService : IEndlessRunService { private readonly ILobbySettingsService lobbySettingsService; private readonly INetTransport transport; private readonly ManualLogSource logger; private bool isHost; private int transitions; private EndlessRoom current; private bool redirecting; private int graveyardPreparedFor = -1; private bool graveyardActivationPending; private int regularCompleted; private Random random = new Random(); private readonly List<EndlessRoom> regularQueue = new List<EndlessRoom>(); private readonly List<EndlessRoom> bossQueue = new List<EndlessRoom>(); private readonly Dictionary<int, (EndlessRoom Room, int RegularCompleted)> planned = new Dictionary<int, (EndlessRoom, int)>(); private readonly Dictionary<int, EndlessRoom> received = new Dictionary<int, EndlessRoom>(); public bool Active { get; private set; } public EndlessRoom CurrentRoom => current; public int Transitions => transitions; public int CompletedLoops { get; private set; } public bool NextRoomKnown { get { if (Active) { if (!isHost) { return received.ContainsKey(transitions + 1); } return true; } return false; } } public EndlessRunService(ILobbySettingsService lobbySettingsService, INetTransport transport, ManualLogSource logger) { this.lobbySettingsService = lobbySettingsService; this.transport = transport; this.logger = logger; EventManager.SubscribeEndlessNextRoomEvents(OnReceivedNextRoom); } public void BeginRun(bool isHost, RunConfig config) { //IL_007b: 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_0137: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Clear(); this.isHost = isHost; if (!lobbySettingsService.EndlessEnabled) { return; } MapData val = ((config != null) ? config.mapData : null) ?? MapController.currentMap; int num = (((Object)(object)((config != null) ? config.mapData : null) != (Object)null && (Object)(object)config.stageData != (Object)null) ? ((Il2CppArrayBase<StageData>)(object)config.mapData.stages).IndexOf(config.stageData) : MapController.index); EndlessRoom? endlessRoom = (((Object)(object)val == (Object)null) ? ((EndlessRoom?)null) : EndlessRooms.FromStage(val.eMap, num, finalBoss: false)); bool flag = default(bool); if (!endlessRoom.HasValue) { ManualLogSource obj = logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(98, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[endless] Endless needs a Forest, Desert or Graveyard start (this run: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((val != null) ? ((object)val.eMap/*cast due to .constrained prefix*/).ToString() : null) ?? "no map"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" stage "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("); off for this run."); } obj.LogWarning(val2); return; } Active = true; current = endlessRoom.Value; ManualLogSource obj2 = logger; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(44, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[endless] Endless Run on; starting room "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<EndlessRoom>(current); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(isHost ? "host rolls the route" : "following the host"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")."); } obj2.LogInfo(val3); if (isHost) { PlanAndSend(1); } } public bool OnStageLoadRequested(bool finalStageRequested) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_00b8: 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_0112: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Expected O, but got Unknown //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown if (!Active || redirecting) { return true; } int num = transitions + 1; int num2 = regularCompleted; EndlessRoom value2; bool flag = default(bool); if (isHost) { if (!planned.Remove(num, out (EndlessRoom, int) value)) { value = Plan(num); } (value2, num2) = value; } else if (!received.Remove(num, out value2)) { ManualLogSource obj = logger; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(85, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[endless] Stage change "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" came before the host's room for it; Endless off for this run."); } obj.LogError(val); Active = false; return true; } DataManager instance = DataManager.Instance; MapData val2 = ((instance != null) ? instance.GetMap(EndlessRooms.Map(value2)) : null); int num3 = EndlessRooms.Stage(value2); if ((Object)(object)val2 == (Object)null || val2.stages == null || num3 >= ((Il2CppArrayBase<StageData>)(object)val2.stages).Length || (Object)(object)((Il2CppArrayBase<StageData>)(object)val2.stages)[num3] == (Object)null) { ManualLogSource obj2 = logger; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(74, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[endless] Room "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<EndlessRoom>(value2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has no stage data in this build; Endless off for this run."); } obj2.LogError(val); Active = false; return true; } StageData val3 = ((Il2CppArrayBase<StageData>)(object)val2.stages)[num3]; RunConfig runConfig = MapController.runConfig; if (runConfig != null) { runConfig.mapData = val2; runConfig.stageData = val3; } MapController.currentMap = val2; MapController.currentStage = val3; MapController.isFinalBossStage = false; BepInExInfoLogInterpolatedStringHandler val4; if (EndlessRooms.IsBoss(current)) { CompletedLoops++; ManualLogSource obj3 = logger; val4 = new BepInExInfoLogInterpolatedStringHandler(57, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[endless] Boss loop "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(CompletedLoops); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" cleared; enemies now x"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<double>(Math.Pow(1.5, CompletedLoops), "0.##"); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" HP, x"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<double>(Math.Pow(1.25, CompletedLoops), "0.##"); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" damage."); } obj3.LogInfo(val4); } transitions = num; current = value2; regularCompleted = num2; ManualLogSource obj4 = logger; val4 = new BepInExInfoLogInterpolatedStringHandler(26, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[endless] Stage change "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<EndlessRoom>(value2); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("."); } obj4.LogInfo(val4); if (isHost) { PlanAndSend(num + 1); } bool flag2 = EndlessRooms.LoadsFinalStage(value2); MapController.index = (flag2 ? num3 : (num3 - 1)); if (flag2 == finalStageRequested) { return true; } redirecting
Tomlyn.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.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using Microsoft.CodeAnalysis; using Tomlyn.Collections; using Tomlyn.Helpers; using Tomlyn.Model; using Tomlyn.Model.Accessors; using Tomlyn.Parsing; using Tomlyn.Syntax; using Tomlyn.Text; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Alexandre Mutel")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Alexandre Mutel")] [assembly: AssemblyDescription("Tomlyn is a TOML parser, validator and authoring library for .NET.")] [assembly: AssemblyFileVersion("0.17.0.0")] [assembly: AssemblyInformationalVersion("0.17.0+ffcc7340e7345fa51b5cac49d0f19d16d1d56e94")] [assembly: AssemblyProduct("Tomlyn")] [assembly: AssemblyTitle("Tomlyn")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/xoofx/Tomlyn")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyVersion("0.17.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Parameter)] internal class NotNullWhenAttribute : Attribute { [ExcludeFromCodeCoverage] public NotNullWhenAttribute(bool returnValue) { } } } namespace Tomlyn { public static class Toml { public static readonly string Version = ((AssemblyFileVersionAttribute)typeof(Toml).Assembly.GetCustomAttributes(typeof(AssemblyFileVersionAttribute), inherit: false)[0]).Version; public static DocumentSyntax Parse(string text, string? sourcePath = null, TomlParserOptions options = TomlParserOptions.ParseAndValidate) { DocumentSyntax documentSyntax = new Parser<StringSourceView>(new Lexer<StringSourceView, StringCharacterIterator>(new StringSourceView(text, sourcePath ?? string.Empty))).Run(); if (!documentSyntax.HasErrors && options == TomlParserOptions.ParseAndValidate) { Validate(documentSyntax); } return documentSyntax; } public static DocumentSyntax Parse(byte[] utf8Bytes, string? sourcePath = null, TomlParserOptions options = TomlParserOptions.ParseAndValidate) { DocumentSyntax documentSyntax = new Parser<StringUtf8SourceView>(new Lexer<StringUtf8SourceView, StringCharacterUtf8Iterator>(new StringUtf8SourceView(utf8Bytes, sourcePath ?? string.Empty))).Run(); if (!documentSyntax.HasErrors && options == TomlParserOptions.ParseAndValidate) { Validate(documentSyntax); } return documentSyntax; } public static DocumentSyntax Validate(DocumentSyntax doc) { if (doc == null) { throw new ArgumentNullException("doc"); } if (doc.HasErrors) { return doc; } new SyntaxValidator(doc.Diagnostics).Visit(doc); return doc; } public static string FromModel(object model, TomlModelOptions? options = null) { if (TryFromModel(model, out string modelAsToml, out DiagnosticsBag diagnostics, options)) { return modelAsToml; } throw new TomlException(diagnostics); } public static bool TryFromModel(object model, [NotNullWhen(true)] out string? modelAsToml, out DiagnosticsBag diagnostics, TomlModelOptions? options = null) { modelAsToml = null; StringWriter stringWriter = new StringWriter(); if (!TryFromModel(model, stringWriter, out diagnostics, options)) { return false; } modelAsToml = stringWriter.ToString(); return true; } public static bool TryFromModel(object model, TextWriter writer, out DiagnosticsBag diagnostics, TomlModelOptions? options = null) { DynamicModelWriteContext dynamicModelWriteContext = new DynamicModelWriteContext(options ?? new TomlModelOptions(), writer); new ModelToTomlTransform(model, dynamicModelWriteContext).Run(); diagnostics = dynamicModelWriteContext.Diagnostics; return !dynamicModelWriteContext.Diagnostics.HasErrors; } public static TomlTable ToModel(string text, string? sourcePath = null, TomlModelOptions? options = null) { return ToModel<TomlTable>(text, sourcePath, options); } public static T ToModel<T>(string text, string? sourcePath = null, TomlModelOptions? options = null) where T : class, new() { DocumentSyntax documentSyntax = Parse(text, sourcePath); if (documentSyntax.HasErrors) { throw new TomlException(documentSyntax.Diagnostics); } return documentSyntax.ToModel<T>(options); } public static bool TryToModel<T>(string text, [NotNullWhen(true)] out T? model, [NotNullWhen(false)] out DiagnosticsBag? diagnostics, string? sourcePath = null, TomlModelOptions? options = null) where T : class, new() { DocumentSyntax documentSyntax = Parse(text, sourcePath); if (documentSyntax.HasErrors) { diagnostics = documentSyntax.Diagnostics; model = null; return false; } return documentSyntax.TryToModel<T>(out model, out diagnostics, options); } public static TomlTable ToModel(this DocumentSyntax syntax) { if (syntax == null) { throw new ArgumentNullException("syntax"); } return TomlTable.From(syntax); } public static T ToModel<T>(this DocumentSyntax syntax, TomlModelOptions? options = null) where T : class, new() { if (!syntax.TryToModel<T>(out T model, out DiagnosticsBag diagnostics, options)) { throw new TomlException(diagnostics); } return model; } public static bool TryToModel<T>(this DocumentSyntax syntax, [NotNullWhen(true)] out T? model, out DiagnosticsBag diagnostics, TomlModelOptions? options = null) where T : class, new() { model = new T(); DynamicModelReadContext dynamicModelReadContext = new DynamicModelReadContext(options ?? new TomlModelOptions()); new SyntaxToModelTransform(dynamicModelReadContext, model).Visit(syntax); diagnostics = dynamicModelReadContext.Diagnostics; return !dynamicModelReadContext.Diagnostics.HasErrors; } } public record struct TomlDateTime(DateTimeOffset DateTime, int SecondPrecision, TomlDateTimeKind Kind) : IConvertible { public TomlDateTime(DateTimeOffset DateTime, int SecondPrecision, TomlDateTimeKind Kind) { this.DateTime = DateTime; this.SecondPrecision = SecondPrecision; this.Kind = Kind; } public TomlDateTime(int year, int month, int day) : this(new DateTimeOffset(new DateTime(year, month, day)), 0, TomlDateTimeKind.LocalDate) { } public TomlDateTime(DateTime datetime) : this(new DateTimeOffset(datetime), 0, TomlDateTimeKind.LocalDateTime) { } public override string ToString() { return ((IConvertible)this).ToString((IFormatProvider?)CultureInfo.InvariantCulture); } [ExcludeFromCodeCoverage] TypeCode IConvertible.GetTypeCode() { return TypeCode.Object; } [ExcludeFromCodeCoverage] bool IConvertible.ToBoolean(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] byte IConvertible.ToByte(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] char IConvertible.ToChar(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] DateTime IConvertible.ToDateTime(IFormatProvider? provider) { return DateTime.DateTime; } [ExcludeFromCodeCoverage] decimal IConvertible.ToDecimal(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] double IConvertible.ToDouble(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] short IConvertible.ToInt16(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] int IConvertible.ToInt32(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] long IConvertible.ToInt64(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] sbyte IConvertible.ToSByte(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] float IConvertible.ToSingle(IFormatProvider? provider) { throw new NotSupportedException(); } string IConvertible.ToString(IFormatProvider? provider) { switch (Kind) { case TomlDateTimeKind.LocalDateTime: if (DateTime.Millisecond == 0) { return DateTime.ToString("yyyy-MM-dd'T'HH:mm:ss", provider); } return DateTime.ToString("yyyy-MM-dd'T'HH:mm:ss." + GetFormatPrecision(SecondPrecision), provider); case TomlDateTimeKind.LocalDate: return DateTime.ToString("yyyy-MM-dd", provider); case TomlDateTimeKind.LocalTime: if (DateTime.Millisecond == 0) { return DateTime.ToString("HH:mm:ss", provider); } return DateTime.ToString("HH:mm:ss." + GetFormatPrecision(SecondPrecision), provider); case TomlDateTimeKind.OffsetDateTimeByNumber: { DateTimeOffset dateTimeOffset2 = DateTime.ToLocalTime(); if (dateTimeOffset2.Millisecond == 0) { return dateTimeOffset2.ToString("yyyy-MM-dd'T'HH:mm:sszzz", provider); } return dateTimeOffset2.ToString("yyyy-MM-dd'T'HH:mm:ss." + GetFormatPrecision(SecondPrecision) + "zzz", provider); } default: { DateTimeOffset dateTimeOffset = DateTime.ToUniversalTime(); if (dateTimeOffset.Millisecond == 0) { return dateTimeOffset.ToString("yyyy-MM-dd'T'HH:mm:ssZ", provider); } return dateTimeOffset.ToString("yyyy-MM-dd'T'HH:mm:ss." + GetFormatPrecision(SecondPrecision) + "Z", provider); } } } object IConvertible.ToType(Type conversionType, IFormatProvider? provider) { if (conversionType == typeof(DateTime)) { return DateTime.DateTime; } if (conversionType == typeof(DateTimeOffset)) { return DateTime; } throw new InvalidCastException("Unable to convert TomlDateTime to destination type " + conversionType.FullName); } [ExcludeFromCodeCoverage] ushort IConvertible.ToUInt16(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] uint IConvertible.ToUInt32(IFormatProvider? provider) { throw new NotSupportedException(); } [ExcludeFromCodeCoverage] ulong IConvertible.ToUInt64(IFormatProvider? provider) { throw new NotSupportedException(); } public static string GetFormatPrecision(int precision) { return precision switch { 1 => "f", 2 => "ff", 3 => "fff", 4 => "ffff", 5 => "fffff", 6 => "ffffff", 7 => "fffffff", _ => "fff", }; } public static implicit operator TomlDateTime(DateTime dateTime) { return new TomlDateTime(dateTime, 0, TomlDateTimeKind.LocalDateTime); } } public enum TomlDateTimeKind { OffsetDateTimeByZ, OffsetDateTimeByNumber, LocalDateTime, LocalDate, LocalTime } public class TomlException : Exception { public DiagnosticsBag Diagnostics { get; } public TomlException(DiagnosticsBag diagnostics) : base(diagnostics.ToString()) { Diagnostics = diagnostics; } } public class TomlModelOptions { public static readonly Func<Type, ObjectKind, object> DefaultCreateInstance = DefaultCreateInstanceImpl; public static readonly Func<string, string> DefaultConvertPropertyName = TomlNamingHelper.PascalToSnakeCase; public static readonly Func<string, string> DefaultConvertFieldName = TomlNamingHelper.PascalToSnakeCase; public Func<PropertyInfo, string?> GetPropertyName { get; set; } public Func<FieldInfo, string?> GetFieldName { get; set; } public Func<string, string> ConvertPropertyName { get; set; } public Func<string, string> ConvertFieldName { get; set; } public Func<Type, ObjectKind, object> CreateInstance { get; set; } [Obsolete("Use ConvertToModel instead")] public Func<object, Type, object?>? ConvertTo { get { return ConvertToModel; } set { ConvertToModel = value; } } public Func<object, Type, object?>? ConvertToModel { get; set; } public Func<object, object?>? ConvertToToml { get; set; } public List<string> AttributeListForIgnore { get; } public List<string> AttributeListForGetName { get; } public bool IgnoreMissingProperties { get; set; } public bool IncludeFields { get; set; } public TomlModelOptions() { GetPropertyName = DefaultGetPropertyNameImpl; GetFieldName = DefaultGetFieldNameImpl; CreateInstance = DefaultCreateInstance; ConvertPropertyName = DefaultConvertPropertyName; ConvertFieldName = DefaultConvertFieldName; IgnoreMissingProperties = false; IncludeFields = false; AttributeListForIgnore = new List<string> { "System.Runtime.Serialization.IgnoreDataMemberAttribute", "System.Text.Json.Serialization.JsonIgnoreAttribute" }; AttributeListForGetName = new List<string> { "System.Runtime.Serialization.DataMemberAttribute", "System.Text.Json.Serialization.JsonPropertyNameAttribute" }; } private string? DefaultGetPropertyNameImpl(PropertyInfo prop) { string text = null; foreach (Attribute customAttribute in prop.GetCustomAttributes()) { string fullName = customAttribute.GetType().FullName; foreach (string item in AttributeListForIgnore) { if (fullName == item) { return null; } } foreach (string item2 in AttributeListForGetName) { if (!(fullName == item2)) { continue; } PropertyInfo property = customAttribute.GetType().GetProperty("Name"); if (property != null && property.PropertyType == typeof(string)) { text = property.GetValue(customAttribute) as string; if (text != null) { break; } } } } return ConvertPropertyName(text ?? prop.Name); } private string? DefaultGetFieldNameImpl(FieldInfo field) { string text = null; foreach (Attribute customAttribute in field.GetCustomAttributes()) { string fullName = customAttribute.GetType().FullName; foreach (string item in AttributeListForIgnore) { if (fullName == item) { return null; } } foreach (string item2 in AttributeListForGetName) { if (!(fullName == item2)) { continue; } PropertyInfo property = customAttribute.GetType().GetProperty("Name"); if (property != null && property.PropertyType == typeof(string)) { text = property.GetValue(customAttribute) as string; if (text != null) { break; } } } } return ConvertFieldName(text ?? field.Name); } private static object DefaultCreateInstanceImpl(Type type, ObjectKind kind) { if (type == typeof(object)) { switch (kind) { case ObjectKind.InlineTable: case ObjectKind.Table: return new TomlTable(kind == ObjectKind.InlineTable); case ObjectKind.TableArray: return new TomlTableArray(); default: return new TomlArray(); } } return Activator.CreateInstance(type) ?? throw new InvalidOperationException("Failed to create an instance of type '" + type.FullName + "'"); } } public enum TomlParserOptions { ParseAndValidate, ParseOnly } } namespace Tomlyn.Text { internal readonly struct char32 { public int Code { get; } public char32(int code) { Code = code; } public static implicit operator int(char32 c) { return c.Code; } public static implicit operator char32(int c) { return new char32(c); } public override string ToString() { return char.ConvertFromUtf32(Code); } } internal interface CharacterIterator : Iterator<char32, int> { } internal static class CharHelper { public static readonly Func<char32, bool> IsHexFunc = IsHex; public static readonly Func<char32, bool> IsOctalFunc = IsOctal; public static readonly Func<char32, bool> IsBinaryFunc = IsBinary; public static readonly Func<char32, int> HexToDecFunc = HexToDecimal; public static readonly Func<char32, int> OctalToDecFunc = OctalToDecimal; public static readonly Func<char32, int> BinaryToDecFunc = BinaryToDecimal; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsControlCharacter(char32 c) { if ((int)c > 31) { return (int)c == 127; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsKeyStart(char32 c) { if (((int)c < 97 || (int)c > 122) && ((int)c < 65 || (int)c > 90) && (int)c != 95 && (int)c != 45) { if ((int)c >= 48) { return (int)c <= 57; } return false; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsKeyContinue(char32 c) { if (((int)c < 97 || (int)c > 122) && ((int)c < 65 || (int)c > 90) && (int)c != 95 && (int)c != 45) { if ((int)c >= 48) { return (int)c <= 57; } return false; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsIdentifierStart(char32 c) { if ((int)c < 97 || (int)c > 122) { if ((int)c >= 65) { return (int)c <= 90; } return false; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsIdentifierContinue(char32 c) { if ((int)c < 97 || (int)c > 122) { if ((int)c >= 65) { return (int)c <= 90; } return false; } return true; } public static bool IsValidUnicodeScalarValue(char32 c) { if ((int)c < 0 || (int)c > 55295) { if ((int)c >= 57344) { return (int)c < 1114111; } return false; } return true; } public static bool IsDigit(char32 c) { if ((int)c >= 48) { return (int)c <= 57; } return false; } public static bool IsDateTime(char32 c) { if (!IsDigit(c) && (int)c != 58 && (int)c != 45 && (int)c != 90 && (int)c != 84 && (int)c != 122 && (int)c != 116 && (int)c != 43) { return (int)c == 46; } return true; } public static string EscapeForToml(this string text, bool allowNewLinesAndSpace = false) { StringBuilder stringBuilder = null; for (int i = 0; i < text.Length; i++) { char c = text[i]; string text2 = null; if (allowNewLinesAndSpace) { if (c == '\r' && i + 1 < text.Length && text[i + 1] == '\n') { text2 = "\r\n"; i++; c = '\n'; } else { switch (c) { case '\n': text2 = "\n"; break; case '\t': text2 = "\t"; break; } } } if (text2 == null) { text2 = EscapeChar(text[i]); } if (text2 != null) { if (stringBuilder == null) { stringBuilder = new StringBuilder(text.Length * 2); stringBuilder.Append(text.Substring(0, i)); } stringBuilder.Append(text2); } else { stringBuilder?.Append(c); } } return stringBuilder?.ToString() ?? text; } private static string? EscapeChar(char c) { if (c < ' ' || c == '"' || c == '\\' || char.IsControl(c)) { return c switch { '\b' => "\\b", '\t' => "\\t", '\n' => "\\n", '\f' => "\\f", '\r' => "\\r", '"' => "\\\"", '\\' => "\\\\", _ => $"\\u{(ushort)c:X4}", }; } return null; } public static string? ToPrintableString(this string? text) { if (text == null) { return null; } StringBuilder stringBuilder = null; for (int i = 0; i < text.Length; i++) { char value = text[i]; string text2 = text[i].ToPrintableString(); if (text2 != null) { if (stringBuilder == null) { stringBuilder = new StringBuilder(text.Length * 2); stringBuilder.Append(text.Substring(0, i)); } stringBuilder.Append(text2); } else { stringBuilder?.Append(value); } } return stringBuilder?.ToString() ?? text; } public static string? ToPrintableString(this char c) { if (c < ' ' || IsWhiteSpace(c)) { return c switch { ' ' => " ", '\b' => "\\b", '\r' => "␍", '\n' => "", '\t' => "\\t", '\a' => "\\a", '\v' => "\\v", '\f' => "\\f", _ => $"\\u{(int)c:X};", }; } return null; } public static bool IsWhiteSpace(char32 c) { if ((int)c != 32) { return (int)c == 9; } return true; } public static bool IsWhiteSpaceOrNewLine(char32 c) { if ((int)c != 32 && (int)c != 9 && (int)c != 13) { return (int)c == 10; } return true; } public static bool IsNewLine(char32 c) { if ((int)c != 13) { return (int)c == 10; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static char32? ToUtf8(byte[] buffer, ref int position) { if (position < buffer.Length) { sbyte b = (sbyte)buffer[position++]; return (b >= 0) ? ((char32)b) : DecodeUTF8_24(buffer, ref position, b); } position = buffer.Length; return null; } private static char32 DecodeUTF8_24(byte[] buffer, ref int position, sbyte c1) { int num = 0; while (c1 < 0) { c1 <<= 1; num++; } if (num > 4 || position + num - 1 > buffer.Length) { throw new CharReaderException($"Invalid UTF8 character at position {position}"); } int num2 = (c1 << 6 - num) | (buffer[position++] & 0x3F); if (num == 2) { return num2; } if (num >= 3) { num2 = (num2 << 6) | (buffer[position++] & 0x3F); } if (num == 4) { num2 = (num2 << 6) | (buffer[position++] & 0x3F); } return num2; } public static int HexToDecimal(char32 c) { if ((int)c < 48 || (int)c > 57) { if ((int)c < 97 || (int)c > 102) { return (int)c - 65 + 10; } return (int)c - 97 + 10; } return (int)c - 48; } public static int OctalToDecimal(char32 c) { return (int)c - 48; } public static int BinaryToDecimal(char32 c) { return (int)c - 48; } private static bool IsHex(char32 c) { if (((int)c < 48 || (int)c > 57) && ((int)c < 97 || (int)c > 102)) { if ((int)c >= 65) { return (int)c <= 70; } return false; } return true; } private static bool IsOctal(char32 c) { if ((int)c >= 48) { return (int)c <= 55; } return false; } private static bool IsBinary(char32 c) { if ((int)c != 48) { return (int)c == 49; } return true; } public static void AppendUtf32(this StringBuilder builder, char32 utf32) { if ((int)utf32 < 65536) { builder.Append((char)(int)utf32); return; } utf32 = (int)utf32 - 65536; builder.Append((char)((int)utf32 / 1024 + 55296)); builder.Append((char)((int)utf32 % 1024 + 56320)); } } internal sealed class CharReaderException : Exception { public CharReaderException(string message) : base(message) { } } internal interface ISourceView : IStringView { string SourcePath { get; } } internal interface ISourceView<out TCharIterator> : ISourceView, IStringView, IStringView<TCharIterator> where TCharIterator : struct, CharacterIterator { } internal interface IStringView { string? GetString(int offset, int length); } internal interface IStringView<out TCharIterator> : IStringView where TCharIterator : struct, CharacterIterator { TCharIterator GetIterator(); } internal struct StringCharacterIterator : CharacterIterator, Iterator<char32, int> { private readonly string _text; public int Start => 0; public StringCharacterIterator(string text) { _text = text; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public char32? TryGetNext(ref int position) { if (position < _text.Length) { char c = _text[position]; position++; return char.IsHighSurrogate(c) ? NextCharWithSurrogate(ref position, c) : c; } position = _text.Length; return null; } private int NextCharWithSurrogate(ref int position, char c1) { if (position < _text.Length) { char c2 = _text[position]; position++; if (char.IsLowSurrogate(c2)) { return char.ConvertToUtf32(c1, c2); } throw new CharReaderException("Unexpected character after high-surrogate char"); } throw new CharReaderException("Unexpected EOF after high-surrogate char"); } } internal struct StringCharacterUtf8Iterator : CharacterIterator, Iterator<char32, int> { private readonly byte[] _text; private readonly int _start; public int Start => _start; public StringCharacterUtf8Iterator(byte[] text) { _text = text; _start = ((text.Length >= 3 && text[0] == 239 && text[1] == 187 && text[0] == 191) ? 3 : 0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public char32? TryGetNext(ref int position) { return CharHelper.ToUtf8(_text, ref position); } } internal struct StringSourceView : ISourceView<StringCharacterIterator>, ISourceView, IStringView, IStringView<StringCharacterIterator> { private readonly string _text; public string SourcePath { get; } public StringSourceView(string text, string sourcePath) { _text = text; SourcePath = sourcePath; } public string? GetString(int offset, int length) { if (offset + length <= _text.Length) { return _text.Substring(offset, length); } return null; } public StringCharacterIterator GetIterator() { return new StringCharacterIterator(_text); } } internal struct StringUtf8SourceView : ISourceView<StringCharacterUtf8Iterator>, ISourceView, IStringView, IStringView<StringCharacterUtf8Iterator> { private readonly byte[] _text; public string SourcePath { get; } public StringUtf8SourceView(byte[] text, string sourcePath) { _text = text; SourcePath = sourcePath; } public string? GetString(int offset, int length) { if (offset + length <= _text.Length) { return Encoding.UTF8.GetString(_text, offset, length); } return null; } public StringCharacterUtf8Iterator GetIterator() { return new StringCharacterUtf8Iterator(_text); } } } namespace Tomlyn.Syntax { public sealed class ArrayItemSyntax : SyntaxNode { private ValueSyntax? _value; private SyntaxToken? _comma; public ValueSyntax? Value { get { return _value; } set { ParentToThis(ref _value, value); } } public SyntaxToken? Comma { get { return _comma; } set { ParentToThis(ref _comma, value, TokenKind.Comma); } } public override int ChildrenCount => 2; public ArrayItemSyntax() : base(SyntaxKind.ArrayItem) { } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { if (index != 0) { return Comma; } return Value; } } public sealed class ArraySyntax : ValueSyntax { private SyntaxToken? _openBracket; private SyntaxToken? _closeBracket; public SyntaxToken? OpenBracket { get { return _openBracket; } set { ParentToThis(ref _openBracket, value, TokenKind.OpenBracket); } } public SyntaxList<ArrayItemSyntax> Items { get; } public SyntaxToken? CloseBracket { get { return _closeBracket; } set { ParentToThis(ref _closeBracket, value, TokenKind.CloseBracket); } } public override int ChildrenCount => 3; public ArraySyntax() : base(SyntaxKind.Array) { Items = new SyntaxList<ArrayItemSyntax> { Parent = this }; } public ArraySyntax(int[] values) : this() { if (values == null) { throw new ArgumentNullException("values"); } OpenBracket = SyntaxFactory.Token(TokenKind.OpenBracket); CloseBracket = SyntaxFactory.Token(TokenKind.CloseBracket); for (int i = 0; i < values.Length; i++) { ArrayItemSyntax arrayItemSyntax = new ArrayItemSyntax { Value = new IntegerValueSyntax(values[i]) }; if (i + 1 < values.Length) { arrayItemSyntax.Comma = SyntaxFactory.Token(TokenKind.Comma); arrayItemSyntax.Comma.AddTrailingWhitespace(); } Items.Add(arrayItemSyntax); } } public ArraySyntax(string[] values) : this() { if (values == null) { throw new ArgumentNullException("values"); } OpenBracket = SyntaxFactory.Token(TokenKind.OpenBracket); CloseBracket = SyntaxFactory.Token(TokenKind.CloseBracket); for (int i = 0; i < values.Length; i++) { ArrayItemSyntax arrayItemSyntax = new ArrayItemSyntax { Value = new StringValueSyntax(values[i]) }; if (i + 1 < values.Length) { arrayItemSyntax.Comma = SyntaxFactory.Token(TokenKind.Comma); arrayItemSyntax.Comma.AddTrailingWhitespace(); } Items.Add(arrayItemSyntax); } } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return index switch { 0 => OpenBracket, 1 => Items, _ => CloseBracket, }; } protected override string ToDebuggerDisplay() { return $"{base.ToDebuggerDisplay()} Count = {Items.ChildrenCount}"; } } public abstract class BareKeyOrStringValueSyntax : ValueSyntax { internal BareKeyOrStringValueSyntax(SyntaxKind kind) : base(kind) { } } public sealed class BareKeySyntax : BareKeyOrStringValueSyntax { private SyntaxToken? _key; public SyntaxToken? Key { get { return _key; } set { ParentToThis(ref _key, value, TokenKind.BasicKey); } } public override int ChildrenCount => 1; public BareKeySyntax() : base(SyntaxKind.BasicKey) { } public BareKeySyntax(string name) : this() { if (!IsBareKey(name)) { throw new ArgumentOutOfRangeException("The key `" + name + "` does not contain valid characters [A-Za-z0-9_\\-]"); } Key = new SyntaxToken(TokenKind.BasicKey, name); } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return Key; } public static bool IsBareKey(string name) { if (name == null) { throw new ArgumentNullException("name"); } if (name.Length == 0 || string.IsNullOrWhiteSpace(name)) { return false; } for (int i = 0; i < name.Length; i++) { if (!CharHelper.IsKeyContinue(name[i])) { return false; } } return true; } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + ": " + ((Key != null) ? TomlFormatHelper.ToString(Key.ToString(), TomlPropertyDisplayKind.Default) : string.Empty); } } public sealed class BooleanValueSyntax : ValueSyntax { private SyntaxToken? _token; private bool _value; public SyntaxToken? Token { get { return _token; } set { ParentToThis(ref _token, value, TokenKind.True, TokenKind.False); } } public bool Value { get { return _value; } set { _value = value; } } public override int ChildrenCount => 1; public BooleanValueSyntax() : base(SyntaxKind.Boolean) { } public BooleanValueSyntax(bool value) : this() { TokenKind tokenKind = (value ? TokenKind.True : TokenKind.False); Token = new SyntaxToken(tokenKind, tokenKind.ToText()); Value = value; } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return Token; } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + ": " + TomlFormatHelper.ToString(Value); } } public sealed class DateTimeValueSyntax : ValueSyntax { private SyntaxToken? _token; public SyntaxToken? Token { get { return _token; } set { ParentToThis(ref _token, value, value?.TokenKind.IsDateTime() ?? false, $"The token kind `{value?.TokenKind}` is not a datetime token"); } } public TomlDateTime Value { get; set; } public override int ChildrenCount => 1; public DateTimeValueSyntax(SyntaxKind kind) : base(CheckDateTimeKind(kind)) { } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return Token; } private static SyntaxKind CheckDateTimeKind(SyntaxKind kind) { if ((uint)(kind - 4) <= 4u) { return kind; } throw new ArgumentOutOfRangeException("kind", kind, null); } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + ": " + TomlFormatHelper.ToString(Value); } } public class DiagnosticMessage { public DiagnosticMessageKind Kind { get; } public SourceSpan Span { get; } public string Message { get; } public DiagnosticMessage(DiagnosticMessageKind kind, SourceSpan span, string message) { Kind = kind; Span = span; Message = message; } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(Span.ToStringSimple()); stringBuilder.Append(" : "); switch (Kind) { case DiagnosticMessageKind.Error: stringBuilder.Append("error"); break; case DiagnosticMessageKind.Warning: stringBuilder.Append("warning"); break; default: throw new InvalidOperationException($"Message type [{Kind}] not supported"); } stringBuilder.Append(" : "); if (Message != null) { stringBuilder.Append(Message); } return stringBuilder.ToString(); } } public enum DiagnosticMessageKind { Error, Warning } [DebuggerDisplay("{Count} Errors: {HasErrors}")] public class DiagnosticsBag : IEnumerable<DiagnosticMessage>, IEnumerable { private readonly List<DiagnosticMessage> _messages; public int Count => _messages.Count; public DiagnosticMessage this[int index] => _messages[index]; public bool HasErrors { get; private set; } public DiagnosticsBag() { _messages = new List<DiagnosticMessage>(); } public DiagnosticsBag(IEnumerable<DiagnosticMessage> messages) : this() { foreach (DiagnosticMessage message in messages) { Add(message); } } public void Add(DiagnosticMessage message) { if (message == null) { throw new ArgumentNullException("message"); } _messages.Add(message); if (message.Kind == DiagnosticMessageKind.Error) { HasErrors = true; } } public void AddRange(IEnumerable<DiagnosticMessage> messages) { foreach (DiagnosticMessage message in messages) { Add(message); } } public void Clear() { _messages.Clear(); HasErrors = false; } public void Warning(SourceSpan span, string text) { Add(new DiagnosticMessage(DiagnosticMessageKind.Warning, span, text)); } public void Error(SourceSpan span, string text) { Add(new DiagnosticMessage(DiagnosticMessageKind.Error, span, text)); } public List<DiagnosticMessage>.Enumerator GetEnumerator() { return _messages.GetEnumerator(); } IEnumerator<DiagnosticMessage> IEnumerable<DiagnosticMessage>.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_messages).GetEnumerator(); } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); foreach (DiagnosticMessage message in _messages) { stringBuilder.AppendLine(message.ToString()); } return stringBuilder.ToString(); } } public sealed class DocumentSyntax : SyntaxNode { public DiagnosticsBag Diagnostics { get; } public bool HasErrors => Diagnostics.HasErrors; public SyntaxList<KeyValueSyntax> KeyValues { get; } public SyntaxList<TableSyntaxBase> Tables { get; } public override int ChildrenCount => 2; public DocumentSyntax() : base(SyntaxKind.Document) { KeyValues = new SyntaxList<KeyValueSyntax> { Parent = this }; Tables = new SyntaxList<TableSyntaxBase> { Parent = this }; Diagnostics = new DiagnosticsBag(); } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode GetChildImpl(int index) { if (index != 0) { return Tables; } return KeyValues; } } public sealed class DottedKeyItemSyntax : ValueSyntax { private SyntaxToken? _dot; private BareKeyOrStringValueSyntax? _key; public SyntaxToken? Dot { get { return _dot; } set { ParentToThis(ref _dot, value, TokenKind.Dot); } } public BareKeyOrStringValueSyntax? Key { get { return _key; } set { ParentToThis(ref _key, value); } } public override int ChildrenCount => 2; public DottedKeyItemSyntax() : base(SyntaxKind.DottedKeyItem) { } public DottedKeyItemSyntax(string key) : this() { if (key == null) { throw new ArgumentNullException("key"); } Dot = SyntaxFactory.Token(TokenKind.Dot); Key = (BareKeySyntax.IsBareKey(key) ? ((BareKeyOrStringValueSyntax)new BareKeySyntax(key)) : ((BareKeyOrStringValueSyntax)new StringValueSyntax(key))); } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { if (index != 0) { return Key; } return Dot; } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + ": " + ToString(); } } public sealed class FloatValueSyntax : ValueSyntax { private SyntaxToken? _token; private const string FloatFormat = "g16"; public SyntaxToken? Token { get { return _token; } set { ParentToThis(ref _token, value, value?.TokenKind.IsFloat() ?? false, TokenKind.Float); } } public double Value { get; set; } public override int ChildrenCount => 1; public FloatValueSyntax() : base(SyntaxKind.Float) { } public FloatValueSyntax(double value) : this() { if (double.IsNaN(value)) { Token = new SyntaxToken(TokenKind.Nan, (value < 0.0) ? TokenKind.NegativeNan.ToText() : TokenKind.Nan.ToText()); } else if (double.IsPositiveInfinity(value)) { Token = new SyntaxToken(TokenKind.PositiveInfinite, TokenKind.PositiveInfinite.ToText()); } else if (double.IsNegativeInfinity(value)) { Token = new SyntaxToken(TokenKind.NegativeInfinite, TokenKind.NegativeInfinite.ToText()); } else { Token = new SyntaxToken(TokenKind.Float, value.ToString("g16", CultureInfo.InvariantCulture)); } Value = value; } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return Token; } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + ": " + TomlFormatHelper.ToString(Value); } } public sealed class InlineTableItemSyntax : SyntaxNode { private KeyValueSyntax? _keyValue; private SyntaxToken? _comma; public KeyValueSyntax? KeyValue { get { return _keyValue; } set { ParentToThis(ref _keyValue, value); } } public SyntaxToken? Comma { get { return _comma; } set { ParentToThis(ref _comma, value, TokenKind.Comma); } } public override int ChildrenCount => 2; public InlineTableItemSyntax() : base(SyntaxKind.InlineTable) { } public InlineTableItemSyntax(KeyValueSyntax keyValue) : this() { KeyValue = keyValue ?? throw new ArgumentNullException("keyValue"); } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { if (index != 0) { return Comma; } return KeyValue; } } public sealed class InlineTableSyntax : ValueSyntax { private SyntaxToken? _openBrace; private SyntaxToken? _closeBrace; public SyntaxToken? OpenBrace { get { return _openBrace; } set { ParentToThis(ref _openBrace, value, TokenKind.OpenBrace); } } public SyntaxList<InlineTableItemSyntax> Items { get; } public SyntaxToken? CloseBrace { get { return _closeBrace; } set { ParentToThis(ref _closeBrace, value, TokenKind.CloseBrace); } } public override int ChildrenCount => 3; public InlineTableSyntax() : base(SyntaxKind.InlineTable) { Items = new SyntaxList<InlineTableItemSyntax> { Parent = this }; } public InlineTableSyntax(params KeyValueSyntax[] keyValues) : this() { if (keyValues == null) { throw new ArgumentNullException("keyValues"); } OpenBrace = SyntaxFactory.Token(TokenKind.OpenBrace).AddTrailingWhitespace(); CloseBrace = SyntaxFactory.Token(TokenKind.CloseBrace).AddLeadingWhitespace(); for (int i = 0; i < keyValues.Length; i++) { KeyValueSyntax keyValue = keyValues[i]; Items.Add(new InlineTableItemSyntax(keyValue) { Comma = ((i + 1 < keyValues.Length) ? SyntaxFactory.Token(TokenKind.Comma).AddTrailingWhitespace() : null) }); } } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return index switch { 0 => OpenBrace, 1 => Items, _ => CloseBrace, }; } protected override string ToDebuggerDisplay() { return $"{base.ToDebuggerDisplay()} Count = {Items.ChildrenCount}"; } } public sealed class IntegerValueSyntax : ValueSyntax { private SyntaxToken? _token; public SyntaxToken? Token { get { return _token; } set { ParentToThis(ref _token, value, value?.TokenKind.IsInteger() ?? false, "decimal/hex/binary/octal integer"); } } public long Value { get; set; } public override int ChildrenCount => 1; public IntegerValueSyntax() : base(SyntaxKind.Integer) { } public IntegerValueSyntax(long value) : this() { Token = new SyntaxToken(TokenKind.Integer, value.ToString(CultureInfo.InvariantCulture)); Value = value; } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return Token; } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + ": " + TomlFormatHelper.ToString(Value); } } public sealed class InvalidSyntaxToken : SyntaxToken { public TokenKind InvalidKind { get; set; } } public sealed class KeySyntax : ValueSyntax { private BareKeyOrStringValueSyntax? _key; public BareKeyOrStringValueSyntax? Key { get { return _key; } set { ParentToThis(ref _key, value); } } public SyntaxList<DottedKeyItemSyntax> DotKeys { get; } public override int ChildrenCount => 2; public KeySyntax() : base(SyntaxKind.Key) { DotKeys = new SyntaxList<DottedKeyItemSyntax> { Parent = this }; } public KeySyntax(string key) : this() { Key = (BareKeySyntax.IsBareKey(key) ? ((BareKeyOrStringValueSyntax)new BareKeySyntax(key)) : ((BareKeyOrStringValueSyntax)new StringValueSyntax(key))); } public KeySyntax(string key, string dotKey1) : this() { if (key == null) { throw new ArgumentNullException("key"); } if (dotKey1 == null) { throw new ArgumentNullException("dotKey1"); } Key = (BareKeySyntax.IsBareKey(key) ? ((BareKeyOrStringValueSyntax)new BareKeySyntax(key)) : ((BareKeyOrStringValueSyntax)new StringValueSyntax(key))); DotKeys.Add(new DottedKeyItemSyntax(dotKey1)); } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { if (index == 0) { return Key; } return DotKeys; } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + ": " + ToString(); } } public sealed class KeyValueSyntax : SyntaxNode { private KeySyntax? _key; private SyntaxToken? _equalToken; private ValueSyntax? _value; private SyntaxToken? _endOfLineToken; public KeySyntax? Key { get { return _key; } set { ParentToThis(ref _key, value); } } public SyntaxToken? EqualToken { get { return _equalToken; } set { ParentToThis(ref _equalToken, value, TokenKind.Equal); } } public ValueSyntax? Value { get { return _value; } set { ParentToThis(ref _value, value); } } public SyntaxToken? EndOfLineToken { get { return _endOfLineToken; } set { ParentToThis(ref _endOfLineToken, value, TokenKind.NewLine, TokenKind.Eof); } } public override int ChildrenCount => 4; public KeyValueSyntax() : base(SyntaxKind.KeyValue) { } public KeyValueSyntax(string key, ValueSyntax value) : this() { if (key == null) { throw new ArgumentNullException("key"); } Key = new KeySyntax(key); Value = value ?? throw new ArgumentNullException("value"); EqualToken = SyntaxFactory.Token(TokenKind.Equal); EqualToken.AddLeadingWhitespace(); EqualToken.AddTrailingWhitespace(); EndOfLineToken = SyntaxFactory.NewLine(); } public KeyValueSyntax(KeySyntax key, ValueSyntax value) : this() { Key = key ?? throw new ArgumentNullException("key"); Value = value ?? throw new ArgumentNullException("value"); EqualToken = SyntaxFactory.Token(TokenKind.Equal); EqualToken.AddLeadingWhitespace(); EqualToken.AddTrailingWhitespace(); EndOfLineToken = SyntaxFactory.NewLine(); } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return index switch { 0 => Key, 1 => EqualToken, 2 => Value, _ => EndOfLineToken, }; } protected override string ToDebuggerDisplay() { return $"{base.ToDebuggerDisplay()}: {Key} = {Value}"; } } public struct SourceSpan { public string FileName; public TextPosition Start; public TextPosition End; public int Offset => Start.Offset; public int Length => End.Offset - Start.Offset + 1; public SourceSpan(string fileName, TextPosition start, TextPosition end) { FileName = fileName; Start = start; End = end; } public override string ToString() { return $"{FileName}{Start}-{End}"; } public string ToStringSimple() { return $"{FileName}{Start}"; } } public sealed class StringValueSyntax : BareKeyOrStringValueSyntax { private SyntaxToken? _token; public SyntaxToken? Token { get { return _token; } set { ParentToThis(ref _token, value, value?.TokenKind.IsString() ?? false, "string"); } } public string? Value { get; set; } public override int ChildrenCount => 1; public StringValueSyntax() : base(SyntaxKind.String) { } public StringValueSyntax(string text) : this() { if (text == null) { throw new ArgumentNullException("text"); } Token = new SyntaxToken(TokenKind.String, "\"" + text.EscapeForToml() + "\""); Value = text; } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return Token; } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + ": " + ((Value != null) ? TomlFormatHelper.ToString(Value, TomlPropertyDisplayKind.Default) : string.Empty); } } public static class SyntaxFactory { public static SyntaxTrivia Whitespace() { return new SyntaxTrivia(TokenKind.Whitespaces, " "); } public static SyntaxTrivia NewLineTrivia() { return new SyntaxTrivia(TokenKind.NewLine, "\n"); } public static SyntaxTrivia Comment(string comment) { if (comment == null) { throw new ArgumentNullException("comment"); } return new SyntaxTrivia(TokenKind.Comment, "# " + comment); } public static SyntaxToken NewLine() { return new SyntaxToken(TokenKind.NewLine, "\n"); } public static SyntaxToken Token(TokenKind kind) { if (kind == TokenKind.NewLine || !kind.IsToken()) { throw new ArgumentOutOfRangeException($"The token kind `{kind}` is not supported for a plain token without a predefined value"); } string text = kind.ToText(); return new SyntaxToken(kind, text); } } public enum SyntaxKind { Array, ArrayItem, BasicKey, Boolean, OffsetDateTimeByZ, OffsetDateTimeByNumber, LocalDateTime, LocalDate, LocalTime, Document, DottedKeyItem, Float, InlineTable, Integer, Key, KeyValue, List, String, Table, TableArray, Token } public abstract class SyntaxList : SyntaxNode { protected readonly List<SyntaxNode> Children; public sealed override int ChildrenCount => Children.Count; internal SyntaxList() : base(SyntaxKind.List) { Children = new List<SyntaxNode>(); } protected override SyntaxNode GetChildImpl(int index) { return Children[index]; } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } } public sealed class SyntaxList<TSyntaxNode> : SyntaxList, IEnumerable<TSyntaxNode>, IEnumerable where TSyntaxNode : SyntaxNode { public struct Enumerator : IEnumerator<TSyntaxNode>, IEnumerator, IDisposable { private readonly List<SyntaxNode> _nodes; private int _index; public TSyntaxNode Current { get { if (_index < 0) { throw new InvalidOperationException("MoveNext must be called before accessing Current"); } return (TSyntaxNode)_nodes[_index]; } } object IEnumerator.Current => Current; public Enumerator(List<SyntaxNode> nodes) { _nodes = nodes; _index = -1; } public bool MoveNext() { if (_index + 1 == _nodes.Count) { return false; } _index++; return true; } public void Reset() { _index = -1; } public void Dispose() { } } public void Add(TSyntaxNode node) { if (node == null) { throw new ArgumentNullException("node"); } if (node.Parent != null) { throw ThrowHelper.GetExpectingNoParentException(); } Children.Add(node); node.Parent = this; } public new TSyntaxNode? GetChild(int index) { return (TSyntaxNode)base.GetChild(index); } protected override SyntaxNode GetChildImpl(int index) { return Children[index]; } public void RemoveChildAt(int index) { SyntaxNode syntaxNode = Children[index]; Children.RemoveAt(index); syntaxNode.Parent = null; } public void RemoveChild(TSyntaxNode node) { if (node == null) { throw new ArgumentNullException("node"); } if (node.Parent != this) { throw new InvalidOperationException("The node is not part of this list"); } Children.Remove(node); node.Parent = null; } public Enumerator GetEnumerator() { return new Enumerator(Children); } IEnumerator<TSyntaxNode> IEnumerable<TSyntaxNode>.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public abstract class SyntaxNode : SyntaxNodeBase { private readonly struct ExpectedTuple2<T1, T2> { public readonly T1 Value1; public readonly T2 Value2; public ExpectedTuple2(T1 value1, T2 value2) { Value1 = value1; Value2 = value2; } public override string ToString() { return $"`{Value1}` or `{Value2}`"; } } public SyntaxKind Kind { get; } public List<SyntaxTrivia>? LeadingTrivia { get; set; } public List<SyntaxTrivia>? TrailingTrivia { get; set; } public abstract int ChildrenCount { get; } protected SyntaxNode(SyntaxKind kind) { Kind = kind; } public SyntaxNode? GetChild(int index) { if (index < 0) { throw ThrowHelper.GetIndexNegativeArgumentOutOfRangeException(); } if (index > ChildrenCount) { throw ThrowHelper.GetIndexArgumentOutOfRangeException(ChildrenCount); } return GetChildImpl(index); } protected abstract SyntaxNode? GetChildImpl(int index); public override string ToString() { StringWriter stringWriter = new StringWriter(); WriteTo(stringWriter); return stringWriter.ToString(); } public void WriteTo(TextWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } WriteToInternal(writer); } private void WriteToInternal(TextWriter writer) { WriteTriviaTo(LeadingTrivia, writer); if (this is SyntaxToken syntaxToken) { writer.Write(syntaxToken.TokenKind.ToText() ?? syntaxToken.Text); } else { int childrenCount = ChildrenCount; for (int i = 0; i < childrenCount; i++) { GetChild(i)?.WriteToInternal(writer); } } WriteTriviaTo(TrailingTrivia, writer); } private static void WriteTriviaTo(List<SyntaxTrivia>? trivias, TextWriter writer) { if (trivias == null) { return; } foreach (SyntaxTrivia trivia in trivias) { if (trivia != null) { writer.Write(trivia.Text); } } } protected void ParentToThis<TSyntaxNode>(ref TSyntaxNode? set, TSyntaxNode? node) where TSyntaxNode : SyntaxNode { if (node?.Parent != null) { throw ThrowHelper.GetExpectingNoParentException(); } if (set != null) { set.Parent = null; } if (node != null) { node.Parent = this; } set = node; } protected void ParentToThis<TSyntaxNode>(ref TSyntaxNode? set, TSyntaxNode? node, TokenKind expectedKind) where TSyntaxNode : SyntaxToken { ParentToThis(ref set, node, node != null && node.TokenKind == expectedKind, expectedKind); } protected void ParentToThis<TSyntaxNode, TExpected>(ref TSyntaxNode? set, TSyntaxNode? node, bool expectedKindSuccess, TExpected expectedMessage) where TSyntaxNode : SyntaxToken { if (node != null && !expectedKindSuccess) { throw new InvalidOperationException($"Unexpected node kind `{node.TokenKind}` while expecting `{expectedMessage}`"); } ParentToThis(ref set, node); } protected void ParentToThis<TSyntaxNode>(ref TSyntaxNode? set, TSyntaxNode? node, TokenKind expectedKind1, TokenKind expectedKind2) where TSyntaxNode : SyntaxToken { int expectedKindSuccess; if (node == null || node.TokenKind != expectedKind1) { expectedKindSuccess = ((node != null && node.TokenKind == expectedKind2) ? 1 : 0); } else { expectedKindSuccess = 1; } ParentToThis(ref set, node, (byte)expectedKindSuccess != 0, new ExpectedTuple2<TokenKind, TokenKind>(expectedKind1, expectedKind2)); } } [DebuggerDisplay("{ToDebuggerDisplay(),nq}")] public abstract class SyntaxNodeBase { public SourceSpan Span; public SyntaxNode? Parent { get; internal set; } public abstract void Accept(SyntaxVisitor visitor); protected virtual string ToDebuggerDisplay() { return GetType().Name ?? ""; } } public static class SyntaxNodeExtensions { public static IEnumerable<SyntaxNodeBase> Tokens(this SyntaxNode node, bool includeCommentsAndWhitespaces = true) { foreach (SyntaxNodeBase item in node.Descendants(includeTokensCommentsAndWhitespaces: true)) { if (item is SyntaxTrivia) { if (!includeCommentsAndWhitespaces) { continue; } } else if (!(item is SyntaxToken)) { continue; } yield return item; } } public static IEnumerable<SyntaxNodeBase> Descendants(this SyntaxNode node, bool includeTokensCommentsAndWhitespaces = false) { if (!includeTokensCommentsAndWhitespaces && node is SyntaxToken) { yield break; } if (includeTokensCommentsAndWhitespaces && node.LeadingTrivia != null) { foreach (SyntaxTrivia leadingTrivium in node.LeadingTrivia) { yield return leadingTrivium; } } int childrenCount = node.ChildrenCount; for (int i = 0; i < childrenCount; i++) { SyntaxNode child = node.GetChild(i); if (child is SyntaxList list) { int subChildrenCount = list.ChildrenCount; for (int j = 0; j < subChildrenCount; j++) { SyntaxNode child2 = list.GetChild(j); if (child2 == null) { continue; } foreach (SyntaxNodeBase item in child2.Descendants(includeTokensCommentsAndWhitespaces)) { yield return item; } } } else { if (child == null) { continue; } foreach (SyntaxNodeBase item2 in child.Descendants(includeTokensCommentsAndWhitespaces)) { yield return item2; } } } yield return node; if (!includeTokensCommentsAndWhitespaces || node.TrailingTrivia == null) { yield break; } foreach (SyntaxTrivia trailingTrivium in node.TrailingTrivia) { yield return trailingTrivium; } } public static void Add(this SyntaxList<KeyValueSyntax> list, string name, int value) { if (list == null) { throw new ArgumentNullException("list"); } list.Add(new KeyValueSyntax(name, new IntegerValueSyntax(value))); } public static void Add(this SyntaxList<KeyValueSyntax> list, string name, long value) { if (list == null) { throw new ArgumentNullException("list"); } list.Add(new KeyValueSyntax(name, new IntegerValueSyntax(value))); } public static void Add(this SyntaxList<KeyValueSyntax> list, string name, bool value) { if (list == null) { throw new ArgumentNullException("list"); } list.Add(new KeyValueSyntax(name, new BooleanValueSyntax(value))); } public static void Add(this SyntaxList<KeyValueSyntax> list, string name, double value) { if (list == null) { throw new ArgumentNullException("list"); } list.Add(new KeyValueSyntax(name, new FloatValueSyntax(value))); } public static void Add(this SyntaxList<KeyValueSyntax> list, string name, string value) { if (list == null) { throw new ArgumentNullException("list"); } list.Add(new KeyValueSyntax(name, new StringValueSyntax(value))); } public static void Add(this SyntaxList<KeyValueSyntax> list, string name, int[] values) { if (list == null) { throw new ArgumentNullException("list"); } list.Add(new KeyValueSyntax(name, new ArraySyntax(values))); } public static void Add(this SyntaxList<KeyValueSyntax> list, string name, string[] values) { if (list == null) { throw new ArgumentNullException("list"); } list.Add(new KeyValueSyntax(name, new ArraySyntax(values))); } public static void Add(this SyntaxList<KeyValueSyntax> list, string name, DateTimeValueSyntax value) { if (list == null) { throw new ArgumentNullException("list"); } list.Add(new KeyValueSyntax(name, value)); } public static KeyValueSyntax AddTrailingComment(this KeyValueSyntax keyValue, string comment) { if (keyValue == null) { throw new ArgumentNullException("keyValue"); } if (keyValue.Value == null) { throw new InvalidOperationException("The Value must not be null on the KeyValueSyntax"); } keyValue.Value.AddTrailingWhitespace().AddTrailingComment(comment); return keyValue; } public static T AddLeadingWhitespace<T>(this T node) where T : SyntaxNode { return node.AddLeadingTrivia(SyntaxFactory.Whitespace()); } public static T AddTrailingWhitespace<T>(this T node) where T : SyntaxNode { return node.AddTrailingTrivia(SyntaxFactory.Whitespace()); } public static T AddLeadingTrivia<T>(this T node, SyntaxTrivia trivia) where T : SyntaxNode { if (node == null) { throw new ArgumentNullException("node"); } List<SyntaxTrivia> list = node.LeadingTrivia; if (list == null) { list = (node.LeadingTrivia = new List<SyntaxTrivia>()); } list.Add(trivia); return node; } public static T AddTrailingTrivia<T>(this T node, SyntaxTrivia trivia) where T : SyntaxNode { if (node == null) { throw new ArgumentNullException("node"); } List<SyntaxTrivia> list = node.TrailingTrivia; if (list == null) { list = (node.TrailingTrivia = new List<SyntaxTrivia>()); } list.Add(trivia); return node; } public static T AddLeadingComment<T>(this T node, string comment) where T : SyntaxNode { return node.AddLeadingTrivia(SyntaxFactory.Comment(comment)); } public static T AddTrailingComment<T>(this T node, string comment) where T : SyntaxNode { return node.AddTrailingTrivia(SyntaxFactory.Comment(comment)); } public static T AddLeadingTriviaNewLine<T>(this T node) where T : SyntaxNode { return node.AddLeadingTrivia(SyntaxFactory.NewLineTrivia()); } public static T AddTrailingTriviaNewLine<T>(this T node) where T : SyntaxNode { return node.AddTrailingTrivia(SyntaxFactory.NewLineTrivia()); } } public class SyntaxToken : SyntaxNode { public TokenKind TokenKind { get; set; } public string? Text { get; set; } public override int ChildrenCount => 0; public SyntaxToken() : base(SyntaxKind.Token) { } public SyntaxToken(TokenKind tokenKind, string? text) : this() { TokenKind = tokenKind; Text = text; } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override SyntaxNode? GetChildImpl(int index) { return null; } protected override string ToDebuggerDisplay() { return $"{base.ToDebuggerDisplay()}: {TokenKind} {((Text != null) ? TomlFormatHelper.ToString(Text, TomlPropertyDisplayKind.Default) : string.Empty)}"; } } public sealed class SyntaxTrivia : SyntaxNodeBase { public TokenKind Kind { get; set; } public string? Text { get; set; } public SyntaxTrivia() { } public SyntaxTrivia(TokenKind kind, string text) { if (!kind.IsTrivia()) { throw new ArgumentOutOfRangeException("kind", $"The kind `{kind}` is not a trivia"); } Kind = kind; Text = text ?? throw new ArgumentNullException("text"); } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + " " + ((Text != null) ? TomlFormatHelper.ToString(Text, TomlPropertyDisplayKind.Default) : string.Empty); } } internal class SyntaxValidator : SyntaxVisitor { private class ObjectPath : List<ObjectPathItem> { private int _hashCode; public void Add(string key) { _hashCode = (_hashCode * 397) ^ key.GetHashCode(); Add(new ObjectPathItem(key)); } public void Add(int index) { _hashCode = (_hashCode * 397) ^ index; Add(new ObjectPathItem(index)); } public ObjectPath Clone() { return (ObjectPath)MemberwiseClone(); } public override bool Equals(object? obj) { ObjectPath objectPath = obj as ObjectPath; if (objectPath?.Count != base.Count) { return false; } if (objectPath._hashCode != _hashCode) { return false; } for (int i = 0; i < base.Count; i++) { if (base[i] != objectPath[i]) { return false; } } return true; } public override int GetHashCode() { return _hashCode; } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < base.Count; i++) { if (i > 0) { stringBuilder.Append('.'); } stringBuilder.Append(base[i]); } return stringBuilder.ToString(); } } [DebuggerDisplay("{Node} - {Kind}")] private class ObjectPathValue { public readonly SyntaxNode Node; public readonly ObjectKind Kind; public readonly bool IsImplicit; public readonly bool FromDottedKeys; public int ArrayIndex; public ObjectPathValue(SyntaxNode node, ObjectKind kind, bool isImplicit, bool fromDottedKeys) { FromDottedKeys = fromDottedKeys; Node = node; Kind = kind; IsImplicit = isImplicit; } } private readonly struct ObjectPathItem : IEquatable<ObjectPathItem> { public readonly string? Key; public readonly int Index; public ObjectPathItem(string key) { this = default(ObjectPathItem); Key = key; } public ObjectPathItem(int index) { this = default(ObjectPathItem); Index = index; } public bool Equals(ObjectPathItem other) { if (string.Equals(Key, other.Key)) { return Index == other.Index; } return false; } public override bool Equals(object? obj) { if (obj == null) { return false; } if (obj is ObjectPathItem other) { return Equals(other); } return false; } public override int GetHashCode() { return (((Key != null) ? Key.GetHashCode() : 0) * 397) ^ Index; } public static bool operator ==(ObjectPathItem left, ObjectPathItem right) { return left.Equals(right); } public static bool operator !=(ObjectPathItem left, ObjectPathItem right) { return !left.Equals(right); } public override string ToString() { return Key ?? $"[{Index}]"; } } private enum KeySource { Table, KeyValue } private readonly DiagnosticsBag _diagnostics; private ObjectPath _currentPath; private readonly Dictionary<ObjectPath, ObjectPathValue> _maps; private int _currentArrayIndex; public SyntaxValidator(DiagnosticsBag diagnostics) { _diagnostics = diagnostics ?? throw new ArgumentNullException("diagnostics"); _currentPath = new ObjectPath(); _maps = new Dictionary<ObjectPath, ObjectPathValue>(); } public override void Visit(KeyValueSyntax keyValue) { ObjectPath currentPath = _currentPath.Clone(); if (keyValue.Key == null) { _diagnostics.Error(keyValue.Span, "A KeyValueSyntax must have a non null Key"); } else { if (!KeyNameToObjectPath(keyValue.Key, ObjectKind.Table, fromDottedKeys: true)) { return; } ValueSyntax value = keyValue.Value; ObjectKind kind; if (!(value is ArraySyntax)) { if (!(value is BooleanValueSyntax)) { if (value is DateTimeValueSyntax dateTimeValueSyntax) { kind = dateTimeValueSyntax.Kind switch { SyntaxKind.OffsetDateTimeByZ => ObjectKind.OffsetDateTimeByZ, SyntaxKind.OffsetDateTimeByNumber => ObjectKind.OffsetDateTimeByNumber, SyntaxKind.LocalDateTime => ObjectKind.LocalDateTime, SyntaxKind.LocalDate => ObjectKind.LocalDate, SyntaxKind.LocalTime => ObjectKind.LocalTime, _ => throw new NotSupportedException($"Unsupported datetime kind `{dateTimeValueSyntax.Kind}` for the key-value `{keyValue}`"), }; } else if (!(value is FloatValueSyntax)) { if (!(value is InlineTableSyntax)) { if (!(value is IntegerValueSyntax)) { if (!(value is StringValueSyntax)) { _diagnostics.Error(keyValue.Span, (keyValue.Value == null) ? "A KeyValueSyntax must have a non null Value" : $"Not supported type `{keyValue.Value.Kind}` for the value of a KeyValueSyntax"); return; } kind = ObjectKind.String; } else { kind = ObjectKind.Integer; } } else { kind = ObjectKind.InlineTable; } } else { kind = ObjectKind.Float; } } else { kind = ObjectKind.Boolean; } } else { kind = ObjectKind.Array; } AddObjectPath(keyValue, kind, isImplicit: false, fromDottedKeys: true); base.Visit(keyValue); _currentPath = currentPath; } } public override void Visit(StringValueSyntax stringValue) { if (stringValue.Token == null) { _diagnostics.Error(stringValue.Span, "A StringValueSyntax must have a non null Token"); } base.Visit(stringValue); } public override void Visit(IntegerValueSyntax integerValue) { if (integerValue.Token == null) { _diagnostics.Error(integerValue.Span, "A IntegerValueSyntax must have a non null Token"); } base.Visit(integerValue); } public override void Visit(BooleanValueSyntax boolValue) { if (boolValue.Token == null) { _diagnostics.Error(boolValue.Span, "A BooleanValueSyntax must have a non null Token"); } base.Visit(boolValue); } public override void Visit(FloatValueSyntax floatValue) { if (floatValue.Token == null) { _diagnostics.Error(floatValue.Span, "A FloatValueSyntax must have a non null Token"); } base.Visit(floatValue); } public override void Visit(TableSyntax table) { VerifyTable(table); ObjectPath currentPath = _currentPath.Clone(); if (table.Name != null && KeyNameToObjectPath(table.Name, ObjectKind.Table)) { AddObjectPath(table, ObjectKind.Table, isImplicit: false, fromDottedKeys: false); base.Visit(table); _currentPath = currentPath; } } public override void Visit(TableArraySyntax table) { VerifyTable(table); ObjectPath currentPath = _currentPath.Clone(); if (table.Name != null && KeyNameToObjectPath(table.Name, ObjectKind.TableArray)) { ObjectPathValue objectPathValue = AddObjectPath(table, ObjectKind.TableArray, isImplicit: false, fromDottedKeys: false); int currentArrayIndex = _currentArrayIndex; _currentArrayIndex = objectPathValue.ArrayIndex; base.Visit(table); objectPathValue.ArrayIndex++; _currentArrayIndex = currentArrayIndex; _currentPath = currentPath; } } public override void Visit(BareKeySyntax bareKey) { if (bareKey.Key == null) { _diagnostics.Error(bareKey.Span, "A BareKeySyntax must have a non null property Key"); } base.Visit(bareKey); } public override void Visit(KeySyntax key) { if (key.Key == null) { _diagnostics.Error(key.Span, "A KeySyntax must have a non null property Key"); } base.Visit(key); } public override void Visit(DateTimeValueSyntax dateTime) { if (dateTime.Token == null) { _diagnostics.Error(dateTime.Span, "A DateTimeValueSyntax must have a non null Token"); } base.Visit(dateTime); } private void VerifyTable(TableSyntaxBase table) { bool flag = table is TableArraySyntax; if (table.OpenBracket == null) { _diagnostics.Error(table.Span, string.Format("The table{0} must have an {1} `{2}`", flag ? " array" : string.Empty, table.OpenTokenKind, table.OpenTokenKind.ToText())); } if (table.CloseBracket == null) { _diagnostics.Error(table.Span, string.Format("The table{0} must have an {1} `{2}`", flag ? " array" : string.Empty, table.CloseTokenKind, table.CloseTokenKind.ToText())); } if (table.EndOfLineToken == null && table.Items.ChildrenCount > 0) { _diagnostics.Error(table.Span, "The table" + (flag ? " array" : string.Empty) + " must have a EndOfLine set after the open/closing brackets and before any elements"); } if (table.Name == null) { _diagnostics.Error(table.Span, "The table" + (flag ? " array" : string.Empty) + " must have a name"); } } private bool KeyNameToObjectPath(KeySyntax key, ObjectKind kind, bool fromDottedKeys = false) { if (key.Key == null) { _diagnostics.Error(key.Span, "The property KeySyntax.Key cannot be null"); } string stringFromBasic = GetStringFromBasic(key.Key); if (string.IsNullOrWhiteSpace(stringFromBasic)) { return false; } _currentPath.Add(stringFromBasic); SyntaxList<DottedKeyItemSyntax> dotKeys = key.DotKeys; for (int i = 0; i < dotKeys.ChildrenCount; i++) { AddObjectPath(key, kind, isImplicit: true, fromDottedKeys); string stringFromBasic2 = GetStringFromBasic(dotKeys.GetChild(i).Key); if (string.IsNullOrWhiteSpace(stringFromBasic2)) { return false; } _currentPath.Add(stringFromBasic2); } return true; } private ObjectPathValue AddObjectPath(SyntaxNode node, ObjectKind kind, bool isImplicit, bool fromDottedKeys) { ObjectPath objectPath = _currentPath.Clone(); if (kind == ObjectKind.TableArray && isImplicit) { kind = ObjectKind.Table; } if (_maps.TryGetValue(objectPath, out ObjectPathValue value)) { bool num = kind != ObjectKind.Table || (value.IsImplicit && (!value.FromDottedKeys || (fromDottedKeys && value.FromDottedKeys))) || (isImplicit && !fromDottedKeys); bool flag = (value.Kind == ObjectKind.TableArray && (kind == ObjectKind.TableArray || (kind == ObjectKind.Table && isImplicit))) || (value.Kind == ObjectKind.Table && kind == ObjectKind.Table); if (!(num && flag)) { _diagnostics.Error(node.Span, $"The key `{objectPath}` is already defined at {value.Node.Span.Start} with `{value.Node.ToString().TrimEnd('\r', '\n').ToPrintableString()}` and cannot be redefined"); } else if (value.Kind == ObjectKind.TableArray) { _currentPath.Add(value.ArrayIndex); } } else { value = new ObjectPathValue(node, kind, isImplicit, fromDottedKeys); _maps.Add(objectPath, value); } return value; } private string? GetStringFromBasic(BareKeyOrStringValueSyntax value) { if (value is BareKeySyntax bareKeySyntax) { return bareKeySyntax.Key?.Text; } return ((StringValueSyntax)value).Value; } public override void Visit(ArraySyntax array) { int currentArrayIndex = _currentArrayIndex; if (array.OpenBracket == null) { _diagnostics.Error(array.Span, "The array must have an OpenBracket `[`"); } else if (array.CloseBracket == null) { _diagnostics.Error(array.Span, "The array must have an CloseBracket `[`"); } SyntaxList<ArrayItemSyntax> items = array.Items; for (int i = 0; i < items.ChildrenCount; i++) { ArrayItemSyntax child = items.GetChild(i); ValueSyntax value = child.Value; if (i == 0) { _ = value.Kind; } if (i + 1 < items.ChildrenCount && child.Comma == null) { _diagnostics.Error(child.Span, $"The array item [{i}] must have a comma `,`"); } } base.Visit(array); _currentArrayIndex = currentArrayIndex; } public override void Visit(InlineTableItemSyntax inlineTableItem) { base.Visit(inlineTableItem); } public override void Visit(ArrayItemSyntax arrayItem) { _currentPath.Add(_currentArrayIndex); if (arrayItem.Value == null) { _diagnostics.Error(arrayItem.Span, $"The array item [{_currentArrayIndex}] must have a non null value"); } base.Visit(arrayItem); _currentArrayIndex++; } public override void Visit(DottedKeyItemSyntax dottedKeyItem) { base.Visit(dottedKeyItem); } public override void Visit(InlineTableSyntax inlineTable) { base.Visit(inlineTable); } } public abstract class SyntaxVisitor { public virtual void Visit(SyntaxList list) { DefaultVisit(list); } public virtual void Visit(DocumentSyntax document) { DefaultVisit(document); } public virtual void Visit(KeyValueSyntax keyValue) { DefaultVisit(keyValue); } public virtual void Visit(StringValueSyntax stringValue) { DefaultVisit(stringValue); } public virtual void Visit(IntegerValueSyntax integerValue) { DefaultVisit(integerValue); } public virtual void Visit(BooleanValueSyntax boolValue) { DefaultVisit(boolValue); } public virtual void Visit(FloatValueSyntax floatValue) { DefaultVisit(floatValue); } public virtual void Visit(TableSyntax table) { DefaultVisit(table); } public virtual void Visit(TableArraySyntax table) { DefaultVisit(table); } public virtual void Visit(SyntaxToken token) { DefaultVisit(token); } public virtual void Visit(SyntaxTrivia trivia) { } public virtual void Visit(BareKeySyntax bareKey) { DefaultVisit(bareKey); } public virtual void Visit(KeySyntax key) { DefaultVisit(key); } public virtual void Visit(DateTimeValueSyntax dateTime) { DefaultVisit(dateTime); } public virtual void Visit(ArraySyntax array) { DefaultVisit(array); } public virtual void Visit(InlineTableItemSyntax inlineTableItem) { DefaultVisit(inlineTableItem); } public virtual void Visit(ArrayItemSyntax arrayItem) { DefaultVisit(arrayItem); } public virtual void Visit(DottedKeyItemSyntax dottedKeyItem) { DefaultVisit(dottedKeyItem); } public virtual void Visit(InlineTableSyntax inlineTable) { DefaultVisit(inlineTable); } public virtual void DefaultVisit(SyntaxNode? node) { if (node != null) { VisitTrivias(node.LeadingTrivia); for (int i = 0; i < node.ChildrenCount; i++) { node.GetChild(i)?.Accept(this); } VisitTrivias(node.TrailingTrivia); } } private void VisitTrivias(List<SyntaxTrivia>? trivias) { if (trivias == null) { return; } foreach (SyntaxTrivia trivia in trivias) { trivia?.Accept(this); } } } public sealed class TableArraySyntax : TableSyntaxBase { internal override TokenKind OpenTokenKind => TokenKind.OpenBracketDouble; internal override TokenKind CloseTokenKind => TokenKind.CloseBracketDouble; public TableArraySyntax() : base(SyntaxKind.TableArray) { } public TableArraySyntax(string name) : this() { if (name == null) { throw new ArgumentNullException("name"); } base.Name = new KeySyntax(name); base.OpenBracket = SyntaxFactory.Token(TokenKind.OpenBracketDouble); base.CloseBracket = SyntaxFactory.Token(TokenKind.CloseBracketDouble); base.EndOfLineToken = SyntaxFactory.NewLine(); } public TableArraySyntax(KeySyntax name) : this() { base.Name = name ?? throw new ArgumentNullException("name"); base.OpenBracket = SyntaxFactory.Token(TokenKind.OpenBracketDouble); base.CloseBracket = SyntaxFactory.Token(TokenKind.CloseBracketDouble); base.EndOfLineToken = SyntaxFactory.NewLine(); } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + " [[" + ((base.Name != null) ? base.Name.ToString() : string.Empty) + "]]"; } } public sealed class TableSyntax : TableSyntaxBase { internal override TokenKind OpenTokenKind => TokenKind.OpenBracket; internal override TokenKind CloseTokenKind => TokenKind.CloseBracket; public TableSyntax() : base(SyntaxKind.Table) { } public TableSyntax(string name) : this() { if (name == null) { throw new ArgumentNullException("name"); } base.OpenBracket = SyntaxFactory.Token(TokenKind.OpenBracket); base.Name = new KeySyntax(name); base.CloseBracket = SyntaxFactory.Token(TokenKind.CloseBracket); base.EndOfLineToken = SyntaxFactory.NewLine(); } public TableSyntax(KeySyntax name) : this() { base.Name = name ?? throw new ArgumentNullException("name"); base.OpenBracket = SyntaxFactory.Token(TokenKind.OpenBracket); base.CloseBracket = SyntaxFactory.Token(TokenKind.CloseBracket); base.EndOfLineToken = SyntaxFactory.NewLine(); } public override void Accept(SyntaxVisitor visitor) { visitor.Visit(this); } protected override string ToDebuggerDisplay() { return base.ToDebuggerDisplay() + " [" + ((base.Name != null) ? base.Name.ToString() : string.Empty) + "]"; } } public abstract class TableSyntaxBase : SyntaxNode { private SyntaxToken? _openBracket; private KeySyntax? _name; private SyntaxToken? _closeBracket; private SyntaxToken? _endOfLineToken; public SyntaxToken? OpenBracket { get { return _openBracket; } set { ParentToThis(ref _openBracket, value, OpenTokenKind); } } public KeySyntax? Name { get { return _name; } set { ParentToThis(ref _name, value); } } public SyntaxToken? CloseBracket { get { return _closeBracket; } set { ParentToThis(ref _closeBracket, value, CloseTokenKind); } } public SyntaxToken? EndOfLineToken { get { return _endOfLineToken; } set { ParentToThis(ref _endOfLineToken, value, TokenKind.NewLine, TokenKind.Eof); } } public SyntaxList<KeyValueSyntax> Items { get; } public override int ChildrenCount => 5; internal abstract TokenKind OpenTokenKind { get; } internal abstract TokenKind CloseTokenKind { get; } internal TableSyntaxBase(SyntaxKind kind) : base(kind) { Items = new SyntaxList<KeyValueSyntax> { Parent = this }; } protected override SyntaxNode? GetChildImpl(int index) { return index switch { 0 => OpenBracket, 1 => Name, 2 => CloseBracket, 3 => EndOfLineToken, _ => Items, }; } } public struct TextPosition : IEquatable<TextPosition> { public static readonly TextPosition Eof = new TextPosition(-1, -1, -1); public int Offset { get; set; } public int Column { get; set; } public int Line { get; set; } public TextPosition(int offset, int line, int column) { Offset = offset; Column = column; Line = line; } public override string ToString() { return $"({Line + 1},{Column + 1})"; } public bool Equals(TextPosition other) { if (Offset == other.Offset && Column == other.Column) { return Line == other.Line; } return false; } public override bool Equals(object? obj) { if (obj == null) { return false; } if (obj is TextPosition) { return Equals((TextPosition)obj); } return false; } public override int GetHashCode() { return Offset; } public static bool operator ==(TextPosition left, TextPosition right) { return left.Equals(right); } public static bool operator !=(TextPosition left, TextPosition right) { return !left.Equals(right); } } public enum TokenKind { Invalid, Eof, Whitespaces, NewLine, Comment, OffsetDateTimeByZ, OffsetDateTimeByNumber, LocalDateTime, LocalDate, LocalTime, Integer, IntegerHexa, IntegerOctal, IntegerBinary, Float, String, StringMulti, StringLiteral, StringLiteralMulti, Comma, Dot, Equal, OpenBracket, OpenBracketDouble, CloseBracket, CloseBracketDouble, OpenBrace, CloseBrace, True, False, Infinite, PositiveInfinite, NegativeInfinite, Nan, PositiveNan, NegativeNan, BasicKey } public static class TokenKindExtensions { public static bool IsHidden(this TokenKind tokenKind, bool hideNewLine = true) { if (tokenKind != TokenKind.Whitespaces && tokenKind != TokenKind.Comment) { return tokenKind == TokenKind.NewLine && hideNewLine; } return true; } public static string? ToText(this TokenKind kind) { return kind switch { TokenKind.Comma => ",", TokenKind.Dot => ".", TokenKind.Equal => "=", TokenKind.OpenBracket => "[", TokenKind.OpenBracketDouble => "[[", TokenKind.CloseBracket => "]", TokenKind.CloseBracketDouble => "]]", TokenKind.OpenBrace => "{", TokenKind.CloseBrace => "}", TokenKind.True => "true", TokenKind.False => "false", TokenKind.Infinite => "inf", TokenKind.PositiveInfinite => "+inf", TokenKind.NegativeInfinite => "-inf", TokenKind.Nan => "nan", TokenKind.PositiveNan => "+nan", TokenKind.NegativeNan => "-nan", _ => null, }; } public static bool IsFloat(this TokenKind kind) { if (kind == TokenKind.Float || (uint)(kind - 30) <= 5u) { return true; } return false; } public static bool IsInteger(this TokenKind kind) { if ((uint)(kind - 10) <= 3u) { return true; } return false; } public static bool IsDateTime(this TokenKind kind) { if ((uint)(kind - 5) <= 4u) { return true; } return false; } public static bool IsString(this TokenKind kind) { if ((uint)(kind - 15) <= 3u) { return true; } return false; } public static bool IsTrivia(this TokenKind kind) { if ((uint)(kind - 2) <= 2u) { return true; } return false; } public static bool IsToken(this TokenKind kind) { if (kind == TokenKind.NewLine || (uint)(kind - 19) <= 16u) { return true; } return false; } } public abstract class ValueSyntax : SyntaxNode { internal ValueSyntax(SyntaxKind kind) : base(kind) { } } } namespace Tomlyn.Parsing { internal interface ITokenProvider<out TSourceView> where TSourceView : ISourceView { bool HasErrors { get; } TSourceView Source { get; } LexerState State { get; set; } SyntaxTokenValue Token { get; } IEnumerable<DiagnosticMessage> Errors { get; } bool MoveNext(); } internal class Lexer<TSourceView, TCharReader> : ITokenProvider<TSourceView> where TSourceView : struct, ISourceView<TCharReader> where TCharReader : struct, CharacterIterator { private SyntaxTokenValue _token; private List<DiagnosticMessage>? _errors; private TCharReader _reader; private const int Eof = -1; private TSourceView _sourceView; private readonly StringBuilder _textBuilder; private readonly List<char32> _currentIdentifierChars; private LexerInternalState? _preview1; private LexerInternalState _current; public TSourceView Source => _sourceView; public bool HasErrors { get { if (_errors != null) { return _errors.Count > 0; } return false; } } public IEnumerable<DiagnosticMessage> Errors { get { IEnumerable<DiagnosticMessage> errors = _errors; return errors ?? Enumerable.Empty<DiagnosticMessage>(); } } public SyntaxTokenValue Token => _token; public LexerState State { get; set; } private TextPosition _position => _current.Position; private char32 _c => _current.CurrentChar; public Lexer(TSourceView sourceView) { _sourceView = sourceView; _reader = sourceView.GetIterator(); _currentIdentifierChars = new List<char32>(); _textBuilder = new StringBuilder(); Reset(); } public bool MoveNext() { if (_token.Kind == TokenKind.Eof) { return false; } if (State == LexerState.Key) { NextTokenForKey(); } else { NextTokenForValue(); } return true; } private void NextTokenForKey() { TextPosition position = _position; switch (_c) { case 10L: _token = new SyntaxTokenValue(TokenKind.NewLine, position, position); NextChar(); return; case 13L: NextChar(); if ((int)_c == 10) { _token = new SyntaxTokenValue(TokenKind.NewLine, position, _position); NextChar(); } else { AddError("Invalid \\r not followed by \\n", position, position); _token = new SyntaxTokenValue(TokenKind.NewLine, position, position); } return; case 35L: NextChar(); ReadComment(position); return; case 46L: NextChar(); _token = new SyntaxTokenValue(TokenKind.Dot, position, position); return; case 61L: NextChar(); _token = new SyntaxTokenValue(TokenKind.Equal, position, position); return; case 123L: _token = new SyntaxTokenValue(TokenKind.OpenBrace, _position, _position); NextChar(); return; case 125L: _token = new SyntaxTokenValue(TokenKind.CloseBrace, _position, _position); NextChar(); return; case 91L: NextChar(); if ((int)_c == 91) { _token = new SyntaxTokenValue(TokenKind.OpenBracketDouble, position, _position); NextChar(); } else { _token = new SyntaxTokenValue(TokenKind.OpenBracket, position, position); } return; case 93L: NextChar(); if ((int)_c == 93) { _token = new SyntaxTokenValue(TokenKind.CloseBracketDouble, position, _position); NextChar(); } else { _token = new SyntaxTokenValue(TokenKind.CloseBracket, position, position); } return; case 34L: ReadString(position, allowMultiline: false); return; case 39L: ReadStringLiteral(position, allowMultiline: false); return; case -1L: _token = new SyntaxTokenValue(TokenKind.Eof, _position, _position); return; } if (!ConsumeWhitespace()) { if (CharHelper.IsKeyStart(_c)) { ReadKey(); return; } _token = new SyntaxTokenValue(TokenKind.Invalid, _position, _position); NextChar(); } } private void NextTokenForValue() { TextPosition position = _position; switch (_c) { case 10L: _token = new SyntaxTokenValue(TokenKind.NewLine, position, _position); NextChar(); return; case 13L: NextChar(); if ((int)_c == 10) { _token = new SyntaxTokenValue(TokenKind.NewLine, position, _position); NextChar(); } else { _token = new SyntaxTokenValue(TokenKind.NewLine, position, position); } return; case 35L: NextChar(); ReadComment(position); return; case 44L: _token = new SyntaxTokenValue(TokenKind.Comma, position, position); NextChar(); return; case 91L: NextChar(); _token = new SyntaxTokenValue(TokenKind.OpenBracket, position, position); return; case 93L: NextChar(); _token = new SyntaxTokenValue(TokenKind.CloseBracket, position, position); return; case 123L: _token = new SyntaxTokenValue(TokenKind.OpenBrace, _position, _position); NextChar(); return; case 125L: _token = new SyntaxTokenValue(TokenKind.CloseBrace, _position, _position); NextChar(); return; case 34L: ReadString(position, allowMultiline: true); return; case 39L: ReadStringLiteral(position, allowMultiline: true); return; case -1L: _token = new SyntaxTokenValue(TokenKind.Eof, _position, _position); return; } if (!ConsumeWhitespace()) { if ((int)_c == 43 || (int)_c == 45 || CharHelper.IsIdentifierStart(_c)) { ReadSpecialToken(); return; } if (CharHelper.IsDigit(_c)) { ReadNumberOrDate(); return; } _token = new SyntaxTokenValue(TokenKind.Invalid, _position, _position); NextChar(); } } private bool ConsumeWhitespace() { TextPosition position = _position; TextPosition position2 = _position; while (CharHelper.IsWhiteSpace(_c)) { position2 = _position; NextChar(); } if (position != _position) { _token = new SyntaxTokenValue(TokenKind.Whitespaces, position, position2); return true; } return false; } private void ReadKey() { TextPosition position = _position; TextPosition position2 = _position; while (CharHelper.IsKeyContinue(_c)) { position2 = _position; NextChar(); } _token = new SyntaxTokenValue(TokenKind.BasicKey, position, position2); } private void ReadSpecialToken() { TextPosition position = _position; TextPosition position2 = _position; _currentIdentifierChars.Clear(); char32 c = _c; _currentIdentifierChars.Add(_c); NextChar(); if (((int)c == 43 || (int)c == 45) && CharHelper.IsDigit(_c)) { _currentIdentifierChars.Clear(); ReadNumberOrDate(c, position); return; } while (CharHelper.IsIdentifierContinue(_c)) { _currentIdentifierChars.Add(_c); position2 = _position; NextChar(); } if (MatchCurrentIdentifier("true")) { _token = new SyntaxTokenValue(TokenKind.True, position, position2, BoxedValues.True); } else if (MatchCurrentIdentifier("false")) { _token = new SyntaxTokenValue(TokenKind.False, position, position2, BoxedValues.False); } else if (MatchCurrentIdentifier("inf")) { _token = new SyntaxTokenValue(TokenKind.Infinite, position, position2, BoxedValues.FloatPositiveInfinity); } else if (MatchCurrentIdentifier("+inf")) { _token = new SyntaxTokenValue(TokenKind.PositiveInfinite, position, position2, BoxedValues.FloatPositiveInfinity); } else if (MatchCurrentIdentifier("-inf")) { _token = new SyntaxTokenValue(TokenKind.NegativeInfinite, position, position2, BoxedValues.FloatNegativeInfinity); } else if (MatchCurrentIdentifier("nan")) { _token = new SyntaxTokenValue(TokenKind.Nan, position, position2, BoxedValues.FloatNan); } else if (MatchCurrentIdentifier("+nan")) { _token = new SyntaxTokenValue(TokenKind.PositiveNan, position, position2, BoxedValues.FloatPositiveNaN); } else if (MatchCurrentIdentifier("-nan")) { _token = new SyntaxTokenValue(TokenKind.NegativeNan, position, position2, BoxedValues.FloatNegativeNaN); } else { _token = new SyntaxTokenValue(TokenKind.Invalid, position, position2); } _currentIdentifierChars.Clear(); } private bool MatchCurrentIdentifier(string text) { if (_currentIdentifierChars.Count != text.Length) { return false; } for (int i = 0; i < text.Length; i++) { if ((int)_currentIdentifierChars[i] != text[i]) { return false; } } return true; } private void ReadNumberOrDate(char32? signPrefix = null, TextPosition? signPrefixPos = null) { TextPosition textPosition = signPrefixPos ?? _position; TextPosition end = _position; bool flag = false; TextPosition position = _position; bool hasValue = signPrefix.HasValue; bool flag2 = (int)_c == 48; _textBuilder.Length = 0; if (hasValue) { _textBuilder.AppendUtf32(signPrefix.Value); } if (flag2) { NextChar(); if (!hasValue && ((int)_c == 120 || (int)_c == 88 || (int)_c == 111 || (int)_c == 79 || (int)_c == 98 || (int)_c == 66)) { string text; string text2; string text3; Func<char32, bool> func; Func<char32, int> func2; int num; TokenKind kind; if ((int)_c == 120 || (int)_c == 88) { text = "hexadecimal"; text2 = "[0-9a-zA-Z]"; text3 = "0x"; func = CharHelper.IsHexFunc; func2 = CharHelper.HexToDecFunc; num = 4; kind = TokenKind.IntegerHexa; if ((int)_c == 88) { AddError("Invalid capital X for hexadecimal. Use `x` instead.", _position, _position); } } else if ((int)_c == 111 || (int)_c == 79) { text = "octal"; text2 = "[0-7]"; text3 = "0o"; func = CharHelper.IsOctalFunc; func2 = CharHelper.OctalToDecFunc; num = 3; kind = TokenKind.IntegerOctal; if ((int)_c == 79) { AddError("Invalid capital O for octal. Use `o` instead.", _position, _position); } } else { text = "binary"; text2 = "0 or 1"; text3 = "0b"; func = CharHelper.IsBinaryFunc; func2 = CharHelper.BinaryToDecFunc; num = 1; kind = TokenKind.IntegerBinary; if ((int)_c == 66) { AddError("Invalid capital B for binary. Use `b` instead.", _position, _position); } } end = _position; NextChar(); int num2 = 64 / num; int num3 = num2; bool flag3 = false; bool flag4 = false; ulong num4 = 0uL; while (true) { bool flag5 = false; if ((int)_c != 95 && !(flag5 = func(_c))) { break; } bool flag6 = (int)_c != 95; if (!flag4 && !flag6) { AddError("An underscore must be surrounded by at least one " + text + " digit on each side", textPosition, textPosition); } else if (flag6) { num4 = (num4 << num) + (ulong)func2(_c); num3--; if (num3 == -1) { AddError($"Invalid size of {text} integer. Expecting less than or equal {num2} {text} digits", textPosition, textPosition); } } flag4 = flag6; if (flag5) { flag3 = true; } end = _position; NextChar(); } if (!flag3) { AddError("Invalid " + text + " integer. Expecting at least one " + text2 + " after " + text3, textPosition, textPosition); _token = new SyntaxTokenValue(TokenKind.Invalid, textPosition, end); } else if (!flag4) { AddError("Invalid " + text + " integer. Expecting a " + text2 + " after the last character", textPosition, textPosition); _token = new SyntaxTokenValue(TokenKind.Invalid, textPosition, end); } else { _token = new SyntaxTokenValue(kind, textPosition, end, (long)num4); } return; } _textBuilder.Append('0'); } TextPosition position2 = _position; bool flag7 = false; bool flag8 = false; if (flag2) { int num5 = 0; flag8 = true; while ((int)_c == 48 || (int)_c == 95) { flag8 = (int)_c == 48; if (flag8) { _textBuilder.Append((char)(int)_c); num5++; } end = _position; NextChar(); } flag7 = num5 > 0; } ReadDigits(ref end, flag8); if ((int)_c == 45 || (int)_c == 58) { while (CharHelper.IsDateTime(_c)) { _textBuilder.AppendUtf32(_c); end = _position; NextChar(); } if (CharHelper.IsWhiteSpace(_c) && CharHelper.IsDateTime(PeekChar())) { _textBuilder.AppendUtf32(_c); NextChar(); while (CharHelper.IsDateTime(_c)) { _textBuilder.AppendUtf32(_c); end = _position; NextChar(); } } string text4 = _textBuilder.ToString(); if (hasValue) { AddError($"Invalid prefix `{signPrefix.Value}` for the following offset/local date/time `{text4}`", textPosition, end); text4 = text4.Substring(1); } DateTime result; if (DateTimeRFC3339.TryParseOffsetDateTime(text4, out var time)) { TokenKind kind2 = ((time.Kind == TomlDateTimeKind.OffsetDateTimeByZ) ? TokenKind.OffsetDateTimeByZ : TokenKind.OffsetDateTimeByNumber); _token = new SyntaxTokenValue(kind2, textPosition, end, time); } else if (DateTimeRFC3339.TryParseLocalDateTime(text4, out time)) { _token = new SyntaxTokenValue(TokenKind.LocalDateTime, textPosition, end, time); } else if (DateTimeRFC3339.TryParseLocalDate(text4, out time)) { _token = new SyntaxTokenValue(TokenKind.LocalDate, textPosition, end, time); } else if (DateTimeRFC3339.TryParseLocalTime(text4, out time)) { _token = new SyntaxTokenValue(TokenKind.LocalTime, textPosition, end, time); } else if (DateTime.TryParse(text4, CultureInfo.InvariantCulture, DateTimeStyles.AllowInnerWhite, out result)) { _token = new SyntaxTokenValue(value: new TomlDateTime(result, 0, TomlDateTimeKind.LocalDateTime), kind: TokenKind.LocalDateTime, start: textPosition, end: end); AddError("Invalid format of date time/offset `" + text4 + "` not following RFC3339", textPosition, end); } else { _token = new SyntaxTokenValue(value: new TomlDateTime(DateTimeOffset.MinValue, 0, TomlDateTimeKind.LocalDateTime), kind: TokenKind.LocalDateTime, start: textPosition, end: end); AddError("Unable to parse the date time/offset `" + text4 + "`", textPosition, end); } return; } if (flag7) { AddError("Multiple leading 0 are not allowed", position2, position2); } if ((int)_c == 46) { _textBuilder.Append('.'); end = _position; NextChar(); if (!CharHelper.IsDigit(_c)) { AddError("Expecting at least one digit after the float dot .", _position, _position); _token = new SyntaxTokenValue(TokenKind.Invalid, textPosition, end); return; } flag = true; ReadDigits(ref end, isPreviousDigit: false); } if ((int)_c == 101 || (int)_c == 69) { flag = true; _textBuilder.AppendUtf32(_c); end = _position; NextChar(); if ((int)_c == 43 || (int)_c == 45) { _textBuilder.AppendUtf32(_c); end = _position; NextChar(); } if (!CharHelper.IsDigit(_c)) { AddError("Expecting at least one digit after the exponent", _position, _position); _token = new SyntaxTokenValue(TokenKind.Invalid, textPosition, end); return; } ReadDigits(ref end, isPreviousDigit: false); } string text5 = _textBuilder.ToString(); object value3; if (flag) { if (!double.TryParse(text5, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { AddError("Unable to parse floating point `" + text5 + "`", textPosition, end); } if ((int)result2 != 0 && flag2) { AddError("Unexpected leading zero (`0`) for float `" + text5 + "`", position, position); } value3 = ((result2 == 0.0) ? BoxedValues.FloatZero : ((result2 == 1.0) ? BoxedValues.FloatOne : ((object)result2))); } else { if (!long.TryParse(text5, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3)) { if (!ulong.TryParse(text5, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result4)) { AddError("Unable to parse integer `" + text5 + "`", textPosition, end); } else { result3 = (long)result4; } } if (flag2 &