From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Thu, 21 Jan 2021 00:40:24 +0100 Subject: [PATCH] Port krypton Co-authored-by: Hugo Planque diff --git a/src/main/java/me/steinborn/krypton/mod/shared/network/VarintByteDecoder.java b/src/main/java/me/steinborn/krypton/mod/shared/network/VarintByteDecoder.java new file mode 100644 index 0000000000000000000000000000000000000000..cdf5a3b1f7ec27171f3825f89cfb8d398fb3fd79 --- /dev/null +++ b/src/main/java/me/steinborn/krypton/mod/shared/network/VarintByteDecoder.java @@ -0,0 +1,47 @@ +package me.steinborn.krypton.mod.shared.network; + +import io.netty.util.ByteProcessor; + +public class VarintByteDecoder implements ByteProcessor { + private int readVarint; + private int bytesRead; + private DecodeResult result = DecodeResult.TOO_SHORT; + + @Override + public boolean process(byte k) { + readVarint |= (k & 0x7F) << bytesRead++ * 7; + if (bytesRead > 3) { + result = DecodeResult.TOO_BIG; + return false; + } + if ((k & 0x80) != 128) { + result = DecodeResult.SUCCESS; + return false; + } + return true; + } + + public int readVarint() { + return readVarint; + } + + public int varintBytes() { + return bytesRead; + } + + public DecodeResult getResult() { + return result; + } + + public void reset() { + readVarint = 0; + bytesRead = 0; + result = DecodeResult.TOO_SHORT; + } + + public enum DecodeResult { + SUCCESS, + TOO_SHORT, + TOO_BIG + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/server/LegacyPingHandler.java b/src/main/java/net/minecraft/server/LegacyPingHandler.java index 4a49fe4cc600e2b70963302ddae0c4479849f3f5..3abc3869b8012f060e1997822ffdb321f4884929 100644 --- a/src/main/java/net/minecraft/server/LegacyPingHandler.java +++ b/src/main/java/net/minecraft/server/LegacyPingHandler.java @@ -23,6 +23,11 @@ public class LegacyPingHandler extends ChannelInboundHandlerAdapter { } public void channelRead(ChannelHandlerContext channelhandlercontext, Object object) throws Exception { + // Yatopia start - New network system + if (!channelhandlercontext.channel().isActive()) { + ((ByteBuf) object).clear(); + return; + } // Yatopia end ByteBuf bytebuf = (ByteBuf) object; // Paper start - Make legacy ping handler more reliable diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java index e081905af0abbad0cf9011075a6380ef652924a7..c3240607b23ccaa6743c013251e1e45a67072441 100644 --- a/src/main/java/net/minecraft/server/LoginListener.java +++ b/src/main/java/net/minecraft/server/LoginListener.java @@ -8,6 +8,7 @@ import java.math.BigInteger; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.security.GeneralSecurityException; // Yatopia import java.security.PrivateKey; import java.util.Arrays; import java.util.Random; diff --git a/src/main/java/net/minecraft/server/PacketDataSerializer.java b/src/main/java/net/minecraft/server/PacketDataSerializer.java index f43193c1090238f2241b878120247d1b3d0d4e57..7dc31ee3211a895993c522a7155a0d8641fd442c 100644 --- a/src/main/java/net/minecraft/server/PacketDataSerializer.java +++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java @@ -7,6 +7,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; +import io.netty.buffer.ByteBufUtil; // Yatopia import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.EncoderException; import io.netty.util.ByteProcessor; @@ -30,7 +31,7 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack; // CraftBukkit public class PacketDataSerializer extends ByteBuf { - private final ByteBuf a; + private final ByteBuf a; private final ByteBuf getParent() { return a; } // Yatopia - OBFHELPER public PacketDataSerializer(ByteBuf bytebuf) { this.a = bytebuf; @@ -210,6 +211,7 @@ public class PacketDataSerializer extends ByteBuf { return new UUID(this.readLong(), this.readLong()); } + public PacketDataSerializer writeVarInt(int i){ return d(i); } // Yatopia - OBFHELPER public PacketDataSerializer d(int i) { while ((i & -128) != 0) { this.writeByte(i & 127 | 128); @@ -358,6 +360,8 @@ public class PacketDataSerializer extends ByteBuf { } public PacketDataSerializer a(String s, int i) { + // Yatopia start - New network system + /* byte[] abyte = s.getBytes(StandardCharsets.UTF_8); if (abyte.length > i) { @@ -367,6 +371,16 @@ public class PacketDataSerializer extends ByteBuf { this.writeBytes(abyte); return this; } + */ + int utf8Bytes = ByteBufUtil.utf8Bytes(s); + if (utf8Bytes > i) { + throw new EncoderException("String too big (was " + utf8Bytes + " bytes encoded, max " + i + ")"); + } else { + this.writeVarInt(utf8Bytes); + this.writeCharSequence(s, StandardCharsets.UTF_8); + return new PacketDataSerializer(getParent()); + } + // Yatopia end } public MinecraftKey p() { diff --git a/src/main/java/net/minecraft/server/PacketSplitter.java b/src/main/java/net/minecraft/server/PacketSplitter.java index 2aaa8770edfd8acc6861c23176e405863858b275..b1e1aa95b5d7a1555428327f2e7fd0eafc679dc1 100644 --- a/src/main/java/net/minecraft/server/PacketSplitter.java +++ b/src/main/java/net/minecraft/server/PacketSplitter.java @@ -5,14 +5,20 @@ import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.CorruptedFrameException; +// Yatopia start +import io.netty.handler.codec.DecoderException; +import me.steinborn.krypton.mod.shared.network.VarintByteDecoder; +// Yatopia end import java.util.List; public class PacketSplitter extends ByteToMessageDecoder { + private final VarintByteDecoder reader = new VarintByteDecoder(); // Yatopia private final byte[] lenBuf = new byte[3]; // Paper public PacketSplitter() {} protected void decode(ChannelHandlerContext channelhandlercontext, ByteBuf bytebuf, List list) throws Exception { + /* // Yatopia start - New network system // Paper start - if channel is not active just discard the packet if (!channelhandlercontext.channel().isActive()) { bytebuf.skipBytes(bytebuf.readableBytes()); @@ -53,5 +59,38 @@ public class PacketSplitter extends ByteToMessageDecoder { } throw new CorruptedFrameException("length wider than 21-bit"); + */ + if (!channelhandlercontext.channel().isActive()) { + bytebuf.clear(); + return; + } + + reader.reset(); + + int varintEnd = bytebuf.forEachByte(reader); + if (varintEnd == -1) { + // We tried to go beyond the end of the buffer. This is probably a good sign that the + // buffer was too short to hold a proper varint. + return; + } + + if (reader.getResult() == VarintByteDecoder.DecodeResult.SUCCESS) { + int readLen = reader.readVarint(); + if (readLen < 0) { + throw new DecoderException("Bad packet length"); + } else if (readLen == 0) { + // skip over the empty packet and ignore it + bytebuf.readerIndex(varintEnd + 1); + } else { + int minimumRead = reader.varintBytes() + readLen; + if (bytebuf.isReadable(minimumRead)) { + list.add(bytebuf.retainedSlice(varintEnd + 1, readLen)); + bytebuf.skipBytes(minimumRead); + } + } + } else if (reader.getResult() == VarintByteDecoder.DecodeResult.TOO_BIG) { + throw new DecoderException("Varint too big"); + } + // Yatopia end } } diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java index 756be0886856aabc31e436f82948d3d069f66fef..c1dd04b57e8ffeb343b0efdec36d6fb36c16884f 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; +import io.netty.util.ResourceLeakDetector; // Yatopia import joptsimple.OptionParser; import joptsimple.OptionSet; import net.minecrell.terminalconsole.TerminalConsoleAppender; // Paper @@ -289,6 +290,24 @@ public class Main { // Paper End } } + // Yatopia start - New network system + // By default, Netty allocates 16MiB arenas for the PooledByteBufAllocator. This is too much + // memory for Minecraft, which imposes a maximum packet size of 2MiB! We'll use 4MiB as a more + // sane default. + // + // Note: io.netty.allocator.pageSize << io.netty.allocator.maxOrder is the formula used to + // compute the chunk size. We lower maxOrder from its default of 11 to 9. (We also use a null + // check, so that the user is free to choose another setting if need be.) + if (System.getProperty("io.netty.allocator.maxOrder") == null) { + System.setProperty("io.netty.allocator.maxOrder", "9"); + } + + // Disable the resource leak detector by default as it reduces performance. Allow the user to + // override this if desired. + if (System.getProperty("io.netty.leakDetection.level") == null) { + ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED); + } + // Yatopia end // Paper start - Log Java and OS versioning to help with debugging plugin issues java.lang.management.RuntimeMXBean runtimeMX = java.lang.management.ManagementFactory.getRuntimeMXBean();