Пример #1
0
        private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage, Player player)
        {
            int spId    = package._splitPacketId;
            int spIdx   = package._splitPacketIndex;
            int spCount = package._splitPacketCount;

            if (!playerSession.Splits.ContainsKey(spId))
            {
                playerSession.Splits.TryAdd(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);

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

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

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

                byte[] buffer = stream.ToArray();
                try
                {
                    Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer);
                    fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber;
                    fullMessage.ReliableMessageNumber  = package._reliableMessageNumber;
                    fullMessage.OrderingChannel        = package._orderingChannel;
                    fullMessage.OrderingIndex          = package._orderingIndex;
                    HandlePackage(fullMessage, playerSession);
                    fullMessage.PutPool();
                }
                catch (Exception e)
                {
                    player.Disconnect("Bad package received from client.");
                }
            }
        }
Пример #2
0
        private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage)
        {
            int spId    = package._splitPacketId;
            int spIdx   = package._splitPacketIndex;
            int spCount = package._splitPacketCount;

            if (!playerSession.Splits.ContainsKey(spId))
            {
                playerSession.Splits.TryAdd(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);

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

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

                byte[] buffer = stream.ToArray();

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

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

                if (!(fullMessage is McpeBatch))
                {
                    Log.Debug($"Split: {fullMessage.GetType().Name} 0x{fullMessage.Id:x2} \n{Package.HexDump(buffer)}");
                }

                HandlePackage(fullMessage);
                fullMessage.PutPool();
            }
        }
Пример #3
0
        private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage)
        {
            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++)
                {
                    SplitPartPackage splitPartPackage = spPackets[i];
                    byte[]           buf = splitPartPackage.Message;
                    stream.Write(buf, 0, buf.Length);
                    splitPartPackage.PutPool();
                }

                playerSession.Splits.Remove(spId);

                byte[] buffer = stream.ToArray();

                Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer);
                fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber;
                fullMessage.OrderingChannel        = package._orderingChannel;
                fullMessage.OrderingIndex          = package._orderingIndex;
                HandlePackage(fullMessage);
                fullMessage.PutPool();
            }
        }
Пример #4
0
        private void HandleSplitMessage(PlayerNetworkSession playerSession, SplitPartPackage 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;

            SplitPartPackage[] 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 SplitPartPackage[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 packages for split ID: {1}", spCount, spId);

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

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

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

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

                        Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer, "raknet") ??
                                              new UnknownPackage(buffer[0], buffer);
                        fullMessage.DatagramSequenceNumber = sequenceNumber;
                        fullMessage.Reliability            = reliability;
                        fullMessage.ReliableMessageNumber  = reliableMessageNumber;
                        fullMessage.OrderingIndex          = orderingIndex;
                        fullMessage.OrderingChannel        = orderingChannel;

                        newPackage.Messages = new List <Package>();
                        newPackage.Messages.Add(fullMessage);

                        Log.Debug(
                            $"Assembled split package {newPackage._reliability} message #{newPackage._reliableMessageNumber}, Chan: #{newPackage._orderingChannel}, OrdIdx: #{newPackage._orderingIndex}");
                        HandleConnectedPackage(playerSession, newPackage);
                        newPackage.PutPool();
                    }
                    catch (Exception e)
                    {
                        Log.Error("Error during split message parsing", e);
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"0x{buffer[0]:x2}\n{Package.HexDump(buffer)}");
                        }
                        playerSession.Disconnect("Bad package received from client.", false);
                    }
                }
            }
        }
Пример #5
0
		private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage, Player player)
		{
			int spId = package._splitPacketId;
			int spIdx = package._splitPacketIndex;
			int spCount = package._splitPacketCount;

			if (!playerSession.Splits.ContainsKey(spId))
			{
				playerSession.Splits.TryAdd(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);

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

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

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

				byte[] buffer = stream.ToArray();
				try
				{
					Package fullMessage = PackageFactory.CreatePackage(buffer[1], buffer) ?? new UnknownPackage(buffer[1], buffer);
					Log.Debug($"0x{fullMessage.Id:x2}\n{Package.HexDump(buffer)}");

					fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber;
					fullMessage.ReliableMessageNumber = package._reliableMessageNumber;
					fullMessage.OrderingChannel = package._orderingChannel;
					fullMessage.OrderingIndex = package._orderingIndex;
					HandlePackage(fullMessage, playerSession);
					fullMessage.PutPool();
				}
				catch (Exception e)
				{
					player.Disconnect("Bad package received from client.");
				}
			}
		}
Пример #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, _listener);
                    break;
                }

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

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

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

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

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

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

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

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

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

                        _playerSessions.TryAdd(senderEndpoint, session);
                    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    package.PutPool();
                }
                else if (header.isACK && header.isValid)
                {
                    HandleAck(receiveBytes, senderEndpoint);
                }
                else if (header.isNAK && header.isValid)
                {
                    HandleNak(receiveBytes, senderEndpoint);
                }
                else if (!header.isValid)
                {
                    Log.Warn("!!!! ERROR, Invalid header !!!!!");
                }
            }
        }
Пример #7
0
        private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage)
        {
            int spId = package._splitPacketId;
            int spIdx = package._splitPacketIndex;
            int spCount = package._splitPacketCount;

            if (!playerSession.Splits.ContainsKey(spId))
            {
                playerSession.Splits.TryAdd(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);

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

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

                byte[] buffer = stream.ToArray();

                Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer);
                fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber;
                fullMessage.OrderingChannel = package._orderingChannel;
                fullMessage.OrderingIndex = package._orderingIndex;
                HandlePackage(fullMessage);
                fullMessage.PutPool();
            }
        }
Пример #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
        /// <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");
                }
            }
        }
Пример #10
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);

                    Log.Warn("!!!! NAK !!!!!" + nak.sequenceNumber.IntValue());
                    HandleNak(receiveBytes, senderEndpoint);
                }
                else if (!header.isValid)
                {
                    Log.Warn("!!!! ERROR, Invalid header !!!!!");
                }
                else
                {
                    Log.Warn("!! WHAT THE F");
                }
            }
        }
Пример #11
0
        private void DelayedProcessing(PlayerNetworkSession playerSession, ConnectedPackage package)
        {
            Player player = playerSession.Player;

            if (ForwardAllPlayers)
            {
                player.SendPackage(new McpeTransfer
                {
                    endpoint = ForwardTarget
                }, true);

                return;
            }

            List <Package> messages = package.Messages;

            foreach (var message in messages)
            {
                message.DatagramSequenceNumber = package._datagramSequenceNumber;
                message.OrderingChannel        = package._orderingChannel;
                message.OrderingIndex          = package._orderingIndex;

                if (message is SplitPartPackage)
                {
                    message.Source = "Receive 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++)
                        {
                            SplitPartPackage splitPartPackage = spPackets[i];
                            byte[]           buf = splitPartPackage.Message;
                            stream.Write(buf, 0, buf.Length);
                            splitPartPackage.PutPool();
                        }

                        playerSession.Splits.Remove(spId);

                        byte[] buffer = stream.ToArray();
                        try
                        {
                            Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer);
                            fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber;
                            fullMessage.OrderingChannel        = package._orderingChannel;
                            fullMessage.OrderingIndex          = package._orderingIndex;
                            HandlePackage(fullMessage, playerSession);
                            fullMessage.PutPool();
                        }
                        catch (Exception e)
                        {
                            player.Disconnect("Bad package received from client.");
                        }
                    }

                    continue;
                }

                message.Timer.Restart();
                HandlePackage(message, playerSession);
                message.PutPool();                 // Handled in HandlePacket now()
            }
        }
Пример #12
0
        private void HandleSplitMessage(PlayerNetworkSession playerSession, ConnectedPackage package, SplitPartPackage splitMessage, Player player)
        {
            int spId    = package._splitPacketId;
            int spIdx   = package._splitPacketIndex;
            int spCount = package._splitPacketCount;

            if (!playerSession.Splits.ContainsKey(spId))
            {
                playerSession.Splits.TryAdd(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);

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

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

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

                byte[] buffer = stream.ToArray();
                try
                {
                    ConnectedPackage newPackage = ConnectedPackage.CreateObject();
                    newPackage._datagramSequenceNumber = package._datagramSequenceNumber;
                    newPackage._reliability            = package._reliability;
                    newPackage._reliableMessageNumber  = package._reliableMessageNumber;
                    newPackage._sequencingIndex        = package._sequencingIndex;
                    newPackage._orderingIndex          = package._orderingIndex;
                    newPackage._orderingChannel        = package._orderingChannel;
                    newPackage._hasSplit = false;

                    Package fullMessage = PackageFactory.CreatePackage(buffer[0], buffer, "raknet") ?? new UnknownPackage(buffer[0], buffer);
                    fullMessage.DatagramSequenceNumber = package._datagramSequenceNumber;
                    fullMessage.Reliability            = package._reliability;
                    fullMessage.ReliableMessageNumber  = package._reliableMessageNumber;
                    fullMessage.OrderingIndex          = package._orderingIndex;
                    fullMessage.OrderingChannel        = package._orderingChannel;

                    newPackage.Messages = new List <Package>();
                    newPackage.Messages.Add(fullMessage);

                    Log.Debug($"Assembled split package {newPackage._reliability} message #{newPackage._reliableMessageNumber}, Chan: #{newPackage._orderingChannel}, OrdIdx: #{newPackage._orderingIndex}");
                    HandleConnectedPackage(playerSession, newPackage);
                    newPackage.PutPool();
                }
                catch (Exception e)
                {
                    Log.Error("Error during split message parsing", e);
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"0x{buffer[0]:x2}\n{Package.HexDump(buffer)}");
                    }
                    player.Disconnect("Bad package received from client.");
                }
            }
        }