コード例 #1
0
		private void HandleRakNetMessage(IPEndPoint senderEndpoint, OpenConnectionRequest1 incoming)
		{
			lock (_playerSessions)
			{
				// Already connecting, then this is just a duplicate
				if (_connectionAttemps.ContainsKey(senderEndpoint))
				{
					DateTime created;
					_connectionAttemps.TryGetValue(senderEndpoint, out created);

					if (DateTime.UtcNow < created + TimeSpan.FromSeconds(3))
					{
						return;
					}

					_connectionAttemps.TryRemove(senderEndpoint, out created);
				}

				if (!_connectionAttemps.TryAdd(senderEndpoint, DateTime.UtcNow)) return;
			}

			if (Log.IsDebugEnabled)
				Log.WarnFormat("New connection from: {0} {1}, MTU: {2}", senderEndpoint.Address, senderEndpoint.Port, incoming.mtuSize);

			var packet = OpenConnectionReply1.CreateObject();
			packet.serverGuid = 12345;
			packet.mtuSize = incoming.mtuSize;
			packet.serverHasSecurity = 0;
			var data = packet.Encode();
			packet.PutPool();

			TraceSend(packet);

			SendData(data, senderEndpoint);
		}
コード例 #2
0
        public void SendOpenConnectionRequest1()
        {
            var packet = new OpenConnectionRequest1()
            {
                raknetProtocolVersion = byte.MaxValue,                 // Indicate to the server that this is a performance tests. Disables logging.
                mtuSize = _mtuSize
            };

            var data = packet.Encode();

            SendData(data);
        }
コード例 #3
0
        public void BeginConnection(IPEndPoint address)
        {
            var connReq = new OpenConnectionRequest1
            {
                Magic    = RakNetConstants.Magic,
                Protocol = RakNetConstants.ProtocolVersion
            };

            Send(address, connReq);

            Socket.RunLoop();
        }
コード例 #4
0
        public void SendOpenConnectionRequest1(IPEndPoint targetEndPoint, short mtuSize)
        {
            MtuSize = mtuSize;             // This is what we will use from connections this point forward

            var packet = OpenConnectionRequest1.CreateObject();

            packet.raknetProtocolVersion = 9;
            packet.mtuSize = mtuSize;

            byte[] data = packet.Encode();

            TraceSend(packet);

            Log.Debug($"Sending MTU size={mtuSize}, data length={data.Length}");
            _sender.SendData(data, targetEndPoint);
        }
コード例 #5
0
        private void HandleRakNetMessage(IPEndPoint senderEndpoint, OpenConnectionRequest1 message)
        {
            ConcurrentDictionary <IPEndPoint, RakSession> sessions           = _connectionInfo.RakSessions;
            ConcurrentDictionary <IPEndPoint, DateTime>   connectionAttempts = _connectionAttempts;

            if (Log.IsDebugEnabled)
            {
                Log.Warn($"New connection from {senderEndpoint.Address} {senderEndpoint.Port}, MTU={message.mtuSize}, RakNet version={message.raknetProtocolVersion}");
            }

            lock (sessions)
            {
                // Already connecting, then this is just a duplicate
                if (connectionAttempts.TryGetValue(senderEndpoint, out DateTime created))
                {
                    if (DateTime.UtcNow < created + TimeSpan.FromSeconds(3))
                    {
                        return;
                    }

                    connectionAttempts.TryRemove(senderEndpoint, out _);
                }

                if (!connectionAttempts.TryAdd(senderEndpoint, DateTime.UtcNow))
                {
                    return;
                }
            }

            if (message.mtuSize > MaxMtuSize)
            {
                return;
            }

            var packet = OpenConnectionReply1.CreateObject();

            packet.serverGuid        = _motdProvider.ServerId;
            packet.mtuSize           = message.mtuSize;
            packet.serverHasSecurity = 0;
            byte[] data = packet.Encode();

            TraceSend(packet);

            packet.PutPool();

            _sender.SendData(data, senderEndpoint);
        }
コード例 #6
0
ファイル: MiNetClient.cs プロジェクト: TheDiamondYT2/MiNET
        public void SendOpenConnectionRequest1()
        {
            var packet = new OpenConnectionRequest1()
            {
                raknetProtocolVersion = 7,                 // Indicate to the server that this is a performance tests. Disables logging.
                mtuSize = _mtuSize
            };

            byte[] data = packet.Encode();

            TraceSend(packet);

            // 1087 1447
            byte[] data2 = new byte[_mtuSize - data.Length];
            Buffer.BlockCopy(data, 0, data2, 0, data.Length);

            SendData(data2);
        }
コード例 #7
0
        private Packet DecodePacket(Byte id, BinaryReaderBE reader)
        {
            Packet packet = null;

            switch ((PacketId)id)
            {
            case PacketId.OpenConnectionRequest1: packet = new OpenConnectionRequest1(); break;

            case PacketId.OpenConnectionResponse1: packet = new OpenConnectionResponse1(); break;

            case PacketId.OpenConnectionRequest2: packet = new OpenConnectionRequest2(); break;

            case PacketId.OpenConnectionResponse2: packet = new OpenConnectionResponse2(); break;

            default: throw new InvalidDataException("Unrecognized packet ID");
            }

            packet.Read(reader);
            return(packet);
        }
コード例 #8
0
        /// <summary>
        ///     Processes a message.
        /// </summary>
        /// <param name="receiveBytes">The received bytes.</param>
        /// <param name="senderEndpoint">The sender's endpoint.</param>
        /// <exception cref="System.Exception">Receive ERROR, NAK in wrong place</exception>
        private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint)
        {
            byte msgId = receiveBytes[0];

            if (msgId == 0xFE)
            {
                Log.WarnFormat("A query detected from: {0}", senderEndpoint.Address);
                HandleQuery(receiveBytes, senderEndpoint);
            }
            else if (msgId <= (byte)DefaultMessageIdTypes.ID_USER_PACKET_ENUM)
            {
                DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId;

                Package message = PackageFactory.CreatePackage(msgId, receiveBytes);

                TraceReceive(message);

                switch (msgIdType)
                {
                case DefaultMessageIdTypes.ID_UNCONNECTED_PING:
                case DefaultMessageIdTypes.ID_UNCONNECTED_PING_OPEN_CONNECTIONS:
                {
                    UnconnectedPing incoming = (UnconnectedPing)message;

                    //TODO: This needs to be verified with RakNet first
                    //response.sendpingtime = msg.sendpingtime;
                    //response.sendpongtime = DateTimeOffset.UtcNow.Ticks / TimeSpan.TicksPerMillisecond;

                    var packet = new UnconnectedPong
                    {
                        serverId   = 22345,
                        pingId     = incoming.pingId /*incoming.pingId*/,
                        serverName = string.Format(@"MCPE;{0};27;0.11.1;{1};{2}", Motd, _playerSessions.Count, 1000)
                    };
                    var data = packet.Encode();
                    TraceSend(packet);
                    SendData(data, senderEndpoint, _listener);
                    break;
                }

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1:
                {
                    OpenConnectionRequest1 incoming = (OpenConnectionRequest1)message;

                    _isPerformanceTest = _isPerformanceTest || incoming.raknetProtocolVersion == byte.MaxValue;

                    var packet = new OpenConnectionReply1
                    {
                        serverGuid        = 12345,
                        mtuSize           = incoming.mtuSize,
                        serverHasSecurity = 0
                    };

                    var data = packet.Encode();
                    TraceSend(packet);
                    SendData(data, senderEndpoint, _listener);
                    break;
                }

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_2:
                {
                    OpenConnectionRequest2 incoming = (OpenConnectionRequest2)message;

                    Log.WarnFormat("New connection from: {0} {1}", senderEndpoint.Address, incoming.clientUdpPort);

                    var packet = new OpenConnectionReply2
                    {
                        serverGuid             = 12345,
                        mtuSize                = incoming.mtuSize,
                        doSecurityAndHandshake = new byte[0]
                    };

                    PlayerNetworkSession session = null;
                    lock (_playerSessions)
                    {
                        if (_playerSessions.ContainsKey(senderEndpoint))
                        {
                            PlayerNetworkSession value;
                            _playerSessions.TryRemove(senderEndpoint, out value);
                            value.Player.HandleDisconnectionNotification();
                            Log.Info("Removed ghost");
                        }

                        session = new PlayerNetworkSession(new Player(this, senderEndpoint, _levels[_random.Next(0, _levels.Count)], _pluginManager, incoming.mtuSize), senderEndpoint);
                        session.LastUpdatedTime = DateTime.UtcNow;
                        session.Mtuize          = incoming.mtuSize;

                        _playerSessions.TryAdd(senderEndpoint, session);
                    }

                    var data = packet.Encode();
                    TraceSend(packet);
                    SendData(data, senderEndpoint, session.SyncRoot);
                    break;
                }

                default:
                    Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) from {1}", msgId, senderEndpoint.Address);
                    break;
                }

                if (message != null)
                {
                    message.PutPool();
                }
                else
                {
                    Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) from {1}", msgId, senderEndpoint.Address);
                }
            }
            else
            {
                DatagramHeader header = new DatagramHeader(receiveBytes[0]);
                if (!header.isACK && !header.isNAK && header.isValid)
                {
                    if (receiveBytes[0] == 0xa0)
                    {
                        throw new Exception("Receive ERROR, NAK in wrong place");
                    }

                    ConnectedPackage package = ConnectedPackage.CreateObject();
                    package.Decode(receiveBytes);
                    List <Package> messages = package.Messages;

                    if (messages.Count == 1)
                    {
                        McpeBatch batch = messages.First() as McpeBatch;
                        if (batch != null)
                        {
                            messages = new List <Package>();

                            // Get bytes
                            byte[] payload = batch.payload;
                            // Decompress bytes

                            MemoryStream stream = new MemoryStream(payload);
                            if (stream.ReadByte() != 0x78)
                            {
                                throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                            }
                            stream.ReadByte();
                            using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
                            {
                                // Get actual package out of bytes
                                MemoryStream destination = new MemoryStream();
                                defStream2.CopyTo(destination);
                                byte[] internalBuffer = destination.ToArray();
                                messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                            }
                        }
                    }

                    // IF reliable code below is enabled, useItem start sending doubles
                    // for some unknown reason.

                    //Reliability reliability = package._reliability;
                    //if (reliability == Reliability.Reliable
                    //	|| reliability == Reliability.ReliableSequenced
                    //	|| reliability == Reliability.ReliableOrdered
                    //	)
                    {
                        EnqueueAck(senderEndpoint, package._datagramSequenceNumber);
                    }

                    PlayerNetworkSession playerSession;
                    if (_playerSessions.TryGetValue(senderEndpoint, out playerSession))
                    {
                        foreach (var message in messages)
                        {
                            if (message is SplitPartPackage)
                            {
                                SplitPartPackage splitMessage = message as SplitPartPackage;

                                int spId    = package._splitPacketId;
                                int spIdx   = package._splitPacketIndex;
                                int spCount = package._splitPacketCount;

                                if (!playerSession.Splits.ContainsKey(spId))
                                {
                                    playerSession.Splits.Add(spId, new SplitPartPackage[spCount]);
                                }

                                SplitPartPackage[] spPackets = playerSession.Splits[spId];
                                spPackets[spIdx] = splitMessage;

                                bool haveEmpty = false;
                                for (int i = 0; i < spPackets.Length; i++)
                                {
                                    haveEmpty = haveEmpty || spPackets[i] == null;
                                }

                                if (!haveEmpty)
                                {
                                    Log.DebugFormat("Got all {0} split packages for split ID: {1}", spCount, spId);

                                    MemoryStream stream = new MemoryStream();
                                    for (int i = 0; i < spPackets.Length; i++)
                                    {
                                        byte[] buf = spPackets[i].Message;
                                        stream.Write(buf, 0, buf.Length);
                                    }

                                    byte[] buffer      = stream.ToArray();
                                    var    fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer);
                                    HandlePackage(fullMessage, playerSession);
                                }
                                continue;
                            }

                            message.Timer.Restart();
                            HandlePackage(message, playerSession);
                            message.PutPool();
                        }
                    }

                    package.PutPool();
                }
                else if (header.isACK && header.isValid)
                {
                    HandleAck(receiveBytes, senderEndpoint);
                }
                else if (header.isNAK && header.isValid)
                {
                    HandleNak(receiveBytes, senderEndpoint);
                }
                else if (!header.isValid)
                {
                    Log.Warn("!!!! ERROR, Invalid header !!!!!");
                }
            }
        }
コード例 #9
0
        public static void HandleRakNetMessage(MiNetServer server, IPEndPoint senderEndpoint, OpenConnectionRequest1 incoming)
        {
            lock (server._rakNetSessions)
            {
                // Already connecting, then this is just a duplicate
                if (server._connectionAttemps.TryGetValue(senderEndpoint, out DateTime created))
                {
                    if (DateTime.UtcNow < created + TimeSpan.FromSeconds(3))
                    {
                        return;
                    }

                    server._connectionAttemps.TryRemove(senderEndpoint, out _);
                }

                if (!server._connectionAttemps.TryAdd(senderEndpoint, DateTime.UtcNow))
                {
                    return;
                }
            }

            if (Log.IsDebugEnabled)
            {
                Log.Warn($"New connection from {senderEndpoint.Address} {senderEndpoint.Port}, MTU={incoming.mtuSize}, RakNet version={incoming.raknetProtocolVersion}");
            }

            var packet = OpenConnectionReply1.CreateObject();

            packet.serverGuid        = server.MotdProvider.ServerId;
            packet.mtuSize           = incoming.mtuSize;
            packet.serverHasSecurity = 0;
            byte[] data = packet.Encode();

            TraceSend(packet);

            packet.PutPool();

            server.SendData(data, senderEndpoint);
        }
コード例 #10
0
ファイル: MiNetServer.cs プロジェクト: ruslan81/MiNET
        private void HandleRakNetMessage(byte[] receiveBytes, IPEndPoint senderEndpoint, byte msgId)
        {
            DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId;

            Package message = PackageFactory.CreatePackage(msgId, receiveBytes);

            if (message == null)
            {
                if (!_badPacketBans.ContainsKey(senderEndpoint.Address))
                {
                    _badPacketBans.Add(senderEndpoint.Address, true);
                }
                Log.ErrorFormat("Receive bad packet with ID: {0} (0x{0:x2}) {2} from {1}", msgId, senderEndpoint.Address, (DefaultMessageIdTypes)msgId);
                return;
            }

            message.Source = "RakNet";

            TraceReceive(message);

            switch (msgIdType)
            {
            case DefaultMessageIdTypes.ID_UNCONNECTED_PING:
            case DefaultMessageIdTypes.ID_UNCONNECTED_PING_OPEN_CONNECTIONS:
            {
                UnconnectedPing incoming = (UnconnectedPing)message;

                //TODO: This needs to be verified with RakNet first
                //response.sendpingtime = msg.sendpingtime;
                //response.sendpongtime = DateTimeOffset.UtcNow.Ticks / TimeSpan.TicksPerMillisecond;

                var packet = UnconnectedPong.CreateObject();
                packet.serverId   = 22345;
                packet.pingId     = incoming.pingId;
                packet.serverName = MotdProvider.GetMotd(ServerInfo);
                var data = packet.Encode();
                packet.PutPool();
                TraceSend(packet);
                SendData(data, senderEndpoint, new object());
                break;
            }

            case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1:
            {
                OpenConnectionRequest1 incoming = (OpenConnectionRequest1)message;
                Log.DebugFormat("New connection from: {0} {1}", senderEndpoint.Address, senderEndpoint.Port);

                lock (_playerSessions)
                {
                    // Already connecting, then this is just a duplicate
                    if (_connectionAttemps.ContainsKey(senderEndpoint))
                    {
                        DateTime created;
                        _connectionAttemps.TryGetValue(senderEndpoint, out created);

                        if (DateTime.UtcNow < created + TimeSpan.FromSeconds(3))
                        {
                            return;
                        }
                    }

                    //PlayerNetworkSession session;
                    //if (_playerSessions.TryGetValue(senderEndpoint, out session))
                    //{

                    //	Log.DebugFormat("Reconnection detected from {0}. Removing old session and disconnecting old player.", senderEndpoint.Address);

                    //	Player oldPlayer = session.Player;
                    //	if (oldPlayer != null)
                    //	{
                    //		oldPlayer.Disconnect("Reconnecting.");
                    //	}
                    //	else
                    //	{
                    //		_playerSessions.TryRemove(session.EndPoint, out session);
                    //	}
                    //}

                    if (!_connectionAttemps.ContainsKey(senderEndpoint))
                    {
                        _connectionAttemps.Add(senderEndpoint, DateTime.UtcNow);
                    }
                }

                var packet = OpenConnectionReply1.CreateObject();
                packet.serverGuid        = 12345;
                packet.mtuSize           = incoming.mtuSize;
                packet.serverHasSecurity = 0;
                var data = packet.Encode();
                packet.PutPool();

                TraceSend(packet);

                SendData(data, senderEndpoint, new object());
                break;
            }

            case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_2:
            {
                OpenConnectionRequest2 incoming = (OpenConnectionRequest2)message;

                PlayerNetworkSession session;
                lock (_playerSessions)
                {
                    if (_connectionAttemps.ContainsKey(senderEndpoint))
                    {
                        _connectionAttemps.Remove(senderEndpoint);
                    }
                    else
                    {
                        Log.ErrorFormat("Unexpected connection request packet from {0}.", senderEndpoint.Address);
                        return;
                    }

                    //PlayerNetworkSession session;
                    if (_playerSessions.TryGetValue(senderEndpoint, out session))
                    {
                        Log.WarnFormat("Reconnection detected from {0}. Removing old session and disconnecting old player.", senderEndpoint.Address);

                        Player oldPlayer = session.Player;
                        if (oldPlayer != null)
                        {
                            oldPlayer.Disconnect("Reconnecting.");
                        }
                        else
                        {
                            _playerSessions.TryRemove(session.EndPoint, out session);
                        }
                    }


                    if (_playerSessions.TryGetValue(senderEndpoint, out session))
                    {
                        // Already connecting, then this is just a duplicate
                        if (session.State == ConnectionState.Connecting /* && DateTime.UtcNow < session.LastUpdatedTime + TimeSpan.FromSeconds(2)*/)
                        {
                            return;
                        }

                        Log.ErrorFormat("Unexpected session from {0}. Removing old session and disconnecting old player.", senderEndpoint.Address);

                        Player oldPlayer = session.Player;
                        if (oldPlayer != null)
                        {
                            oldPlayer.Disconnect("Reconnecting.");
                        }
                        else
                        {
                            _playerSessions.TryRemove(session.EndPoint, out session);
                        }
                    }

                    session = new PlayerNetworkSession(null, senderEndpoint)
                    {
                        State           = ConnectionState.Connecting,
                        LastUpdatedTime = DateTime.UtcNow,
                        Mtuize          = incoming.mtuSize
                    };

                    _playerSessions.TryAdd(senderEndpoint, session);
                }

                Player player = PlayerFactory.CreatePlayer(this, senderEndpoint, incoming.mtuSize);
                player.ClientGuid     = incoming.clientGuid;
                player.NetworkSession = session;
                session.Player        = player;

                var reply = OpenConnectionReply2.CreateObject();
                reply.serverGuid             = 12345;
                reply.mtuSize                = incoming.mtuSize;
                reply.doSecurityAndHandshake = new byte[0];
                var data = reply.Encode();
                reply.PutPool();

                TraceSend(reply);

                SendData(data, senderEndpoint, session.SyncRoot);
                break;
            }

            default:
                if (!_badPacketBans.ContainsKey(senderEndpoint.Address))
                {
                    _badPacketBans.Add(senderEndpoint.Address, true);
                }
                Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) {2} from {1}", msgId, senderEndpoint.Address, (DefaultMessageIdTypes)msgId);
                break;
            }

            message.PutPool();
        }
コード例 #11
0
        public void ProcessMessage(MessageType messageType, Protocol.IncomingMessageBuffer buffer)
        {
            switch (messageType)
            {
            case MessageType.ID_OPEN_CONNECTION_REQUEST_1:
                if (State == ConnectionState.Waiting || State == ConnectionState.Connecting)
                {
                    OpenConnectionRequest1 message = new OpenConnectionRequest1();
                    if (!message.Parse(buffer))
                    {
                        return;
                    }

                    if (message.IncompatibleProtocol)
                    {
                        IncompatibleVersion incompatibleVersion = new IncompatibleVersion();
                        Network.UdpReceiver.Instance.Broadcast(incompatibleVersion, mSource);
                    }

                    OpenConnectionReply1 response = new OpenConnectionReply1();
                    response.MTU = message.NullPayloadLength;
                    UdpReceiver.Instance.Broadcast(response, mSource);

                    State = ConnectionState.Connecting;
                }
                break;

            case Protocol.MessageType.ID_OPEN_CONNECTION_REQUEST_2:
                if (State == ConnectionState.Connecting)
                {
                    OpenConnectionRequest2 message = new OpenConnectionRequest2();
                    if (!message.Parse(buffer))
                    {
                        return;
                    }

                    OpenConnectionReply2 response = new OpenConnectionReply2();
                    response.MTUSize       = message.MTUSize;
                    response.ClientAddress = message.ClientAddress;
                    Network.UdpReceiver.Instance.Broadcast(response, mSource);

                    State = ConnectionState.Handshaking;
                }
                break;

            case Protocol.MessageType.ID_CUSTOM_PACKET_0:
            case Protocol.MessageType.ID_CUSTOM_PACKET_1:
            case Protocol.MessageType.ID_CUSTOM_PACKET_2:
            case Protocol.MessageType.ID_CUSTOM_PACKET_3:
            case Protocol.MessageType.ID_CUSTOM_PACKET_4:
            case Protocol.MessageType.ID_CUSTOM_PACKET_5:
            case Protocol.MessageType.ID_CUSTOM_PACKET_6:
            case Protocol.MessageType.ID_CUSTOM_PACKET_7:
            case Protocol.MessageType.ID_CUSTOM_PACKET_8:
            case Protocol.MessageType.ID_CUSTOM_PACKET_9:
            case Protocol.MessageType.ID_CUSTOM_PACKET_A:
            case Protocol.MessageType.ID_CUSTOM_PACKET_B:
            case Protocol.MessageType.ID_CUSTOM_PACKET_C:
            case Protocol.MessageType.ID_CUSTOM_PACKET_D:
            case Protocol.MessageType.ID_CUSTOM_PACKET_E:
            case Protocol.MessageType.ID_CUSTOM_PACKET_F:
                if (State == ConnectionState.Connected || State == ConnectionState.Handshaking)
                {
                    FrameSet message = new FrameSet(messageType);
                    if (!message.Parse(buffer))
                    {
                        return;
                    }

                    foreach (Frame frame in message.Frames)
                    {
                        ProcessFrame(frame);
                    }
                }
                break;

            default:
                //Unknown message
                break;
            }
        }