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