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; } }
internal void HandlePackage(Package message, PlayerNetworkSession playerSession) { //SignalTick(); try { if (message == null) { return; } if (typeof(UnknownPackage) == message.GetType()) { UnknownPackage packet = (UnknownPackage)message; if (Log.IsDebugEnabled) { Log.Warn($"Received unknown package 0x{message.Id:X2}\n{Package.HexDump(packet.Message)}"); } message.PutPool(); return; } if (typeof(McpeWrapper) == message.GetType()) { McpeWrapper batch = (McpeWrapper)message; var messages = new List <Package>(); // Get bytes byte[] payload = batch.payload; if (playerSession.CryptoContext != null && playerSession.CryptoContext.UseEncryption) { throw new Exception("No crypto enabled"); } // 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 using (MemoryStream destination = MiNetServer.MemoryStreamManager.GetStream()) { defStream2.CopyTo(destination); destination.Position = 0; NbtBinaryReader reader = new NbtBinaryReader(destination, true); while (destination.Position < destination.Length) { //int len = reader.ReadInt32(); int len = BatchUtils.ReadLength(destination); byte[] internalBuffer = reader.ReadBytes(len); //if (Log.IsDebugEnabled) // Log.Debug($"0x{internalBuffer[0]:x2}\n{Package.HexDump(internalBuffer)}"); messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer, "mcpe") ?? new UnknownPackage(internalBuffer[0], internalBuffer)); } 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; HandlePackage(msg, playerSession); } message.PutPool(); return; } MiNetServer.TraceReceive(message); if (CryptoContext != null && CryptoContext.UseEncryption) { MiNetServer.FastThreadPool.QueueUserWorkItem(delegate() { HandlePackage(MessageHandler, message as Package); message.PutPool(); }); } else { HandlePackage(MessageHandler, message); message.PutPool(); } } catch (Exception e) { Log.Error("Package handling", e); throw; } }
internal void HandlePackage(Package message, PlayerNetworkSession playerSession) { if (message == null) { return; } if (typeof(McpeWrapper) == message.GetType()) { McpeWrapper wrapper = (McpeWrapper)message; // Get bytes byte[] payload = wrapper.payload; if (playerSession.CryptoContext != null && playerSession.CryptoContext.UseEncryption) { payload = CryptoUtils.Decrypt(payload, playerSession.CryptoContext); } //if (Log.IsDebugEnabled) // Log.Debug($"0x{payload[0]:x2}\n{Package.HexDump(payload)}"); var msg = PackageFactory.CreatePackage(payload[0], payload, "mcpe") ?? new UnknownPackage(payload[0], payload); msg.DatagramSequenceNumber = wrapper.DatagramSequenceNumber; msg.Reliability = wrapper.Reliability; msg.ReliableMessageNumber = wrapper.ReliableMessageNumber; msg.OrderingChannel = wrapper.OrderingChannel; msg.OrderingIndex = wrapper.OrderingIndex; HandlePackage(msg, playerSession); message.PutPool(); return; } if (typeof(UnknownPackage) == message.GetType()) { UnknownPackage packet = (UnknownPackage)message; if (Log.IsDebugEnabled) { Log.Warn($"Received unknown package 0x{message.Id:X2}\n{Package.HexDump(packet.Message)}"); } message.PutPool(); return; } if (typeof(McpeBatch) == message.GetType()) { Log.Debug("Handle MCPE batch message"); McpeBatch batch = (McpeBatch)message; var messages = new List <Package>(); // Get bytes byte[] payload = batch.payload.Array; // 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 = MiNetServer.MemoryStreamManager.GetStream(); defStream2.CopyTo(destination); destination.Position = 0; NbtBinaryReader reader = new NbtBinaryReader(destination, true); while (destination.Position < destination.Length) { int len = reader.ReadInt32(); byte[] internalBuffer = reader.ReadBytes(len); //if (Log.IsDebugEnabled) // Log.Debug($"0x{internalBuffer[0]:x2}\n{Package.HexDump(internalBuffer)}"); messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer, "mcpe") ?? new UnknownPackage(internalBuffer[0], internalBuffer)); } if (destination.Length > destination.Position) { throw new Exception("Have more data"); } } foreach (var msg in messages) { msg.DatagramSequenceNumber = batch.DatagramSequenceNumber; msg.Reliability = batch.Reliability; msg.ReliableMessageNumber = batch.ReliableMessageNumber; msg.OrderingChannel = batch.OrderingChannel; msg.OrderingIndex = batch.OrderingIndex; HandlePackage(msg, playerSession); } message.PutPool(); return; } MiNetServer.TraceReceive(message, message.OrderingIndex); if (CryptoContext != null && CryptoContext.UseEncryption) { MiNetServer.FastThreadPool.QueueUserWorkItem(delegate() { HandlePackage(MessageHandler, message as Package); message.PutPool(); }); } else { HandlePackage(MessageHandler, message); message.PutPool(); } }