Ejemplo n.º 1
0
        public static McpeWrapper CreateBatchPacket(byte[] input, int offset, int length, CompressionLevel compressionLevel, bool writeLen)
        {
            var batch = McpeWrapper.CreateObject();

            batch.Id = 0xfe;

            batch.payload = Compression.Compress(input, offset, length, writeLen);

            //if (writeLen)
            //{
            //	var stream = MiNetServer.MemoryStreamManager.GetStream();
            //	WriteLength(stream, length);
            //	stream.Write(input, offset, length);
            //	batch.payload = stream.ToArray();
            //}
            //else
            //{
            //	byte[] target = new byte[length];
            //	Buffer.BlockCopy(input, offset, target, 0, length);
            //	batch.payload = target;
            //}

            batch.Encode();
            return(batch);
        }
Ejemplo n.º 2
0
        public static McpeWrapper CreateBatchPacket(Memory <byte> input, CompressionLevel compressionLevel, bool writeLen)
        {
            var batch = McpeWrapper.CreateObject();

            batch.payload = Compression.Compress(input, writeLen, compressionLevel);
            batch.Encode();             // prepare
            return(batch);
        }
Ejemplo n.º 3
0
        public static McpeWrapper CreateBatchPacket(Memory <byte> input, CompressionLevel compressionLevel, bool writeLen)
        {
            var batch = McpeWrapper.CreateObject();

            batch.ReliabilityHeader.Reliability = Reliability.ReliableOrdered;
            batch.payload = Compression.Compress(input, writeLen, input.Length > 1000 ? compressionLevel : CompressionLevel.NoCompression);
            batch.Encode();             // prepare
            return(batch);
        }
Ejemplo n.º 4
0
        public List <Packet> PrepareSend(List <Packet> packetsToSend)
        {
            var sendList    = new List <Packet>();
            var sendInBatch = new List <Packet>();

            foreach (Packet packet in packetsToSend)
            {
                // We must send forced clear messages in single message batch because
                // we can't mix them with un-encrypted messages for obvious reasons.
                // If need be, we could put these in a batch of it's own, but too rare
                // to bother.
                if (packet.ForceClear)
                {
                    var wrapper = McpeWrapper.CreateObject();
                    wrapper.ReliabilityHeader.Reliability = Reliability.ReliableOrdered;
                    wrapper.ForceClear = true;
                    wrapper.payload    = Compress(new List <Packet>()
                    {
                        packet
                    });
                    wrapper.Encode();                     // prepare
                    packet.PutPool();
                    sendList.Add(wrapper);
                    continue;
                }

                if (packet is McpeWrapper)
                {
                    packet.ReliabilityHeader.Reliability = Reliability.ReliableOrdered;
                    sendList.Add(packet);
                    continue;
                }

                if (!packet.IsMcpe)
                {
                    packet.ReliabilityHeader.Reliability = packet.ReliabilityHeader.Reliability != Reliability.Undefined ? packet.ReliabilityHeader.Reliability : Reliability.Reliable;
                    sendList.Add(packet);
                    continue;
                }

                packet.ReliabilityHeader.Reliability = Reliability.ReliableOrdered;

                sendInBatch.Add(packet);
            }

            if (sendInBatch.Count > 0)
            {
                var batch = McpeWrapper.CreateObject();
                batch.ReliabilityHeader.Reliability = Reliability.ReliableOrdered;
                batch.payload = Compress(sendInBatch);
                batch.Encode();                 // prepare
                sendList.Add(batch);
            }

            return(sendList);
        }
Ejemplo n.º 5
0
        public Packet HandleOrderedSend(Packet packet)
        {
            if (!packet.ForceClear && CryptoContext != null && CryptoContext.UseEncryption && packet is McpeWrapper wrapper)
            {
                var encryptedWrapper = McpeWrapper.CreateObject();
                encryptedWrapper.ReliabilityHeader.Reliability = Reliability.ReliableOrdered;
                encryptedWrapper.payload = CryptoUtils.Encrypt(wrapper.payload, CryptoContext);
                encryptedWrapper.Encode();

                return(encryptedWrapper);
            }

            return(packet);
        }
Ejemplo n.º 6
0
        public object Clone()
        {
            ChunkColumn cc = (ChunkColumn)MemberwiseClone();

            cc.chunks = new Chunk[16];
            for (int i = 0; i < chunks.Length; i++)
            {
                cc.chunks[i] = (Chunk)chunks[i].Clone();
            }

            cc.biomeId = (byte[])biomeId.Clone();
            cc.height  = (short[])height.Clone();

            cc.BlockEntities = new Dictionary <BlockCoordinates, NbtCompound>();
            foreach (KeyValuePair <BlockCoordinates, NbtCompound> blockEntityPair in BlockEntities)
            {
                cc.BlockEntities.Add(blockEntityPair.Key, (NbtCompound)blockEntityPair.Value.Clone());
            }

            if (_cache != null)
            {
                cc._cache = (byte[])_cache.Clone();
            }

            McpeWrapper batch = McpeWrapper.CreateObject();

            batch.payload = _cachedBatch.payload;
            batch.Encode();
            batch.MarkPermanent();

            cc._cachedBatch = batch;

            cc._cacheSync = new object();

            return(cc);
        }
Ejemplo n.º 7
0
        private static List <MessagePart> CreateMessageParts(Packet message, int mtuSize, Reliability reliability, RakSession session)
        {
            Memory <byte> encodedMessage = message.Encode();

            if (encodedMessage.IsEmpty)
            {
                return(new List <MessagePart>(0));
            }

            // All MCPE messages goes into a compressed (and possible encrypted) wrapper.
            // Note that McpeWrapper itself is a RakNet level message.
            bool isWrapper = message is McpeWrapper;

            if (message.IsMcpe)
            {
                var wrapper = McpeWrapper.CreateObject();
                wrapper.payload = Compression.Compress(encodedMessage, true, encodedMessage.Length > 1000 ? CompressionLevel.Fastest : CompressionLevel.NoCompression);
                encodedMessage  = wrapper.Encode();
                wrapper.PutPool();
                isWrapper = true;
            }

            // Should probably only force for McpeWrapper, not the other messages (RakNet)
            if (!(message is ConnectedPong) && !(message is DetectLostConnections))
            {
                reliability = Reliability.ReliableOrdered;
            }

            int orderingIndex = 0;

            lock (session.EncodeSync)
            {
                CryptoContext cryptoContext = session.CryptoContext;
                if (!message.ForceClear && cryptoContext != null && session.CryptoContext.UseEncryption && isWrapper)
                {
                    var wrapper = McpeWrapper.CreateObject();
                    wrapper.payload = CryptoUtils.Encrypt(encodedMessage.Slice(1), cryptoContext);
                    encodedMessage  = wrapper.Encode();
                    wrapper.PutPool();
                }

                if (reliability == Reliability.ReliableOrdered)
                {
                    orderingIndex = Interlocked.Increment(ref session.OrderingIndex);
                }
            }

            List <(int @from, int length)> splits = ArraySplit(encodedMessage.Length, mtuSize - 100);
            int count = splits.Count;

            if (count == 0)
            {
                Log.Warn("Got zero parts back from split");
            }
            if (count <= 1)
            {
                var messagePart = MessagePart.CreateObject();
                messagePart.ReliabilityHeader.Reliability           = reliability;
                messagePart.ReliabilityHeader.ReliableMessageNumber = Interlocked.Increment(ref session.ReliableMessageNumber);
                messagePart.ReliabilityHeader.OrderingChannel       = 0;
                messagePart.ReliabilityHeader.OrderingIndex         = orderingIndex;
                messagePart.ReliabilityHeader.HasSplit = false;
                messagePart.Buffer = encodedMessage;

                return(new List <MessagePart>(1)
                {
                    messagePart
                });
            }

            // Stupid but scared to change it .. remove the -100 when i feel "safe"
            if (session.SplitPartId > short.MaxValue - 100)
            {
                Interlocked.CompareExchange(ref session.SplitPartId, 0, short.MaxValue);
            }

            int   index        = 0;
            short splitId      = (short)Interlocked.Increment(ref session.SplitPartId);
            var   messageParts = new List <MessagePart>(count);

            foreach ((int from, int length)span in splits)
            {
                var messagePart = MessagePart.CreateObject();
                messagePart.ReliabilityHeader.Reliability           = reliability;
                messagePart.ReliabilityHeader.ReliableMessageNumber = Interlocked.Increment(ref session.ReliableMessageNumber);
                messagePart.ReliabilityHeader.OrderingChannel       = 0;
                messagePart.ReliabilityHeader.OrderingIndex         = orderingIndex;
                messagePart.ReliabilityHeader.HasSplit  = count > 1;
                messagePart.ReliabilityHeader.PartCount = count;
                messagePart.ReliabilityHeader.PartId    = splitId;
                messagePart.ReliabilityHeader.PartIndex = index++;
                messagePart.Buffer = encodedMessage.Slice(span.@from, span.length);

                messageParts.Add(messagePart);
            }

            return(messageParts);
        }