//"Connect to" constructor internal NetPeer(NetManager netManager, IPEndPoint remoteEndPoint, byte connectNum, NetDataWriter connectData) : this(netManager, remoteEndPoint) { Initialize(); _connectId = DateTime.UtcNow.Ticks; _connectionState = ConnectionState.InProgress; ConnectionNum = connectNum; //Make initial packet _connectRequestPacket = NetConnectRequestPacket.Make(connectData, _connectId); _connectRequestPacket.ConnectionNumber = connectNum; //Send request _netManager.SendRaw(_connectRequestPacket, _remoteEndPoint); NetUtils.DebugWrite(ConsoleColor.Cyan, "[CC] ConnectId: {0}, ConnectNum: {1}", _connectId, connectNum); }
internal ConnectRequestResult ProcessConnectRequest(NetConnectRequestPacket connRequest) { //current or new request switch (_connectionState) { //P2P case or just ID update case ConnectionState.InProgress: case ConnectionState.Incoming: _connectionState = ConnectionState.Incoming; //change connect id if newer if (connRequest.ConnectionId >= _connectId) { //Change connect id _connectId = connRequest.ConnectionId; ConnectionNum = connRequest.ConnectionNumber; } return(_connectionState == ConnectionState.InProgress ? ConnectRequestResult.P2PConnection : ConnectRequestResult.None); case ConnectionState.Connected: //Old connect request if (connRequest.ConnectionId == _connectId) { //just reply accept _netManager.SendRaw(_connectAcceptPacket, _remoteEndPoint); } //New connect request else if (connRequest.ConnectionId > _connectId) { return(ConnectRequestResult.Reconnection); } break; case ConnectionState.Disconnected: case ConnectionState.ShutdownRequested: if (connRequest.ConnectionId >= _connectId) { return(ConnectRequestResult.NewConnection); } break; } return(ConnectRequestResult.None); }
private void DataReceived(byte[] reusableBuffer, int count, IPEndPoint remoteEndPoint) { #if STATS_ENABLED Statistics.PacketsReceived++; Statistics.BytesReceived += (uint)count; #endif //Try read packet NetPacket packet = NetPacketPool.GetPacket(count, false); if (!packet.FromBytes(reusableBuffer, 0, count)) { NetPacketPool.Recycle(packet); NetUtils.DebugWriteError("[NM] DataReceived: bad!"); return; } //get peer //Check normal packets NetPeer netPeer; //old packets protection NetEvent netEvent; bool peerFound = _peers.TryGetValue(remoteEndPoint, out netPeer); //Check unconnected switch (packet.Property) { case PacketProperty.DiscoveryRequest: if (!DiscoveryEnabled) { break; } netEvent = CreateEvent(NetEventType.DiscoveryRequest); netEvent.RemoteEndPoint = remoteEndPoint; netEvent.DataReader.SetSource(packet.RawData, NetConstants.HeaderSize, count); EnqueueEvent(netEvent); break; case PacketProperty.DiscoveryResponse: netEvent = CreateEvent(NetEventType.DiscoveryResponse); netEvent.RemoteEndPoint = remoteEndPoint; netEvent.DataReader.SetSource(packet.RawData, NetConstants.HeaderSize, count); EnqueueEvent(netEvent); break; case PacketProperty.UnconnectedMessage: if (!UnconnectedMessagesEnabled) { break; } netEvent = CreateEvent(NetEventType.ReceiveUnconnected); netEvent.RemoteEndPoint = remoteEndPoint; netEvent.DataReader.SetSource(packet.RawData, NetConstants.HeaderSize, count); EnqueueEvent(netEvent); break; case PacketProperty.NatIntroduction: case PacketProperty.NatIntroductionRequest: case PacketProperty.NatPunchMessage: if (NatPunchEnabled) { NatPunchModule.ProcessMessage(remoteEndPoint, packet); } break; case PacketProperty.Disconnect: if (peerFound) { var disconnectResult = netPeer.ProcessDisconnect(packet); if (disconnectResult == DisconnectResult.None) { NetPacketPool.Recycle(packet); return; } if (disconnectResult == DisconnectResult.Disconnect) { _connectedPeersCount--; } netEvent = CreateEvent(NetEventType.Disconnect); netEvent.Peer = netPeer; netEvent.DataReader.SetSource(packet.RawData, 9, packet.Size); netEvent.DisconnectReason = disconnectResult == DisconnectResult.Disconnect ? DisconnectReason.RemoteConnectionClose : DisconnectReason.ConnectionRejected; EnqueueEvent(netEvent); } else { NetPacketPool.Recycle(packet); } //Send shutdown SendRaw(new[] { (byte)PacketProperty.ShutdownOk }, 0, 1, remoteEndPoint); break; case PacketProperty.ConnectAccept: var connAccept = NetConnectAcceptPacket.FromData(packet); if (connAccept != null && peerFound && netPeer.ProcessConnectAccept(connAccept)) { var connectEvent = CreateEvent(NetEventType.Connect); connectEvent.Peer = netPeer; EnqueueEvent(connectEvent); } break; case PacketProperty.ConnectRequest: var connRequest = NetConnectRequestPacket.FromData(packet); if (connRequest != null) { ProcessConnectRequest(remoteEndPoint, netPeer, connRequest); } break; default: if (peerFound) { netPeer.ProcessPacket(packet); } break; } }
private void ProcessConnectRequest( IPEndPoint remoteEndPoint, NetPeer netPeer, NetConnectRequestPacket connRequest) { byte connectionNumber = connRequest.ConnectionNumber; NetEvent netEvent; NetUtils.DebugWrite("ConnectRequest LastId: {0}, NewId: {1}, EP: {2}", netPeer.ConnectId, connRequest.ConnectionId, remoteEndPoint); //if we have peer if (netPeer != null) { var processResult = netPeer.ProcessConnectRequest(connRequest); switch (processResult) { case ConnectRequestResult.Reconnection: _connectedPeersCount--; netEvent = CreateEvent(NetEventType.Disconnect); netEvent.Peer = netPeer; netEvent.DisconnectReason = DisconnectReason.RemoteConnectionClose; EnqueueEvent(netEvent); _peers.RemovePeer(netPeer); //go to new connection break; case ConnectRequestResult.NewConnection: _peers.RemovePeer(netPeer); //go to new connection break; case ConnectRequestResult.P2PConnection: netEvent = CreateEvent(NetEventType.ConnectionRequest); netEvent.ConnectionRequest = new ConnectionRequest( netPeer.ConnectId, connectionNumber, ConnectionRequestType.PeerToPeer, connRequest.Data, netPeer, OnConnectionSolved); EnqueueEvent(netEvent); return; default: //no operations needed return; } //ConnectRequestResult.NewConnection //Set next connection number connectionNumber = (byte)((netPeer.ConnectionNum + 1) % NetConstants.MaxConnectionNumber); //To reconnect peer } //Add new peer and craete ConnectRequest event NetUtils.DebugWrite("[NM] Creating request event: " + connRequest.ConnectionId); netPeer = new NetPeer(this, remoteEndPoint); if (_peers.TryAdd(netPeer)) { netEvent = CreateEvent(NetEventType.ConnectionRequest); netEvent.ConnectionRequest = new ConnectionRequest( connRequest.ConnectionId, connectionNumber, ConnectionRequestType.Incoming, connRequest.Data, netPeer, OnConnectionSolved); EnqueueEvent(netEvent); } }