private void DataReceived(byte[] reusableBuffer, int count, NetEndPoint remoteEndPoint) { #if STATS_ENABLED Statistics.PacketsReceived++; Statistics.BytesReceived += (uint)count; #endif //Try read packet NetPacket packet = NetPacketPool.GetAndRead(reusableBuffer, 0, count); if (packet == null) { NetUtils.DebugWriteError("[NM] DataReceived: bad!"); return; } //Check unconnected switch (packet.Property) { case PacketProperty.DiscoveryRequest: if (DiscoveryEnabled) { var netEvent = CreateEvent(NetEventType.DiscoveryRequest); netEvent.RemoteEndPoint = remoteEndPoint; netEvent.DataReader.SetSource(packet); EnqueueEvent(netEvent); packet.Recycle(); } return; case PacketProperty.DiscoveryResponse: { var netEvent = CreateEvent(NetEventType.DiscoveryResponse); netEvent.RemoteEndPoint = remoteEndPoint; netEvent.DataReader.SetSource(packet); EnqueueEvent(netEvent); packet.Recycle(); } return; case PacketProperty.UnconnectedMessage: if (UnconnectedMessagesEnabled) { var netEvent = CreateEvent(NetEventType.ReceiveUnconnected); netEvent.RemoteEndPoint = remoteEndPoint; netEvent.DataReader.SetSource(packet); EnqueueEvent(netEvent); packet.Recycle(); } return; case PacketProperty.NatIntroduction: case PacketProperty.NatIntroductionRequest: case PacketProperty.NatPunchMessage: { if (NatPunchEnabled) { NatPunchModule.ProcessMessage(remoteEndPoint, packet); } packet.Recycle(); return; } } //Check normal packets NetPeer netPeer; //lock (_peers) { _peers.TryGetValue(remoteEndPoint, out netPeer); } if (netPeer != null && netPeer.ConnectionState != ConnectionState.Disconnected) { switch (packet.Property) { case PacketProperty.Disconnect: if (netPeer.ConnectionState == ConnectionState.InProgress || netPeer.ConnectionState == ConnectionState.Connected) { if (BitConverter.ToInt64(packet.RawData, 0) == netPeer.ConnectId) { var netEvent = CreateEvent(NetEventType.Disconnect); netEvent.Peer = netPeer; netEvent.DataReader.SetSource(packet.RawData, sizeof(long), packet.GetDataSize() - sizeof(long)); netEvent.DisconnectReason = DisconnectReason.RemoteConnectionClose; EnqueueEvent(netEvent); } } break; case PacketProperty.ShutdownOk: if (netPeer.ConnectionState == ConnectionState.ShutdownRequested) { netPeer.ProcessPacket(packet); NetUtils.DebugWriteForce(ConsoleColor.Cyan, "[NM] ShutdownOK!"); } break; case PacketProperty.ConnectAccept: if (netPeer.ProcessConnectAccept(packet)) { var connectEvent = CreateEvent(NetEventType.Connect); connectEvent.Peer = netPeer; EnqueueEvent(connectEvent); } break; default: netPeer.ProcessPacket(packet); break; } packet.Recycle(); return; } //Unacked shutdown if (packet.Property == PacketProperty.Disconnect) { byte[] data = { (byte)PacketProperty.ShutdownOk }; SendRaw(data, 0, 1, remoteEndPoint); return; } if (packet.Property == PacketProperty.ConnectRequest && packet.Size >= 12) { lock (_connectingPeers) { if (_connectingPeers.Contains(remoteEndPoint)) { return; } } int peersCount = GetPeersCount(ConnectionState.Connected | ConnectionState.InProgress); if (peersCount < _maxConnections) { int protoId = BitConverter.ToInt32(packet.RawData, 0); if (protoId != NetConstants.ProtocolId) { NetUtils.DebugWrite(ConsoleColor.Cyan, "[NM] Peer connect reject. Invalid protocol ID: " + protoId); return; } //Getting new id for peer long connectionId = BitConverter.ToInt64(packet.RawData, sizeof(int)); // Read data and create request var reader = new NetDataReader(null, 0, 0); if (packet.GetDataSize() > sizeof(int) + sizeof(long)) { reader.SetSource(packet.RawData, sizeof(int) + sizeof(long), packet.GetDataSize() - sizeof(int) - sizeof(long)); } lock (_connectingPeers) { _connectingPeers.Add(remoteEndPoint); } var netEvent = CreateEvent(NetEventType.ConnectionRequest); netEvent.ConnectionRequest = new ConnectionRequest(connectionId, remoteEndPoint, reader, OnConnectionSolved); if (String.IsNullOrEmpty(PasscodeKey) == true) { EnqueueEvent(netEvent); } else { netEvent.ConnectionRequest.AcceptIfKey(PasscodeKey); OnConnectionSolved(netEvent.ConnectionRequest); } } } }
private NetPeer(NetManager netManager, NetEndPoint remoteEndPoint) { Statistics = new NetStatistics(); _packetPool = netManager.NetPacketPool; _netManager = netManager; _remoteEndPoint = remoteEndPoint; _mergedPackets = new FastQueue <NetPacket>(NetConstants.DefaultWindowSize); if (netManager.MtuStartIdx >= 0 && netManager.MtuStartIdx < NetConstants.PossibleMtu.Length) { _mtuIdx = netManager.MtuStartIdx; _mtu = NetConstants.PossibleMtu[_mtuIdx]; _finishMtu = true; } _avgRtt = 0; _rtt = 0; _pingSendTimer = 0; _pingMustSend = false; if (NetManager.EnableReliableOrderedChannel) { _reliableOrderedChannels = new ReliableChannel[NetConstants.MultiChannelCount]; } if (NetManager.EnableReliableUnorderedChannel) { _reliableUnorderedChannels = new ReliableChannel[NetConstants.MultiChannelCount]; } if (NetManager.EnableSequencedChannel) { _sequencedChannels = new SequencedChannel[NetConstants.MultiChannelCount]; } if (NetManager.EnableSimpleChannel) { _simpleChannels = new SimpleChannel[NetConstants.MultiChannelCount]; } //_reliableSequencedChannels = new ReliableSequencedChannel[NetConstants.MultiChannelCount]; // Initialise default channel for (int i = 0; i < NetConstants.MultiChannelCount; ++i) { if (NetManager.EnableReliableOrderedChannel) { _reliableOrderedChannels[i] = new ReliableChannel(this, true, i); } if (NetManager.EnableReliableUnorderedChannel) { _reliableUnorderedChannels[i] = new ReliableChannel(this, false, i); } if (NetManager.EnableSequencedChannel) { _sequencedChannels[i] = new SequencedChannel(this, i); } if (NetManager.EnableSimpleChannel) { _simpleChannels[i] = new SimpleChannel(this, i); } //_reliableSequencedChannels[i] = new ReliableSequencedChannel(this, i); } _holdedFragments = new Dictionary <ushort, IncomingFragments>(); }
/// <summary> /// Connect to remote host /// </summary> /// <param name="address">Server IP or hostname</param> /// <param name="port">Server Port</param> /// <param name="connectionData">Additional data for remote peer</param> /// <returns>Null if connections limit reached, New NetPeer if new connection, Old NetPeer if already connected</returns> /// <exception cref="InvalidOperationException">Manager is not running. Call <see cref="Start()"/></exception> public NetPeer Connect(string address, int port, NetDataWriter connectionData) { var ep = new NetEndPoint(address, port); return(Connect(ep, connectionData)); }
/// <summary> /// Connect to remote host /// </summary> /// <param name="target">Server end point (ip and port)</param> /// <param name="key">Connection key</param> /// <returns>Null if connections limit reached, New NetPeer if new connection, Old NetPeer if already connected</returns> /// <exception cref="InvalidOperationException">Manager is not running. Call <see cref="Start()"/></exception> public NetPeer Connect(NetEndPoint target, string key) { return(Connect(target, NetDataWriter.FromString(key))); }
/// <summary> /// Connect to remote host /// </summary> /// <param name="address">Server IP or hostname</param> /// <param name="port">Server Port</param> /// <param name="key">Connection key</param> /// <returns>Null if connections limit reached, New NetPeer if new connection, Old NetPeer if already connected</returns> /// <exception cref="InvalidOperationException">Manager is not running. Call <see cref="Start()"/></exception> public NetPeer Connect(string address, int port, string key) { var ep = new NetEndPoint(address, port); return(Connect(ep, key)); }
public bool SendDiscoveryResponse(byte[] data, NetEndPoint remoteEndPoint) { return(SendDiscoveryResponse(data, 0, data.Length, remoteEndPoint)); }
public bool SendDiscoveryResponse(NetDataWriter writer, NetEndPoint remoteEndPoint) { return(SendDiscoveryResponse(writer.Data, 0, writer.Length, remoteEndPoint)); }
/// <summary> /// Send message without connection /// </summary> /// <param name="writer">Data serializer</param> /// <param name="remoteEndPoint">Packet destination</param> /// <returns>Operation result</returns> public bool SendUnconnectedMessage(NetDataWriter writer, NetEndPoint remoteEndPoint) { return(SendUnconnectedMessage(writer.Data, 0, writer.Length, remoteEndPoint)); }
/// <summary> /// Send message without connection /// </summary> /// <param name="message">Raw data</param> /// <param name="remoteEndPoint">Packet destination</param> /// <returns>Operation result</returns> public bool SendUnconnectedMessage(byte[] message, NetEndPoint remoteEndPoint) { return(SendUnconnectedMessage(message, 0, message.Length, remoteEndPoint)); }