From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: ayunami2000 Date: Thu, 25 Jan 2024 23:48:51 -0600 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 96d5448019d53ac3575e209c1c5c223a62a2638d..d0cfc4fc00d45c91380d2d794ca816db74d40266 100644 --- a/src/main/java/net/minecraft/network/PacketEncoder.java +++ b/src/main/java/net/minecraft/network/PacketEncoder.java @@ -7,8 +7,17 @@ import io.netty.handler.codec.MessageToByteEncoder; import io.netty.util.Attribute; import io.netty.util.AttributeKey; import java.io.IOException; +import java.util.Collections; + +import net.minecraft.ChatFormatting; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.SignedMessageBody; import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.*; import net.minecraft.util.profiling.jfr.JvmProfiler; +import net.minecraft.world.item.ItemStack; import org.slf4j.Logger; public class PacketEncoder extends MessageToByteEncoder> { @@ -19,6 +28,23 @@ public class PacketEncoder extends MessageToByteEncoder> { this.codecKey = protocolKey; } + // Scissors start + private int tryWrite(Packet packet, FriendlyByteBuf friendlyByteBuf, ChannelHandlerContext channelHandlerContext, int i) { + friendlyByteBuf.writeVarInt(i); + friendlyByteBuf.adventure$locale = channelHandlerContext.channel().attr(io.papermc.paper.adventure.PaperAdventure.LOCALE_ATTRIBUTE).get(); // Paper + + int j = friendlyByteBuf.writerIndex(); + packet.write(friendlyByteBuf); + int k = friendlyByteBuf.writerIndex() - j; + int packetLength = friendlyByteBuf.readableBytes(); + if (packetLength > MAX_PACKET_SIZE) { + throw new PacketTooLargeException(packet, this.codecKey, packetLength); + } + + return k; + } + // Scissors end + protected void encode(ChannelHandlerContext channelHandlerContext, Packet packet, ByteBuf byteBuf) throws Exception { Attribute> attribute = channelHandlerContext.channel().attr(this.codecKey); ConnectionProtocol.CodecData codecData = attribute.get(); @@ -34,45 +60,58 @@ 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(io.papermc.paper.adventure.PaperAdventure.LOCALE_ATTRIBUTE).get(); // Paper - adventure; set player's locale + // Scissors start + int k; try { - int j = friendlyByteBuf.writerIndex(); - packet.write(friendlyByteBuf); - int k = friendlyByteBuf.writerIndex() - j; - if (false && k > 8388608) { // Paper - Handle large packets disconnecting client; disable - throw new IllegalArgumentException("Packet too big (is " + k + ", should be less than 8388608): " + packet); - } - - JvmProfiler.INSTANCE.onPacketSent(codecData.protocol(), i, channelHandlerContext.channel().remoteAddress(), k); + k = this.tryWrite(packet, friendlyByteBuf, channelHandlerContext, i); } catch (Throwable var13) { - // Paper start - Give proper error message - String packetName = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(packet.getClass().getName()); - if (packetName.contains(".")) { - packetName = packetName.substring(packetName.lastIndexOf(".") + 1); + packet = capPacket(packet, i); + if (packet == null) { + throw new SkipPacketException(new IllegalArgumentException("Packet too big: " + packet)); } - - LOGGER.error("Packet encoding of packet {} (ID: {}) threw (skippable? {})", packetName, i, packet.isSkippable(), var13); - // Paper end - if (packet.isSkippable()) { - throw new SkipPacketException(var13); - } - - throw var13; - } finally { - // Paper start - Handle large packets disconnecting client - int packetLength = friendlyByteBuf.readableBytes(); - if (packetLength > MAX_PACKET_SIZE) { - throw new PacketTooLargeException(packet, this.codecKey, packetLength); - } - // Paper end - Handle large packets disconnecting client - ProtocolSwapHandler.swapProtocolIfNeeded(attribute, packet); + friendlyByteBuf.clear(); + k = this.tryWrite(packet, friendlyByteBuf, channelHandlerContext, i); } + JvmProfiler.INSTANCE.onPacketSent(codecData.protocol(), i, channelHandlerContext.channel().remoteAddress(), k); + ProtocolSwapHandler.swapProtocolIfNeeded(attribute, packet); + // 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 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 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 { + 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 76bde683d193b37e563a67c1c7b9bdcf17d64524..185aa88ff28e6f3e3314abe19dff88609a47334e 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 - Handle oversized block entities in chunks + // 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 - Handle oversized block entities in chunks for (Entry entry2 : chunk.getBlockEntities().entrySet()) { + if (this.extraPackets.size() > 50) break; // Scissors - Limit extraPackets size // Paper start - Handle oversized block entities in chunks if (++totalTileEntities > TE_LIMIT) { var packet = entry2.getValue().getUpdatePacket();