示例#1
0
 public Datagram()
 {
     MessageParts = new List <MessagePart>(50);
     Header       = new DatagramHeader
     {
         isValid     = true,
         needsBAndAs = true,
         //datagramSequenceNumber = datagramSequenceNumber
     };
     _buf = new MemoryStream(new byte[1600], 0, 1600, true, true);
 }
示例#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;
				}

				Player player = playerSession.Player;

				if (player == null)
				{
					Log.ErrorFormat("Receive MCPE message 0x{1:x2} without player {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)
					{
						player.Disconnect("Bad package received from client.");
						//if (Log.IsDebugEnabled)
						{
							Log.Warn("Bad packet " + receiveBytes[0], 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);
					}


					DelayedProcessing(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 !!!!!");
				}
			}
		}
示例#3
0
        protected override void EncodePackage()
        {
            _buffer.Position = 0;

            byte[] encodedMessage = Buffer;
            if (Buffer == null)
            {
                encodedMessage = Messages.First().Encode();
            }

            MessageLength = encodedMessage.Length;

            // Datagram header

            if (_datagramHeader == null)
            {
                _datagramHeader = new DatagramHeader(0x8c);
            }
            if (_splitPacketCount > 1 && _splitPacketIndex > 0)
            {
                Write((byte)0x8c);
            }
            else
            {
                Write((byte)0x84);
            }

            Write(_datagramSequenceNumber);

            // foreach message

            // Message header

            byte rely = (byte)_reliability;

            Write((byte)((rely << 5) | (_hasSplit ? Convert.ToByte("00010000", 2) : 0x00)));
            Write((short)(MessageLength * 8));            // length

            if (_reliability == Reliability.Reliable ||
                _reliability == Reliability.ReliableOrdered ||
                _reliability == Reliability.ReliableSequenced ||
                _reliability == Reliability.ReliableWithAckReceipt ||
                _reliability == Reliability.ReliableOrderedWithAckReceipt
                )
            {
                Write(_reliableMessageNumber);
            }

            if (_reliability == Reliability.UnreliableSequenced ||
                _reliability == Reliability.ReliableOrdered ||
                _reliability == Reliability.ReliableSequenced ||
                _reliability == Reliability.ReliableOrderedWithAckReceipt
                )
            {
                Write(_orderingIndex);
                Write(_orderingChannel);
            }

            if (_hasSplit)
            {
                Write(_splitPacketCount);
                Write(_splitPacketId);
                Write(_splitPacketIndex);
            }

            // Message body

            Write(encodedMessage);
        }
示例#4
0
        protected override void DecodePackage()
        {
            Messages = new List <Package>();

            _buffer.Position = 0;

            _datagramHeader         = new DatagramHeader(ReadByte());
            _datagramSequenceNumber = ReadLittle();

            while (_buffer.Position != _buffer.Length)
            {
                byte flags = ReadByte();


                _reliability = (Reliability)((flags & Convert.ToByte("011100000", 2)) >> 5);
                int hasSplitPacket = ((flags & Convert.ToByte("00010000", 2)) >> 0);

                short dataBitLength = ReadShort();

                if (_reliability == Reliability.Reliable ||
                    _reliability == Reliability.ReliableSequenced ||
                    _reliability == Reliability.ReliableOrdered
                    )
                {
                    _reliableMessageNumber = ReadLittle();
                }
                else
                {
                    _reliableMessageNumber = -1;
                }

                if (_reliability == Reliability.UnreliableSequenced ||
                    _reliability == Reliability.ReliableSequenced
                    )
                {
                    _sequencingIndex = ReadLittle();
                }

                if (_reliability == Reliability.UnreliableSequenced ||
                    _reliability == Reliability.ReliableSequenced ||
                    _reliability == Reliability.ReliableOrdered ||
                    _reliability == Reliability.ReliableOrderedWithAckReceipt
                    )
                {
                    _orderingIndex   = ReadLittle();
                    _orderingChannel = ReadByte();                     // flags
                }
                else
                {
                    _orderingChannel = 0;
                }

                if (hasSplitPacket != 0)
                {
                    _splitPacketCount = ReadInt();
                    _splitPacketId    = ReadShort();
                    _splitPacketIndex = ReadInt();
                }
                else
                {
                    _splitPacketCount = 0;
                }

                // Slurp the payload
                MessageLength = (int)Math.Ceiling((((double)dataBitLength) / 8));

                byte[] internalBuffer = ReadBytes(MessageLength);

                if (hasSplitPacket != 0)
                {
                    Messages.Add(new SplitPartPackage(internalBuffer[0], internalBuffer));
                    return;
                }

                Messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                if (MessageLength != internalBuffer.Length)
                {
                    Debug.WriteLine("Missmatch of requested lenght, and actual read lenght");
                }
            }
        }
示例#5
0
        protected override void DecodePackage()
        {
            Messages = new List <Package>();

            _buffer.Position = 0;

            _datagramHeader         = new DatagramHeader(ReadByte());
            _datagramSequenceNumber = ReadLittle();
            _datagramHeader.datagramSequenceNumber = _datagramSequenceNumber;

            while (_buffer.Position < _buffer.Length)
            {
                byte flags = ReadByte();
                _reliability = (Reliability)((flags & Convert.ToByte("011100000", 2)) >> 5);
                _hasSplit    = ((flags & Convert.ToByte("00010000", 2)) > 0);

                short dataBitLength = ReadShort();

                if (_reliability == Reliability.Reliable ||
                    _reliability == Reliability.ReliableSequenced ||
                    _reliability == Reliability.ReliableOrdered
                    )
                {
                    _reliableMessageNumber = ReadLittle();
                }
                else
                {
                    _reliableMessageNumber = -1;
                }

                if (_reliability == Reliability.UnreliableSequenced ||
                    _reliability == Reliability.ReliableSequenced
                    )
                {
                    _sequencingIndex = ReadLittle();
                }

                if (_reliability == Reliability.UnreliableSequenced ||
                    _reliability == Reliability.ReliableSequenced ||
                    _reliability == Reliability.ReliableOrdered ||
                    _reliability == Reliability.ReliableOrderedWithAckReceipt
                    )
                {
                    _orderingIndex   = ReadLittle();
                    _orderingChannel = ReadByte();                     // flags
                }
                else
                {
                    _orderingIndex   = 0;
                    _orderingChannel = 0;
                }

                if (_hasSplit)
                {
                    _splitPacketCount = ReadInt();
                    _splitPacketId    = ReadShort();
                    _splitPacketIndex = ReadInt();
                }
                else
                {
                    _splitPacketCount = -1;
                    _splitPacketId    = -1;
                    _splitPacketIndex = -1;
                }

                // Slurp the payload
                MessageLength = (int)Math.Ceiling((((double)dataBitLength) / 8));

                byte[] internalBuffer = ReadBytes(MessageLength);

                if (_hasSplit)
                {
                    //Log.Debug("Recieve split\n" + HexDump(internalBuffer));
                    SplitPartPackage splitPartPackage = SplitPartPackage.CreateObject();
                    splitPartPackage.Id      = internalBuffer[0];
                    splitPartPackage.Message = internalBuffer;
                    Messages.Add(splitPartPackage);
                    return;
                }

                byte id = internalBuffer[0];
                if (id == 0x8e)
                {
                    id = internalBuffer[1];
                }

                Package package = PackageFactory.CreatePackage(id, internalBuffer) ?? new UnknownPackage(id, internalBuffer);
                package.DatagramSequenceNumber = _datagramSequenceNumber;
                package.ReliableMessageNumber  = _reliableMessageNumber;
                package.OrderingChannel        = _orderingChannel;
                package.OrderingIndex          = _orderingIndex;

                if (!(package is McpeBatch))
                {
                    Log.Debug($"Raw: {package.DatagramSequenceNumber} {package.ReliableMessageNumber} {package.OrderingIndex} {package.GetType().Name} 0x{package.Id:x2} \n{HexDump(internalBuffer)}");
                }

                Messages.Add(package);
                if (MessageLength != internalBuffer.Length)
                {
                    Debug.WriteLine("Missmatch of requested lenght, and actual read lenght");
                }
            }
        }
示例#6
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, new object());
                        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, new object());
                        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");
                            }

                            Player player = PlayerFactory.CreatePlayer(this, senderEndpoint, _levels[_random.Next(0, _levels.Count)], incoming.mtuSize);
                            session = new PlayerNetworkSession(player, 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 !!!!!");
                }
            }
        }
示例#7
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 <= (byte) DefaultMessageIdTypes.ID_USER_PACKET_ENUM)
            {
                DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes) msgId;

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

                if (message == null) return;

                TraceReceive(message);

                switch (msgIdType)
                {
                    case DefaultMessageIdTypes.ID_UNCONNECTED_PONG:
                    {
                        UnconnectedPong incoming = (UnconnectedPong) message;
                        HaveServer = true;
                        SendOpenConnectionRequest1();

                        break;
                    }
                    case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1:
                    {
                        OpenConnectionReply1 incoming = (OpenConnectionReply1) message;
                        _mtuSize = incoming.mtuSize;
                        //if (incoming.mtuSize < _mtuSize) throw new Exception("Error:" + incoming.mtuSize);
                        SendOpenConnectionRequest2();
                        break;
                    }
                    case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2:
                    {
                        OpenConnectionReply2 incoming = (OpenConnectionReply2) message;
                        //_mtuSize = incoming.mtuSize;
                        SendConnectionRequest();
                        break;
                    }
                }
            }
            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();
                    ConnectedPackage package = new ConnectedPackage();
                    package.Decode(receiveBytes);
                    header = package._datagramHeader;
                    //Log.Debug($"> Datagram #{header.datagramSequenceNumber}, {package._hasSplit}, {package._splitPacketId}, {package._reliability}, {package._reliableMessageNumber}, {package._sequencingIndex}, {package._orderingChannel}, {package._orderingIndex}");

                    var messages = package.Messages;

                    //Reliability reliability = package._reliability;
                    //if (reliability == Reliability.Reliable
                    //	|| reliability == Reliability.ReliableSequenced
                    //	|| reliability == Reliability.ReliableOrdered
                    //	)
                    {
                        if (header.datagramSequenceNumber == 1000)
                        {
                            Log.Error("Datagram 1000 ignored");
                        }
                        else
                        {
                            // Send ACK
                            Acks ack = new Acks();
                            ack.acks.Add(package._datagramSequenceNumber.IntValue());
                            byte[] data = ack.Encode();
                            //Log.Info("Send ACK #" + package._datagramSequenceNumber.IntValue());
                            SendData(data, senderEndpoint);
                        }
                    }

                    //if (LoginSent) return; //HACK

                    foreach (var message in messages)
                    {
                        if (message is SplitPartPackage)
                        {
                            lock (Session.SyncRoot)
                            {
                                HandleSplitMessage(Session, package, (SplitPartPackage) message);
                            }

                            continue;
                        }

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

                    //package.PutPool();
                }
                else if (header.isPacketPair)
                {
                    Log.Warn("header.isPacketPair");
                }
                else if (header.isACK && header.isValid)
                {
                    HandleAck(receiveBytes, senderEndpoint);
                }
                else if (header.isNAK && header.isValid)
                {
                    Nak nak = new Nak();
                    nak.Decode(receiveBytes);
                    HandleNak(receiveBytes, senderEndpoint);
                }
                else if (!header.isValid)
                {
                    Log.Warn("!!!! ERROR, Invalid header !!!!!");
                }
                else
                {
                    Log.Warn("!! WHAT THE F");
                }
            }
        }
示例#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)
        {
            //_serverEndpoint = senderEndpoint;
            byte msgId = receiveBytes[0];

            if (msgId <= (byte) DefaultMessageIdTypes.ID_USER_PACKET_ENUM)
            {
                DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes) msgId;

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

                if (message == null) return;

                TraceReceive(message);

                switch (msgIdType)
                {
                    case DefaultMessageIdTypes.ID_UNCONNECTED_PONG:
                    {
                        //Thread.Sleep(50);
                        UnconnectedPong incoming = (UnconnectedPong) message;
                        SendOpenConnectionRequest1();

                        break;
                    }
                    case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1:
                    {
                        //Thread.Sleep(50);
                        OpenConnectionReply1 incoming = (OpenConnectionReply1) message;
                        if (incoming.mtuSize < _mtuSize) throw new Exception("Error:" + incoming.mtuSize);
                        SendOpenConnectionRequest2();
                        break;
                    }
                    case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2:
                    {
                        OpenConnectionReply2 incoming = (OpenConnectionReply2) message;
                        //Thread.Sleep(50);
                        //_mtuSize = incoming.mtuSize;
                        SendConnectionRequest();
                        break;
                    }
                    case DefaultMessageIdTypes.ID_CONNECTION_REQUEST_ACCEPTED:
                    {
                        //Thread.Sleep(50);
                        SendNewIncomingConnection();
                        var t1 = new Timer(state => SendConnectedPing(), null, 0, 5000);
                        //Thread.Sleep(50);
                        SendLogin("Client12");
                        break;
                    }
                }
            }
            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);
                    Log.Debug(">\tReceive Datagram #" + package._datagramSequenceNumber.IntValue());

                    var messages = package.Messages;

                    //Log.Debug("Received package: #" + package._datagramSequenceNumber.IntValue());

                    Reliability reliability = package._reliability;
                    //Log.InfoFormat("Reliability: {0}", reliability);

                    //if (reliability == Reliability.Reliable
                    //	|| reliability == Reliability.ReliableSequenced
                    //	|| reliability == Reliability.ReliableOrdered
                    //	)
                    {
                        // Send ACK
                        Acks ack = new Acks();
                        ack.acks.Add(package._datagramSequenceNumber.IntValue());
                        byte[] data = ack.Encode();
                        //Log.Debug("<\tSend ACK on #" + package._datagramSequenceNumber.IntValue());
                        SendData(data, senderEndpoint);
                    }

                    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;

                            Log.DebugFormat("Got split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx);

                            if (!_splits.ContainsKey(spId))
                            {
                                _splits[spId] = new SplitPartPackage[spCount];
                            }
                            else
                            {
                                Log.WarnFormat("Resent split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx);
                            }

                            SplitPartPackage[] spPackets = _splits[spId];
                            spPackets[spIdx] = splitMessage;

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

                            if (!haveEmpty)
                            {
                                Log.WarnFormat("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);
                                }

                                try
                                {
                                    byte[] buffer = stream.ToArray();
                                    var fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer);
                                    Log.Debug("Processing split-message");
                                    HandlePackage(fullMessage, senderEndpoint);
                                    fullMessage.PutPool();
                                }
                                catch (Exception e)
                                {
                                    Log.Warn("When processing split-message", e);
                                }
                            }

                            message.PutPool();
                            return;
                        }

                        {
                            message.Timer.Restart();
                            HandlePackage(message, senderEndpoint);
                            //message.PutPool();
                        }
                    }

                    //package.PutPool();
                }
                else if (header.isPacketPair)
                {
                    Log.Warn("header.isPacketPair");
                }
                else if (header.isACK && header.isValid)
                {
                    HandleAck(receiveBytes, senderEndpoint);
                }
                else if (header.isNAK && header.isValid)
                {
                    Nak nak = new Nak();
                    nak.Decode(receiveBytes);

                    Log.Warn("!!!! NAK !!!!!" + nak.sequenceNumber.IntValue());
                    HandleNak(receiveBytes, senderEndpoint);
                }
                else if (!header.isValid)
                {
                    Log.Warn("!!!! ERROR, Invalid header !!!!!");
                }
                else
                {
                    Log.Warn("!! WHAT THE F");
                }
            }
        }
示例#9
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);
                    return;
                }

                Player player = playerSession.Player;

                if (player == null)
                {
                    Log.ErrorFormat("Receive MCPE message 0x{1:x2} without player {0}. Session removed.", senderEndpoint.Address, msgId);
                    _playerSessions.TryRemove(senderEndpoint, out playerSession);
                    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)
                    {
                        player.Disconnect("Bad package received from client.");
                        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);
                    }

                    List<Package> messages = package.Messages;

                    if (messages.Count == 1)
                    {
                        McpeBatch batch = messages.First() as McpeBatch;
                        if (batch != null)
                        {
                            batch.Source = "Client";
                            messages.Clear();

                            // 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));
                            }
                            batch.PutPool();
                        }
                    }

                    DelayedProcessing(playerSession, package);
                    package.PutPool();
                }
                else if (header.isACK && header.isValid)
                {
                    ServerInfo.NumberOfAckReceive++;
                    HandleAck(playerSession, receiveBytes);
                }
                else if (header.isNAK && header.isValid)
                {
                    ServerInfo.NumberOfNakReceive++;
                    HandleNak(playerSession, receiveBytes);
                }
                else if (!header.isValid)
                {
                    Log.Warn("!!!! ERROR, Invalid header !!!!!");
                }
            }
        }
示例#10
0
        protected override void DecodePacket()
        {
            Messages = new List <Packet>();

            _buffer.Position = 0;

            _datagramHeader         = new DatagramHeader(ReadByte());
            _datagramSequenceNumber = ReadLittle();
            _datagramHeader.datagramSequenceNumber = _datagramSequenceNumber;

            _hasSplit = false;
            while (_buffer.Position < _buffer.Length)
            {
                if (_hasSplit)
                {
                    Log.Warn("Reading second split message");
                }

                byte flags = ReadByte();
                _reliability = (Reliability)((flags & Convert.ToByte("011100000", 2)) >> 5);
                _hasSplit    = ((flags & Convert.ToByte("00010000", 2)) > 0);

                short dataBitLength = ReadShort(true);

                if (_reliability == Reliability.Reliable ||
                    _reliability == Reliability.ReliableSequenced ||
                    _reliability == Reliability.ReliableOrdered
                    )
                {
                    _reliableMessageNumber = ReadLittle();
                }
                else
                {
                    _reliableMessageNumber = -1;
                }

                if (_reliability == Reliability.UnreliableSequenced ||
                    _reliability == Reliability.ReliableSequenced
                    )
                {
                    _sequencingIndex = ReadLittle();
                }
                else
                {
                    _sequencingIndex = -1;
                }

                if (_reliability == Reliability.UnreliableSequenced ||
                    _reliability == Reliability.ReliableSequenced ||
                    _reliability == Reliability.ReliableOrdered ||
                    _reliability == Reliability.ReliableOrderedWithAckReceipt
                    )
                {
                    _orderingIndex   = ReadLittle();
                    _orderingChannel = ReadByte();                     // flags
                }
                else
                {
                    _orderingIndex   = 0;
                    _orderingChannel = 0;
                }

                if (_hasSplit)
                {
                    _splitPacketCount = ReadInt(true);
                    _splitPacketId    = ReadShort(true);
                    _splitPacketIndex = ReadInt(true);
                }
                else
                {
                    _splitPacketCount = -1;
                    _splitPacketId    = -1;
                    _splitPacketIndex = -1;
                }

                // Slurp the payload
                MessageLength = (int)Math.Ceiling((((double)dataBitLength) / 8));

                byte[] internalBuffer = ReadBytes(MessageLength);

                if (_hasSplit)
                {
                    SplitPartPacket splitPartPacket = SplitPartPacket.CreateObject();
                    splitPartPacket.DatagramSequenceNumber = _datagramSequenceNumber;
                    splitPartPacket.Reliability            = _reliability;
                    splitPartPacket.ReliableMessageNumber  = _reliableMessageNumber;
                    splitPartPacket.OrderingChannel        = _orderingChannel;
                    splitPartPacket.OrderingIndex          = _orderingIndex;
                    splitPartPacket.SplitId    = _splitPacketId;
                    splitPartPacket.SplitCount = _splitPacketCount;
                    splitPartPacket.SplitIdx   = _splitPacketIndex;
                    splitPartPacket.Id         = internalBuffer[0];
                    splitPartPacket.Message    = internalBuffer;
                    Messages.Add(splitPartPacket);

                    if (Log.IsDebugEnabled && _buffer.Position < _buffer.Length)
                    {
                        Log.Debug($"Got split message, but more to read {_buffer.Length - _buffer.Position}");
                    }
                    continue;
                }

                byte   id     = internalBuffer[0];
                Packet packet = PacketFactory.Create(id, internalBuffer, "raknet") ?? new UnknownPacket(id, internalBuffer);
                packet.DatagramSequenceNumber = _datagramSequenceNumber;
                packet.Reliability            = _reliability;
                packet.ReliableMessageNumber  = _reliableMessageNumber;
                packet.OrderingChannel        = _orderingChannel;
                packet.OrderingIndex          = _orderingIndex;

                //if (!(package is McpeBatch)) Log.Debug($"Raw: {package.DatagramSequenceNumber} {package.ReliableMessageNumber} {package.OrderingIndex} {package.GetType().Name} 0x{package.Id:x2} \n{HexDump(internalBuffer)}");

                Messages.Add(packet);
                if (Log.IsDebugEnabled && MessageLength != internalBuffer.Length)
                {
                    Log.Debug("Missmatch of requested lenght, and actual read lenght");
                }
            }
        }
示例#11
0
		public void EncapsulatedHeaderTest()
		{
			DatagramHeader header = new DatagramHeader(0x8c);
			Assert.AreEqual(true, header.isValid);
			Assert.AreEqual(false, header.isACK);
			Assert.AreEqual(false, header.isNAK);
			Assert.AreEqual(false, header.isPacketPair);
			Assert.AreEqual(false, header.hasBAndAS);
			Assert.AreEqual(true, header.isContinuousSend);
			Assert.AreEqual(true, header.needsBAndAs);
		}
示例#12
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];

            //Log.DebugFormat("Recieve {0} 0x{0:x2} len: {1}", msgId, receiveBytes.Length);

            if (msgId <= (byte) DefaultMessageIdTypes.ID_USER_PACKET_ENUM)
            {
                DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes) msgId;

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

                if (message == null) return;

                TraceReceive(message);

                switch (msgIdType)
                {
                    case DefaultMessageIdTypes.ID_UNCONNECTED_PONG:
                    {
                        UnconnectedPong incoming = (UnconnectedPong) message;
                        SendOpenConnectionRequest1();

                        break;
                    }
                    case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1:
                    {
                        OpenConnectionReply1 incoming = (OpenConnectionReply1) message;
                        _mtuSize = incoming.mtuSize;
                        //if (incoming.mtuSize < _mtuSize) throw new Exception("Error:" + incoming.mtuSize);
                        SendOpenConnectionRequest2();
                        break;
                    }
                    case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2:
                    {
                        OpenConnectionReply2 incoming = (OpenConnectionReply2) message;
                        //_mtuSize = incoming.mtuSize;
                        SendConnectionRequest();
                        break;
                    }
                }
            }
            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();
                    ConnectedPackage package = new ConnectedPackage();
                    package.Decode(receiveBytes);
                    //Log.Debug(">\tReceive Datagram #" + package._datagramSequenceNumber.IntValue());

                    var messages = package.Messages;

                    //Reliability reliability = package._reliability;
                    //if (reliability == Reliability.Reliable
                    //	|| reliability == Reliability.ReliableSequenced
                    //	|| reliability == Reliability.ReliableOrdered
                    //	)
                    {
                        // Send ACK
                        Acks ack = new Acks();
                        ack.acks.Add(package._datagramSequenceNumber.IntValue());
                        byte[] data = ack.Encode();
                        //Log.Info("Send ACK #" + package._datagramSequenceNumber.IntValue());
                        SendData(data, senderEndpoint);
                    }

                    //if (LoginSent) return; //HACK

                    foreach (var message in messages)
                    {
                        if (message is SplitPartPackage)
                        {
                            lock (Session.SyncRoot)
                            {
                                var splits = Session.Splits;
                                SplitPartPackage splitMessage = message as SplitPartPackage;

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

                                Log.DebugFormat("Got split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx);

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

                                SplitPartPackage[] spPackets = splits[spId];
                                if (spIdx < 0 || spIdx >= spPackets.Length)
                                {
                                    Log.DebugFormat("Unexpeted split package {2} (of {0}) for split ID: {1}", spCount, spId, spIdx);
                                    continue;
                                }

                                if (splitMessage.Message == null)
                                {
                                    Log.DebugFormat("Empty split package");
                                    continue;
                                }

                                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);
                                    }

                                    try
                                    {
                                        byte[] buffer = stream.ToArray();
                                        Log.DebugFormat("Processing split-message 0x{1:x2}, lenght={0}", buffer.Length, buffer[0]);
                                        Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer);
                                        HandlePackage(fullMessage, senderEndpoint);
                                        fullMessage.PutPool();
                                        continue;
                                    }
                                    catch (Exception e)
                                    {
                                        Log.Error("When processing split-message", e);
                                    }
                                }

                                message.PutPool();
                                continue;
                            }
                        }
                        else
                        {
                            message.Timer.Restart();
                            HandlePackage(message, senderEndpoint);
                            message.PutPool();
                        }
                    }

                    //package.PutPool();
                }
                else if (header.isPacketPair)
                {
                    Log.Warn("header.isPacketPair");
                }
                else if (header.isACK && header.isValid)
                {
                    HandleAck(receiveBytes, senderEndpoint);
                }
                else if (header.isNAK && header.isValid)
                {
                    Nak nak = new Nak();
                    nak.Decode(receiveBytes);
                    HandleNak(receiveBytes, senderEndpoint);
                }
                else if (!header.isValid)
                {
                    Log.Warn("!!!! ERROR, Invalid header !!!!!");
                }
                else
                {
                    Log.Warn("!! WHAT THE F");
                }
            }
        }