예제 #1
0
        public void Received(byte[] data)
        {
            if (!CheckVerify())
            {
                _session.Send(PacketFactory.CreateError("not verification"));
                _session.Close();
                return;
            }
            var package = PacketFactory.Create(data);

            _packetHandler.HandlePacket(package);
        }
예제 #2
0
 void TcpClient_Received(object sender, SocketEventArgs e)
 {
     try
     {
         LastActiveTime = DateTime.Now;
         var packet = PacketFactory.Create(e.Data);
         switch (packet.Version)
         {
         case 2:
             Packet2Handler(packet as Packet);
             break;
         }
     }
     catch (Exception ex)
     {
         logger.Error("ClientBase DataReceived error:{0}", ex);
     }
 }
예제 #3
0
        public override void Flush()
        {
            if (Closed)
            {
                throw new InvalidOperationException("Stream is closed");
            }

            if (Buf.Length > VBANPacket <T> .MaxSize)
            {
                throw new InvalidOperationException($"Buffer is too large, must be smaller than {VBANPacket<T>.MaxSize}");
            }

            VBANPacket <T> packet = PacketFactory.Create();

            packet.Data = Buf.Bytes;

            byte[] x;
            _client.Send(x = packet.Bytes, x.Length, IpEndPoint);

            Buf = new UnfinishedByteArray(VBANPacket <T> .MaxSize, true);
        }
예제 #4
0
        public override void Flush()
        {
            if (Closed)
            {
                throw new InvalidOperationException("Stream is closed");
            }

            if (Buf.Length > VBANPacket <T> .MaxSize)
            {
                throw new InvalidOperationException(
                          $"Buffer is too large, must be smaller than {VBANPacket<T>.MaxSize}");
            }

            var packet = PacketFactory.Create();

            packet.AttachData(Buf);

            byte[] x = packet;
            _client.Send(x, x.Length, IpEndPoint);

            Buf = new ByteArray();
        }
예제 #5
0
        private void SetupRequest(Request request)
        {
            switch (Context.ServiceContract.ConcurrencyMode)
            {
            case ConcurrencyMode.Single:
            case ConcurrencyMode.Reentrant:
            {
                var response = Response(request);
                var respPack = PacketFactory.Create(response);
                Session.Send(respPack);
            }
            break;

            case ConcurrencyMode.Multiple:
                ThreadPool.QueueUserWorkItem(obj =>
                {
                    var response = Response(request);
                    var packet   = PacketFactory.Create(response);
                    Session.Send(packet);
                }, null);
                break;
            }
        }
예제 #6
0
        private void HandleSplitMessage(PlayerNetworkSession playerSession, SplitPartPacket splitMessage)
        {
            int spId    = splitMessage.SplitId;
            int spIdx   = splitMessage.SplitIdx;
            int spCount = splitMessage.SplitCount;

            Int24       sequenceNumber        = splitMessage.DatagramSequenceNumber;
            Reliability reliability           = splitMessage.Reliability;
            Int24       reliableMessageNumber = splitMessage.ReliableMessageNumber;
            Int24       orderingIndex         = splitMessage.OrderingIndex;
            byte        orderingChannel       = splitMessage.OrderingChannel;

            SplitPartPacket[] spPackets;
            bool haveEmpty = false;

            // Need sync for this part since they come very fast, and very close in time.
            // If no synk, will often detect complete message two times (or more).
            lock (playerSession.Splits)
            {
                if (!playerSession.Splits.ContainsKey(spId))
                {
                    playerSession.Splits.TryAdd(spId, new SplitPartPacket[spCount]);
                }

                spPackets = playerSession.Splits[spId];
                if (spPackets[spIdx] != null)
                {
                    Log.Debug("Already had splitpart (resent). Ignore this part.");
                    return;
                }
                spPackets[spIdx] = splitMessage;

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

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

                SplitPartPacket[] waste;
                playerSession.Splits.TryRemove(spId, out waste);

                using (MemoryStream stream = MemoryStreamManager.GetStream())
                {
                    for (int i = 0; i < spPackets.Length; i++)
                    {
                        SplitPartPacket splitPartPacket = spPackets[i];
                        byte[]          buf             = splitPartPacket.Message;
                        if (buf == null)
                        {
                            Log.Error("Expected bytes in splitpart, but got none");
                            continue;
                        }

                        stream.Write(buf, 0, buf.Length);
                        splitPartPacket.PutPool();
                    }

                    byte[] buffer = stream.ToArray();
                    try
                    {
                        ConnectedPacket newPacket = ConnectedPacket.CreateObject();
                        newPacket._datagramSequenceNumber = sequenceNumber;
                        newPacket._reliability            = reliability;
                        newPacket._reliableMessageNumber  = reliableMessageNumber;
                        newPacket._orderingIndex          = orderingIndex;
                        newPacket._orderingChannel        = (byte)orderingChannel;
                        newPacket._hasSplit = false;

                        Packet fullMessage = PacketFactory.Create(buffer[0], buffer, "raknet") ??
                                             new UnknownPacket(buffer[0], buffer);
                        fullMessage.DatagramSequenceNumber = sequenceNumber;
                        fullMessage.Reliability            = reliability;
                        fullMessage.ReliableMessageNumber  = reliableMessageNumber;
                        fullMessage.OrderingIndex          = orderingIndex;
                        fullMessage.OrderingChannel        = orderingChannel;

                        newPacket.Messages = new List <Packet>();
                        newPacket.Messages.Add(fullMessage);

                        Log.Debug(
                            $"Assembled split packet {newPacket._reliability} message #{newPacket._reliableMessageNumber}, Chan: #{newPacket._orderingChannel}, OrdIdx: #{newPacket._orderingIndex}");
                        HandleConnectedPacket(playerSession, newPacket);
                        newPacket.PutPool();
                    }
                    catch (Exception e)
                    {
                        Log.Error("Error during split message parsing", e);
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"0x{buffer[0]:x2}\n{Packet.HexDump(buffer)}");
                        }
                        playerSession.Disconnect("Bad packet received from client.", false);
                    }
                }
            }
        }
예제 #7
0
        private void HandleRakNetMessage(byte[] receiveBytes, IPEndPoint senderEndpoint, byte msgId)
        {
            DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId;

            // Increase fast, decrease slow on 1s ticks.
            if (ServerInfo.NumberOfPlayers < ServerInfo.PlayerSessions.Count)
            {
                ServerInfo.NumberOfPlayers = ServerInfo.PlayerSessions.Count;
            }

            // Shortcut to reply fast, and no parsing
            if (msgIdType == DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1)
            {
                if (!GreylistManager.AcceptConnection(senderEndpoint.Address))
                {
                    var noFree = NoFreeIncomingConnections.CreateObject();
                    var bytes  = noFree.Encode();
                    noFree.PutPool();

                    TraceSend(noFree);

                    SendData(bytes, senderEndpoint);
                    Interlocked.Increment(ref ServerInfo.NumberOfDeniedConnectionRequestsPerSecond);
                    return;
                }
            }

            Packet message = null;

            try
            {
                try
                {
                    message = PacketFactory.Create(msgId, receiveBytes, "raknet");
                }
                catch (Exception)
                {
                    message = null;
                }

                if (message == null)
                {
                    GreylistManager.Blacklist(senderEndpoint.Address);
                    Log.ErrorFormat("Receive bad packet with ID: {0} (0x{0:x2}) {2} from {1}", msgId, senderEndpoint.Address, (DefaultMessageIdTypes)msgId);

                    return;
                }

                TraceReceive(message);

                switch (msgIdType)
                {
                case DefaultMessageIdTypes.ID_UNCONNECTED_PING:
                case DefaultMessageIdTypes.ID_UNCONNECTED_PING_OPEN_CONNECTIONS:
                {
                    HandleRakNetMessage(senderEndpoint, (UnconnectedPing)message);
                    break;
                }

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1:
                {
                    HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest1)message);
                    break;
                }

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_2:
                {
                    HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest2)message);
                    break;
                }

                default:
                    GreylistManager.Blacklist(senderEndpoint.Address);
                    if (Log.IsInfoEnabled)
                    {
                        Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) {2} from {1}", msgId, senderEndpoint.Address, (DefaultMessageIdTypes)msgId);
                    }
                    break;
                }
            }
            finally
            {
                if (message != null)
                {
                    message.PutPool();
                }
            }
        }
예제 #8
0
        internal void HandlePacket(Packet message, PlayerNetworkSession playerSession)
        {
            //SignalTick();

            try
            {
                if (message == null)
                {
                    return;
                }

                if (typeof(UnknownPacket) == message.GetType())
                {
                    UnknownPacket packet = (UnknownPacket)message;
                    if (Log.IsDebugEnabled)
                    {
                        Log.Warn($"Received unknown packet 0x{message.Id:X2}\n{Packet.HexDump(packet.Message)}");
                    }

                    message.PutPool();
                    return;
                }

                if (typeof(McpeWrapper) == message.GetType())
                {
                    McpeWrapper batch    = (McpeWrapper)message;
                    var         messages = new List <Packet>();

                    // Get bytes
                    byte[] payload = batch.payload;
                    if (playerSession.CryptoContext != null && playerSession.CryptoContext.UseEncryption)
                    {
                        payload = CryptoUtils.Decrypt(payload, playerSession.CryptoContext);
                    }


                    // Decompress bytes

                    MemoryStream stream = new MemoryStream(payload);
                    if (stream.ReadByte() != 0x78)
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Error($"Incorrect ZLib header. Expected 0x78 0x9C 0x{message.Id:X2}\n{Packet.HexDump(batch.payload)}");
                        }
                        if (Log.IsDebugEnabled)
                        {
                            Log.Error($"Incorrect ZLib header. Decrypted 0x{message.Id:X2}\n{Packet.HexDump(payload)}");
                        }
                        throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                    }
                    stream.ReadByte();
                    using (var deflateStream = new DeflateStream(stream, CompressionMode.Decompress, false))
                    {
                        // Get actual packet out of bytes
                        using (MemoryStream destination = MiNetServer.MemoryStreamManager.GetStream())
                        {
                            deflateStream.CopyTo(destination);
                            destination.Position = 0;

                            while (destination.Position < destination.Length)
                            {
                                int  len = (int)VarInt.ReadUInt32(destination);
                                long pos = destination.Position;
                                int  id  = (int)VarInt.ReadUInt32(destination);
                                len = (int)(len - (destination.Position - pos));                                  // calculate len of buffer after varint
                                byte[] internalBuffer = new byte[len];
                                destination.Read(internalBuffer, 0, len);

                                //if (Log.IsDebugEnabled)
                                //	Log.Debug($"0x{internalBuffer[0]:x2}\n{Packet.HexDump(internalBuffer)}");

                                try
                                {
                                    messages.Add(PacketFactory.Create((byte)id, internalBuffer, "mcpe") ??
                                                 new UnknownPacket((byte)id, internalBuffer));
                                }
                                catch (Exception e)
                                {
                                    if (Log.IsDebugEnabled)
                                    {
                                        Log.Warn($"Error parsing packet 0x{message.Id:X2}\n{Packet.HexDump(internalBuffer)}");
                                    }

                                    throw;
                                }
                            }

                            if (destination.Length > destination.Position)
                            {
                                throw new Exception("Have more data");
                            }
                        }
                    }
                    foreach (var msg in messages)
                    {
                        // Temp fix for performance, take 1.
                        var interact = msg as McpeInteract;
                        if (interact?.actionId == 4 && interact.targetRuntimeEntityId == 0)
                        {
                            continue;
                        }

                        msg.DatagramSequenceNumber = batch.DatagramSequenceNumber;
                        msg.Reliability            = batch.Reliability;
                        msg.ReliableMessageNumber  = batch.ReliableMessageNumber;
                        msg.OrderingChannel        = batch.OrderingChannel;
                        msg.OrderingIndex          = batch.OrderingIndex;
                        HandlePacket(msg, playerSession);
                    }

                    message.PutPool();
                    return;
                }

                MiNetServer.TraceReceive(message);

                if (CryptoContext != null && CryptoContext.UseEncryption)
                {
                    MiNetServer.FastThreadPool.QueueUserWorkItem(() =>
                    {
                        HandlePacket(MessageHandler, message as Packet);
                        message.PutPool();
                    });
                }
                else
                {
                    HandlePacket(MessageHandler, message);
                    message.PutPool();
                }
            }
            catch (Exception e)
            {
                Log.Error("Packet handling", e);
                throw;
            }
        }
예제 #9
0
        private IPacket PrivateReadPacket()
        {
            IPacket p = null;

            switch (SocketModeRx)
            {
            case Mode.Ascii:
            {
                p = new SshIdentification(pr.ReadLine().ToByteArray());
                break;
            }

            case Mode.PlainText:
            {
                ServerSequence++;
                int  packetLength  = pr.ReadInt32();
                byte paddingLength = pr.ReadByte();
                var  payload       = pr.ReadBytes(packetLength - paddingLength - 1);
                pr.ReadBytes(paddingLength);
                p = PacketFactory.Create(session, payload);
                break;
            }

            case Mode.CipherText:
            {
                if (Decryptor == null)
                {
                    session.KexProcessor.Wait();
                }

                int  packetLength  = pr.ReadInt32();
                byte paddingLength = pr.ReadByte();
                var  payload       = pr.ReadBytes(packetLength - paddingLength - 1);
                var  padding       = pr.ReadBytes(paddingLength);

                var hmac = DecryptorMac;
                hmac.WriteUInt32(ServerSequence++);
                hmac.WriteInt32(packetLength);
                hmac.Write(paddingLength);
                hmac.Write(payload);
                hmac.Write(padding);

                if (rxCompressionEnabled || (rxCompressionEnabled = IsRxCompressionEnabled()))
                {
                    if (RxZlibTransform == null)
                    {
                        RxZlibTransform = new ZlibTransform(CompressionMode.Decompress);
                    }

                    var length = RxZlibTransform.TransformBlock(payload, 0, payload.Length, zlibRxBuffer, 0);
                    Debug.WriteLine(string.Format("Compression In: In: {0}; Out: {1}; TotalIn: {2}; TotalOut: {3}; TotalRatio: {4}",
                                                  payload.Length, length, RxZlibTransform.TotalIn, RxZlibTransform.TotalOut, RxZlibTransform.Ratio));
                    payload = new byte[length];
                    Buffer.BlockCopy(zlibRxBuffer, 0, payload, 0, length);
                }

                // mac isn't encrypted, read directly from network stream
                byte[] mac = new byte[hmac.BlockSize];
                st.Read(mac, 0, hmac.BlockSize);

                if (!hmac.IsMatch(mac))
                {
                    throw new CryptographicException("MAC couldn't be verified!");
                }
                hmac.Reset();

                p = PacketFactory.Create(session, payload);
                break;
            }
            }

            if (p.Code == MessageCode.SSH_MSG_IDENTIFICATION)
            {
                SocketModeRx = Mode.PlainText;
            }
            if (p.Code == MessageCode.SSH_MSG_NEWKEYS)
            {
                SocketModeRx = Mode.CipherText;
            }
            return(p);
        }
예제 #10
0
        internal void HandleOfflineRakMessage(ReadOnlyMemory <byte> receiveBytes, IPEndPoint senderEndpoint)
        {
            byte messageId   = receiveBytes.Span[0];
            var  messageType = (DefaultMessageIdTypes)messageId;

            // Increase fast, decrease slow on 1s ticks.
            if (_connectionInfo.NumberOfPlayers < _connectionInfo.RakSessions.Count)
            {
                _connectionInfo.NumberOfPlayers = _connectionInfo.RakSessions.Count;
            }

            // Shortcut to reply fast, and no parsing
            if (messageType == DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1)
            {
                if (!_greyListManager.AcceptConnection(senderEndpoint.Address))
                {
                    var noFree = NoFreeIncomingConnections.CreateObject();
                    var bytes  = noFree.Encode();

                    TraceSend(noFree);

                    noFree.PutPool();

                    _sender.SendData(bytes, senderEndpoint);
                    Interlocked.Increment(ref _connectionInfo.NumberOfDeniedConnectionRequestsPerSecond);
                    return;
                }
            }

            Packet message = null;

            try
            {
                try
                {
                    message = PacketFactory.Create(messageId, receiveBytes, "raknet");
                }
                catch (Exception)
                {
                    message = null;
                }

                if (message == null)
                {
                    _greyListManager.Blacklist(senderEndpoint.Address);
                    Log.Error($"Receive bad packet with ID: {messageId} (0x{messageId:x2}) {messageType} from {senderEndpoint.Address}");

                    return;
                }

                TraceReceive(Log, message);

                switch (messageType)
                {
                case DefaultMessageIdTypes.ID_NO_FREE_INCOMING_CONNECTIONS:
                    // Stop this client connection
                    _connection.Stop();
                    break;

                case DefaultMessageIdTypes.ID_UNCONNECTED_PING:
                case DefaultMessageIdTypes.ID_UNCONNECTED_PING_OPEN_CONNECTIONS:
                    HandleRakNetMessage(senderEndpoint, (UnconnectedPing)message);
                    break;

                case DefaultMessageIdTypes.ID_UNCONNECTED_PONG:
                    HandleRakNetMessage(senderEndpoint, (UnconnectedPong)message);
                    break;

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1:
                    HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest1)message);
                    break;

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1:
                    HandleRakNetMessage(senderEndpoint, (OpenConnectionReply1)message);
                    break;

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_2:
                    HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest2)message);
                    break;

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2:
                    HandleRakNetMessage(senderEndpoint, (OpenConnectionReply2)message);
                    break;

                default:
                    _greyListManager.Blacklist(senderEndpoint.Address);
                    if (Log.IsInfoEnabled)
                    {
                        Log.Error($"Receive unexpected packet with ID: {messageId} (0x{messageId:x2}) {messageType} from {senderEndpoint.Address}");
                    }
                    break;
                }
            }
            finally
            {
                message?.PutPool();
            }
        }
예제 #11
0
        internal void HandleOfflineRakMessage(ReadOnlyMemory <byte> receiveBytes, IPEndPoint senderEndpoint)
        {
            byte messageId   = receiveBytes.Span[0];
            var  messageType = (DefaultMessageIdTypes)messageId;

            // Increase fast, decrease slow on 1s ticks.
            //if (_connectionInfo.NumberOfPlayers < _connectionInfo.RakSessions.Count) _connectionInfo.NumberOfPlayers = _connectionInfo.RakSessions.Count;

            Packet message = null;

            try
            {
                try
                {
                    message = PacketFactory.Create(messageId, receiveBytes, "raknet");
                }
                catch (Exception)
                {
                    message = null;
                }

                if (message == null)
                {
                    Log.Error($"Receive bad packet with ID: {messageId} (0x{messageId:x2}) {messageType} from {senderEndpoint.Address}");

                    return;
                }

                //	TraceReceive(Log, message);

                switch (messageType)
                {
                case DefaultMessageIdTypes.ID_NO_FREE_INCOMING_CONNECTIONS:
                    // Stop this client connection
                    _connection.Stop();
                    break;

                case DefaultMessageIdTypes.ID_UNCONNECTED_PING:
                case DefaultMessageIdTypes.ID_UNCONNECTED_PING_OPEN_CONNECTIONS:
                    HandleRakNetMessage(senderEndpoint, (UnconnectedPing)message);
                    break;

                case DefaultMessageIdTypes.ID_UNCONNECTED_PONG:
                    HandleRakNetMessage(senderEndpoint, (UnconnectedPong)message);
                    break;

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1:
                    //HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest1) message);
                    break;

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_1:
                    HandleRakNetMessage(senderEndpoint, (OpenConnectionReply1)message);
                    break;

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_2:
                    //HandleRakNetMessage(senderEndpoint, (OpenConnectionRequest2) message);
                    break;

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REPLY_2:
                    HandleRakNetMessage(senderEndpoint, (OpenConnectionReply2)message);
                    break;

                default:
                    if (Log.IsInfoEnabled)
                    {
                        Log.Error($"Receive unexpected packet with ID: {messageId} (0x{messageId:x2}) {messageType} from {senderEndpoint.Address}");
                    }
                    break;
                }
            }
            finally
            {
                message?.PutPool();
            }
        }
        public void HandlePacket(Packet message)
        {
            if (message is McpeWrapper wrapper)
            {
                var messages = new List <Packet>();

                // Get bytes to process
                ReadOnlyMemory <byte> payload = wrapper.payload;

                // Decrypt bytes

                if (CryptoContext != null && CryptoContext.UseEncryption)
                {
                    // This call copies the entire buffer, but what can we do? It is kind of compensated by not
                    // creating a new buffer when parsing the packet (only a mem-slice)
                    payload = CryptoUtils.Decrypt(payload, CryptoContext);
                }

                // Decompress bytes

                var stream = new MemoryStreamReader(payload.Slice(0, payload.Length - 4));                 // slice away adler
                if (stream.ReadByte() != 0x78)
                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.Error($"Incorrect ZLib header. Expected 0x78 0x9C 0x{wrapper.Id:X2}\n{Packet.HexDump(wrapper.payload)}");
                    }
                    if (Log.IsDebugEnabled)
                    {
                        Log.Error($"Incorrect ZLib header. Decrypted 0x{wrapper.Id:X2}\n{Packet.HexDump(payload)}");
                    }
                    throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                }
                stream.ReadByte();
                using (var deflateStream = new DeflateStream(stream, CompressionMode.Decompress, false))
                {
                    using var s = new MemoryStream();
                    deflateStream.CopyTo(s);
                    s.Position = 0;

                    int count = 0;
                    // Get actual packet out of bytes
                    while (s.Position < s.Length)
                    {
                        count++;

                        uint len = VarInt.ReadUInt32(s);
                        ReadOnlyMemory <byte> internalBuffer = s.GetBuffer().AsMemory((int)s.Position, (int)len);
                        s.Position += len;
                        int id = internalBuffer.Span[0];

                        //if (Log.IsDebugEnabled)
                        //	Log.Debug($"0x{internalBuffer[0]:x2}\n{Packet.HexDump(internalBuffer)}");

                        try
                        {
                            messages.Add(PacketFactory.Create((byte)id, internalBuffer, "mcpe") ??
                                         new UnknownPacket((byte)id, internalBuffer));
                        }
                        catch (Exception)
                        {
                            if (Log.IsDebugEnabled)
                            {
                                Log.Warn($"Error parsing bedrock message #{count} id={id}\n{Packet.HexDump(internalBuffer)}");
                            }
                            //throw;
                            return;                             // Exit, but don't crash.
                        }
                    }

                    if (s.Length > s.Position)
                    {
                        throw new Exception("Have more data");
                    }
                }

                foreach (Packet msg in messages)
                {
                    // Temp fix for performance, take 1.
                    //var interact = msg as McpeInteract;
                    //if (interact?.actionId == 4 && interact.targetRuntimeEntityId == 0) continue;

                    msg.ReliabilityHeader = new ReliabilityHeader()
                    {
                        Reliability           = wrapper.ReliabilityHeader.Reliability,
                        ReliableMessageNumber = wrapper.ReliabilityHeader.ReliableMessageNumber,
                        OrderingChannel       = wrapper.ReliabilityHeader.OrderingChannel,
                        OrderingIndex         = wrapper.ReliabilityHeader.OrderingIndex,
                    };

                    RakOfflineHandler.TraceReceive(Log, msg);
                    try
                    {
                        HandleCustomPacket(msg);
                    }
                    catch (Exception e)
                    {
                        Log.Warn($"Bedrock message handler error", e);
                    }
                }

                wrapper.PutPool();
            }
            else if (message is UnknownPacket unknownPacket)
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Warn($"Received unknown packet 0x{unknownPacket.Id:X2}\n{Packet.HexDump(unknownPacket.Message)}");
                }

                unknownPacket.PutPool();
            }
            else
            {
                Log.Error($"Unhandled packet: {message.GetType().Name} 0x{message.Id:X2} for user: {_session.Username}, IP {_session.EndPoint.Address}");
                if (Log.IsDebugEnabled)
                {
                    Log.Warn($"Unknown packet 0x{message.Id:X2}\n{Packet.HexDump(message.Bytes)}");
                }
            }
        }
예제 #13
0
        protected override void DecodePacket()
        {
            _reader.Position = 0;

            Header = new InternalDatagramHeader(ReadByte());
            Header.DatagramSequenceNumber = ReadLittle();

            // End datagram, online packet starts

            Messages = new List <Packet>();

            while (!_reader.Eof)
            {
                byte flags  = ReadByte();
                var  header = new ReliabilityHeader();

                header.Reliability = (Reliability)((flags & 0b011100000) >> 5);
                header.HasSplit    = (flags & 0b00010000) > 0;

                short dataBitLength = ReadShort(true);

                switch (header.Reliability)
                {
                case Reliability.Reliable:
                case Reliability.ReliableSequenced:
                case Reliability.ReliableOrdered:
                    header.ReliableMessageNumber = ReadLittle();
                    break;
                }

                switch (header.Reliability)
                {
                case Reliability.UnreliableSequenced:
                case Reliability.ReliableSequenced:
                    header.SequencingIndex = ReadLittle();
                    break;
                }

                switch (header.Reliability)
                {
                case Reliability.UnreliableSequenced:
                case Reliability.ReliableSequenced:
                case Reliability.ReliableOrdered:
                case Reliability.ReliableOrderedWithAckReceipt:
                    header.OrderingIndex   = ReadLittle();
                    header.OrderingChannel = ReadByte();                             // flags
                    break;
                }

                if (header.HasSplit)
                {
                    header.PartCount = ReadInt(true);
                    header.PartId    = ReadShort(true);
                    header.PartIndex = ReadInt(true);
                }

                // Slurp the payload
                int messageLength = (int)Math.Ceiling((((double)dataBitLength) / 8));
                ReadOnlyMemory <byte> internalBuffer = Slice(messageLength);
                if (internalBuffer.Length != messageLength)
                {
                    Log.Error($"Didn't get expected length {internalBuffer.Length}");
                }
                if (internalBuffer.Length == 0)
                {
                    continue;                                              //Log.Error($"Read length {internalBuffer.Length}, expected {messageLength}");
                }
                if (messageLength == 0)
                {
                    continue;
                }
                //if(header.Reliability != Reliability.ReliableOrdered) Log.Error($"Parsing message {internalBuffer.Span[0]} with reliability={header.Reliability}");

                if (header.HasSplit)
                {
                    var splitPartPacket = SplitPartPacket.CreateObject();
                    splitPartPacket.ReliabilityHeader = header;
                    splitPartPacket.Id      = internalBuffer.Span[0];
                    splitPartPacket.Message = internalBuffer;
                    Messages.Add(splitPartPacket);

                    if (Log.IsDebugEnabled && _reader.Position < _reader.Length)
                    {
                        Log.Debug($"Got split message, but more to read {_reader.Length - _reader.Position}");
                    }
                }
                else
                {
                    byte   id     = internalBuffer.Span[0];
                    Packet packet = PacketFactory.Create(id, internalBuffer, "raknet") ?? new UnknownPacket(id, internalBuffer.ToArray());
                    packet.ReliabilityHeader = header;

                    Messages.Add(packet);
                }

                if (Log.IsDebugEnabled && messageLength != internalBuffer.Length)
                {
                    Log.Debug("Mismatch of requested length, and actual read length");
                }
            }
        }
예제 #14
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");
                }
            }
        }
예제 #15
0
        public void HandlePacket(Packet message)
        {
            if (message is McpeWrapper wrapper)
            {
                var messages = new LinkedList <Packet>();

                // Get bytes to process
                var payload = wrapper.payload.ToArray();

                // Decrypt bytes


                if (CryptoContext != null && CryptoContext.UseEncryption)
                {
                    FirstEncryptedPacketWaitHandle.Set();

                    payload = CryptoUtils.Decrypt(payload, CryptoContext);

                    _hasEncrypted = true;
                }

                //var stream = new MemoryStreamReader(payload);
                using (var deflateStream = new DeflateStream(new MemoryStream(payload), System.IO.Compression.CompressionMode.Decompress, false))
                {
                    using var s = new MemoryStream();
                    deflateStream.CopyTo(s);
                    s.Position = 0;

                    int count = 0;
                    // Get actual packet out of bytes
                    while (s.Position < s.Length)
                    {
                        count++;

                        uint len = VarInt.ReadUInt32(s);
                        long pos = s.Position;
                        ReadOnlyMemory <byte> internalBuffer = s.GetBuffer().AsMemory((int)s.Position, (int)len);
                        int id = VarInt.ReadInt32(s);

                        Packet packet = null;
                        try
                        {
                            packet = PacketFactory.Create((byte)id, internalBuffer, "mcpe")
                                     ?? new UnknownPacket((byte)id, internalBuffer);

                            //Hack for some servers that screw up the order.
                            //	if (packet is McpePlayerList)
                            //	{
                            //		messages.AddFirst(packet);
                            //	}
                            //	else
                            {
                                messages.AddLast(packet);
                            }

                            //var a = 0x91;
                        }
                        catch (Exception e)
                        {
                            Log.Warn(e, $"Error parsing bedrock message #{count} id={id}\n{Packet.HexDump(internalBuffer)}");
                            //throw;
                            return;                             // Exit, but don't crash.
                        }

                        s.Position = pos + len;
                    }

                    if (s.Length > s.Position)
                    {
                        throw new Exception("Have more data");
                    }
                }

                //var msgs = messages.ToArray();
                //messages.Clear();


                foreach (Packet msg in messages)
                {
                    msg.ReliabilityHeader = new ReliabilityHeader()
                    {
                        Reliability           = wrapper.ReliabilityHeader.Reliability,
                        ReliableMessageNumber = wrapper.ReliabilityHeader.ReliableMessageNumber,
                        OrderingChannel       = wrapper.ReliabilityHeader.OrderingChannel,
                        OrderingIndex         = wrapper.ReliabilityHeader.OrderingIndex,
                        SequencingIndex       = wrapper.ReliabilityHeader.SequencingIndex
                    };

                    try
                    {
                        HandleGamePacket(msg);
                    }
                    catch (Exception e)
                    {
                        Log.Warn(e, $"Bedrock message handler error");
                    }
                }

                wrapper.PutPool();
            }
            else if (message is UnknownPacket unknownPacket)
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Warn($"Received unknown packet 0x{unknownPacket.Id:X2}\n{Packet.HexDump(unknownPacket.Message)}");
                }

                unknownPacket.PutPool();
            }
            else
            {
                Log.Error($"Unhandled packet: {message.GetType().Name} 0x{message.Id:X2} for user: {_session.Username}, IP {_session.EndPoint.Address}");
                if (Log.IsDebugEnabled)
                {
                    Log.Warn($"Unknown packet 0x{message.Id:X2}\n{Packet.HexDump(message.Bytes)}");
                }
            }
        }
예제 #16
0
 private void Parse()
 {
     ParsedPacket = PacketFactory.Create(_bits);
     Consumed     = ParsedPacket.Consumed;
 }