From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: ayunami2000 Date: Mon, 28 Mar 2022 17:02:21 -0400 Subject: [PATCH] Block server-side chunkbans diff --git a/src/main/java/net/minecraft/network/PacketEncoder.java b/src/main/java/net/minecraft/network/PacketEncoder.java index fbfadeb83719b81f42724e79c59e92ed88fdece7..c9c0652a22760716f9dbb5fc73bc6fce5148b800 100644 --- a/src/main/java/net/minecraft/network/PacketEncoder.java +++ b/src/main/java/net/minecraft/network/PacketEncoder.java @@ -6,9 +6,17 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; import io.papermc.paper.adventure.PaperAdventure; // Paper import java.io.IOException; +import java.util.Collections; // Scissors +import net.minecraft.ChatFormatting; // Scissors +import net.minecraft.core.NonNullList; // Scissors +import net.minecraft.nbt.CompoundTag; // Scissors +import net.minecraft.network.chat.Component; // Scissors +import net.minecraft.network.chat.SignedMessageBody; // Scissors import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.PacketFlow; +import net.minecraft.network.protocol.game.*; // Scissors import net.minecraft.util.profiling.jfr.JvmProfiler; +import net.minecraft.world.item.ItemStack; // Scissors import org.slf4j.Logger; public class PacketEncoder extends MessageToByteEncoder> { @@ -19,6 +27,23 @@ public class PacketEncoder extends MessageToByteEncoder> { this.flow = side; } + // Scissors start + private static int tryWrite(Packet packet, FriendlyByteBuf friendlyByteBuf, ChannelHandlerContext channelHandlerContext, int i) { + friendlyByteBuf.writeVarInt(i); + friendlyByteBuf.adventure$locale = channelHandlerContext.channel().attr(PaperAdventure.LOCALE_ATTRIBUTE).get(); + + int j = friendlyByteBuf.writerIndex(); + packet.write(friendlyByteBuf); + int k = friendlyByteBuf.writerIndex() - j; + int packetLength = friendlyByteBuf.readableBytes(); + if (k > 8388608 || packetLength > MAX_PACKET_SIZE) { + throw new SkipPacketException(new IllegalArgumentException("Packet too big (is " + k + "): " + packet)); + } + + return k; + } + // Scissors end + protected void encode(ChannelHandlerContext channelHandlerContext, Packet packet, ByteBuf byteBuf) throws Exception { ConnectionProtocol connectionProtocol = channelHandlerContext.channel().attr(Connection.ATTRIBUTE_PROTOCOL).get(); if (connectionProtocol == null) { @@ -33,38 +58,66 @@ public class PacketEncoder extends MessageToByteEncoder> { throw new IOException("Can't serialize unregistered packet"); } else { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(byteBuf); - friendlyByteBuf.writeVarInt(i); - friendlyByteBuf.adventure$locale = channelHandlerContext.channel().attr(PaperAdventure.LOCALE_ATTRIBUTE).get(); // Paper + // Scissors start + int k; try { - int j = friendlyByteBuf.writerIndex(); - packet.write(friendlyByteBuf); - int k = friendlyByteBuf.writerIndex() - j; - if (false && k > 8388608) { // Paper - disable - throw new IllegalArgumentException("Packet too big (is " + k + ", should be less than 8388608): " + packet); - } else { - int l = channelHandlerContext.channel().attr(Connection.ATTRIBUTE_PROTOCOL).get().getId(); - JvmProfiler.INSTANCE.onPacketSent(l, i, channelHandlerContext.channel().remoteAddress(), k); - } + k = tryWrite(packet, friendlyByteBuf, channelHandlerContext, i); } catch (Throwable var10) { - LOGGER.error("Packet encoding of packet ID {} threw (skippable? {})", i, packet.isSkippable(), var10); // Paper - Give proper error message - if (packet.isSkippable()) { - throw new SkipPacketException(var10); - } else { - throw var10; + packet = capPacket(packet, i); + if (packet == null) { + throw new SkipPacketException(new IllegalArgumentException("Packet too big: " + packet)); } + friendlyByteBuf.clear(); + k = tryWrite(packet, friendlyByteBuf, channelHandlerContext, i); } - // Paper start - int packetLength = friendlyByteBuf.readableBytes(); - if (packetLength > MAX_PACKET_SIZE) { - throw new PacketTooLargeException(packet, packetLength); - } - // Paper end + int l = channelHandlerContext.channel().attr(Connection.ATTRIBUTE_PROTOCOL).get().getId(); + JvmProfiler.INSTANCE.onPacketSent(l, i, channelHandlerContext.channel().remoteAddress(), k); + // Scissors end } } } + // Scissors start + private static Packet capPacket(Packet packet, int i) { + if (packet instanceof ClientboundBlockEntityDataPacket blockEntityDataPacket) { + packet = new ClientboundBlockEntityDataPacket(blockEntityDataPacket.getPos(), blockEntityDataPacket.getType(), new CompoundTag()); + } else if (packet instanceof ClientboundLevelChunkPacketData chunkPacket) { + chunkPacket.clearNBT(); + } else if (packet instanceof ClientboundSetEntityDataPacket) { + return null; // Skip + } else if (packet instanceof ClientboundContainerSetContentPacket containerSetContentPacket) { + packet = new ClientboundContainerSetContentPacket(containerSetContentPacket.getContainerId(), containerSetContentPacket.getStateId(), NonNullList.create(), ItemStack.EMPTY); + } else if (packet instanceof ClientboundSetEquipmentPacket setEquipmentPacket) { + packet = new ClientboundSetEquipmentPacket(setEquipmentPacket.getEntity(), Collections.emptyList()); + } else if (packet instanceof ClientboundContainerSetSlotPacket containerSetSlotPacket) { + packet = new ClientboundContainerSetSlotPacket(containerSetSlotPacket.getContainerId(), containerSetSlotPacket.getStateId(), containerSetSlotPacket.getSlot(), ItemStack.EMPTY); + } else if (packet instanceof ClientboundMapItemDataPacket mapItemDataPacket) { + packet = new ClientboundMapItemDataPacket(mapItemDataPacket.getMapId(), mapItemDataPacket.getScale(), mapItemDataPacket.isLocked(), null, null); + } else if (packet instanceof ClientboundSystemChatPacket) { + return null; + } else if (packet instanceof ClientboundDisguisedChatPacket) { + return null; + } else if (packet instanceof ClientboundPlayerChatPacket playerChatPacket) { + final SignedMessageBody.Packed body = playerChatPacket.body(); + packet = new ClientboundPlayerChatPacket(playerChatPacket.sender(), // Not sending this packet results in a kick when someone says something. + playerChatPacket.index(), + playerChatPacket.signature(), + playerChatPacket.body(), + Component.empty().append("** Message too large **").withStyle(ChatFormatting.RED), + playerChatPacket.filterMask(), + playerChatPacket.chatType() + ); + } else { + LOGGER.error("Packet with ID {} was too large and was not caught. Please report this to the Scissors developers.", i); + return null; + } + + return packet; + } + // Scissors end + // Paper start private static int MAX_PACKET_SIZE = 8388608; diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java index 3944852921335c78a04a9dc301882ab5b152b1ed..96ee53c7cc862e059328c5cdf5e07f309df6a79e 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java @@ -24,7 +24,7 @@ public class ClientboundBlockEntityDataPacket implements Packet blockEntityType, CompoundTag nbt) { + public ClientboundBlockEntityDataPacket(BlockPos pos, BlockEntityType blockEntityType, CompoundTag nbt) { // Scissors - private -> public this.pos = pos; this.type = blockEntityType; this.tag = nbt.isEmpty() ? null : nbt; diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java index 39b879f21f958dbd91ab0f74e5d4f3c74928fc33..688287c637a0d4b28d630b7304a3c2cf339bdf54 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java @@ -33,6 +33,13 @@ public class ClientboundLevelChunkPacketData { } // Paper end + // Scissors start + public void clearNBT() { + this.blockEntitiesData.clear(); + this.extraPackets.clear(); + } + // Scissors end + // Paper start - Anti-Xray - Add chunk packet info @Deprecated @io.papermc.paper.annotation.DoNotUse public ClientboundLevelChunkPacketData(LevelChunk chunk) { this(chunk, null); } public ClientboundLevelChunkPacketData(LevelChunk chunk, com.destroystokyo.paper.antixray.ChunkPacketInfo chunkPacketInfo) { @@ -58,6 +65,7 @@ public class ClientboundLevelChunkPacketData { int totalTileEntities = 0; // Paper for(Map.Entry entry2 : chunk.getBlockEntities().entrySet()) { + if (this.extraPackets.size() > 50) break; // Scissors - Limit extraPackets size // Paper start if (++totalTileEntities > TE_LIMIT) { var packet = entry2.getValue().getUpdatePacket();