示例#1
0
        private void HandleRakNetMessage(IPEndPoint senderEndpoint, OpenConnectionRequest2 incoming)
        {
            PlayerNetworkSession session;

            lock (PlayerSessions)
            {
                DateTime trash;
                if (!_connectionAttemps.TryRemove(senderEndpoint, out trash))
                {
                    Log.WarnFormat("Unexpected connection request packet from {0}. Probably a resend.", senderEndpoint.Address);
                    return;
                }

                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.InfoFormat("Unexpected session from {0}. Removing old session and disconnecting old player.", senderEndpoint.Address);

                    session.Disconnect("Reconnecting.", false);

                    PlayerSessions.TryRemove(senderEndpoint, out session);
                }

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

                PlayerSessions.TryAdd(senderEndpoint, session);
            }

            //Player player = PlayerFactory.CreatePlayer(this, senderEndpoint);
            //player.ClientGuid = incoming.clientGuid;
            //player.NetworkHandler = session;
            //session.Player = player;
            session.MessageHandler = new LoginMessageHandler(session);

            var reply = OpenConnectionReply2.CreateObject();

            reply.serverGuid             = 12345;
            reply.clientEndpoint         = senderEndpoint;
            reply.mtuSize                = incoming.mtuSize;
            reply.doSecurityAndHandshake = new byte[1];
            var data = reply.Encode();

            reply.PutPool();

            TraceSend(reply);

            SendData(data, senderEndpoint);
        }
示例#2
0
        private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint)
        {
            byte msgId = receiveBytes[0];

            if (msgId == 0xFE)
            {
                Log.InfoFormat("A query detected from: {0}", senderEndpoint.Address);
                HandleQuery(receiveBytes, senderEndpoint);
            }
            else if (msgId <= (byte)DefaultMessageIdTypes.ID_USER_PACKET_ENUM)
            {
                HandleRakNetMessage(receiveBytes, senderEndpoint, msgId);
            }
            else
            {
                PlayerNetworkSession playerSession;
                if (!PlayerSessions.TryGetValue(senderEndpoint, out playerSession))
                {
                    //Log.DebugFormat("Receive MCPE message 0x{1:x2} without session {0}", senderEndpoint.Address, msgId);
                    //if (!_badPacketBans.ContainsKey(senderEndpoint.Address))
                    //{
                    //	_badPacketBans.Add(senderEndpoint.Address, true);
                    //}
                    return;
                }

                if (playerSession.MessageHandler == null)
                {
                    Log.ErrorFormat("Receive MCPE message 0x{1:x2} without message handler {0}. Session removed.", senderEndpoint.Address, msgId);
                    PlayerSessions.TryRemove(senderEndpoint, out playerSession);
                    //if (!_badPacketBans.ContainsKey(senderEndpoint.Address))
                    //{
                    //	_badPacketBans.Add(senderEndpoint.Address, true);
                    //}
                    return;
                }

                if (playerSession.Evicted)
                {
                    return;
                }

                playerSession.LastUpdatedTime = DateTime.UtcNow;

                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();
                    try
                    {
                        package.Decode(receiveBytes);
                    }
                    catch (Exception e)
                    {
                        playerSession.Disconnect("Bad package received from client.");

                        Log.Warn($"Bad packet {receiveBytes[0]}\n{Package.HexDump(receiveBytes)}", e);

                        GreylistManager.Blacklist(senderEndpoint.Address);

                        return;
                    }


                    // 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(playerSession, package._datagramSequenceNumber);
                        //if (Log.IsDebugEnabled) Log.Debug("ACK on #" + package._datagramSequenceNumber.IntValue());
                    }

                    HandleConnectedPackage(playerSession, package);
                    package.PutPool();
                }
                else if (header.isACK && header.isValid)
                {
                    HandleAck(playerSession, receiveBytes);
                }
                else if (header.isNAK && header.isValid)
                {
                    HandleNak(playerSession, receiveBytes);
                }
                else if (!header.isValid)
                {
                    Log.Warn("!!!! ERROR, Invalid header !!!!!");
                }
            }
        }