Beispiel #1
0
        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);
                    }
                }
            }
        }
Beispiel #2
0
        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>();
        }
Beispiel #3
0
        /// <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));
        }
Beispiel #4
0
 /// <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)));
 }
Beispiel #5
0
        /// <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));
        }
Beispiel #6
0
 public bool SendDiscoveryResponse(byte[] data, NetEndPoint remoteEndPoint)
 {
     return(SendDiscoveryResponse(data, 0, data.Length, remoteEndPoint));
 }
Beispiel #7
0
 public bool SendDiscoveryResponse(NetDataWriter writer, NetEndPoint remoteEndPoint)
 {
     return(SendDiscoveryResponse(writer.Data, 0, writer.Length, remoteEndPoint));
 }
Beispiel #8
0
 /// <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));
 }
Beispiel #9
0
 /// <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));
 }