예제 #1
0
    void SendConnected(uint clientId, IPEndPoint iPEndPoint)
    {
        ConnectedPacket packet = new ConnectedPacket();

        packet.payload.clientId = clientId;
        PacketManager.Instance.SendPacketToClient(packet, iPEndPoint);
    }
예제 #2
0
        private void HandleConnectedPacket(PlayerNetworkSession playerSession, ConnectedPacket packet)
        {
            foreach (var message in packet.Messages)
            {
                if (message is SplitPartPacket)
                {
                    HandleSplitMessage(playerSession, (SplitPartPacket)message);
                    continue;
                }

                message.Timer.Restart();
                HandlePacket(message, playerSession);
            }
        }
예제 #3
0
    void OnConnected(Stream stream, IPEndPoint iPEndPoint)
    {
        if (!NetworkManager.Instance.isServer && state != State.Connected)
        {
            ConnectedPacket packet = new ConnectedPacket();
            packet.Deserialize(stream);

            if (packet.payload.clientId == clientId)
            {
                state = State.Connected;
                if (onConnect != null)
                {
                    onConnect(true);
                    onConnect = null;
                }
            }
        }
    }
예제 #4
0
        private static void ProcessMessage(MiNetServer server, ReadOnlyMemory <byte> receivedBytes, IPEndPoint clientEndpoint)
        {
            var header = new DatagramHeader(receivedBytes.Span[0]);

            if (!header.IsValid)
            {
                // We parse as an offline message. This is not actually correct, but works.

                byte messageId = receivedBytes.Span[0];

                if (messageId <= (byte)DefaultMessageIdTypes.ID_USER_PACKET_ENUM)
                {
                    RakNetProcessor.HandleOfflineRakMessage(server, receivedBytes, clientEndpoint, messageId, server.ServerInfo);
                }
                else
                {
                    Log.Warn($"Receive invalid message, but not a RakNet message. Message ID={messageId}. Ignoring.");
                }

                return;
            }

            if (!server._rakNetSessions.TryGetValue(clientEndpoint, out RakSession rakNetSession))
            {
                //Log.DebugFormat("Receive MCPE message 0x{1:x2} without session {0}", senderEndpoint.Address, msgId);
                //if (!_badPacketBans.ContainsKey(senderEndpoint.Address))
                //{
                //	_badPacketBans.Add(senderEndpoint.Address, true);
                //}
                return;
            }

            if (rakNetSession.MessageHandler == null)
            {
                Log.ErrorFormat("Receive online message without message handler for IP={0}. Session removed.", clientEndpoint.Address);
                server._rakNetSessions.TryRemove(clientEndpoint, out rakNetSession);
                //if (!_badPacketBans.ContainsKey(senderEndpoint.Address))
                //{
                //	_badPacketBans.Add(senderEndpoint.Address, true);
                //}
                return;
            }

            if (rakNetSession.Evicted)
            {
                return;
            }

            rakNetSession.LastUpdatedTime = DateTime.UtcNow;

            if (header.IsAck)
            {
                rakNetSession.HandleAck(receivedBytes, server.ServerInfo);
                return;
            }

            if (header.IsNak)
            {
                rakNetSession.HandleNak(receivedBytes, server.ServerInfo);
                return;
            }

            var datagram = ConnectedPacket.CreateObject();

            try
            {
                datagram.Decode(receivedBytes);
            }
            catch (Exception e)
            {
                rakNetSession.Disconnect("Bad packet received from client.");

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

                server.GreylistManager.Blacklist(clientEndpoint.Address);

                return;
            }

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

            //Reliability reliability = packet._reliability;
            //if (reliability == Reliability.Reliable
            //	|| reliability == Reliability.ReliableSequenced
            //	|| reliability == Reliability.ReliableOrdered
            //	)
            {
                server.EnqueueAck(rakNetSession, datagram.Header.DatagramSequenceNumber);
            }

            rakNetSession.HandleDatagram(datagram);
            datagram.PutPool();
        }
예제 #5
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);
                    }
                }
            }
        }
예제 #6
0
        private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint)
        {
            byte msgId = receiveBytes[0];

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

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

                if (playerSession.Evicted)
                {
                    return;
                }

                playerSession.LastUpdatedTime = DateTime.UtcNow;

                DatagramHeader header = new DatagramHeader(receiveBytes[0]);
                if (!header.isACK && !header.isNAK && header.isValid)
                {
                    if (receiveBytes[0] == 0xa0)
                    {
                        throw new Exception("Receive ERROR, NAK in wrong place");
                    }

                    ConnectedPacket packet = ConnectedPacket.CreateObject();
                    try
                    {
                        packet.Decode(receiveBytes);
                    }
                    catch (Exception e)
                    {
                        playerSession.Disconnect("Bad packet received from client.");

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

                        GreylistManager.Blacklist(senderEndpoint.Address);

                        return;
                    }


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

                    //Reliability reliability = packet._reliability;
                    //if (reliability == Reliability.Reliable
                    //	|| reliability == Reliability.ReliableSequenced
                    //	|| reliability == Reliability.ReliableOrdered
                    //	)
                    {
                        EnqueueAck(playerSession, packet._datagramSequenceNumber);
                        //if (Log.IsDebugEnabled) Log.Debug("ACK on #" + packet._datagramSequenceNumber.IntValue());
                    }

                    HandleConnectedPacket(playerSession, packet);
                    packet.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 !!!!!");
                }
            }
        }
예제 #7
0
 public void ConnectedPacket_encode_basic_ok()
 {
     ConnectedPacket packet = new ConnectedPacket();
     //packet.Decode();
 }