diff --git a/patches/unapplied/server/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch b/patches/server/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch similarity index 100% rename from patches/unapplied/server/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch rename to patches/server/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch diff --git a/patches/unapplied/server/Add-PlayerConnectionCloseEvent.patch b/patches/server/Add-PlayerConnectionCloseEvent.patch similarity index 96% rename from patches/unapplied/server/Add-PlayerConnectionCloseEvent.patch rename to patches/server/Add-PlayerConnectionCloseEvent.patch index fa8fb8361a..7ba913bc95 100644 --- a/patches/unapplied/server/Add-PlayerConnectionCloseEvent.patch +++ b/patches/server/Add-PlayerConnectionCloseEvent.patch @@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java @@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler> { - this.getPacketListener().onDisconnect(new TranslatableComponent("multiplayer.disconnect.generic")); + this.getPacketListener().onDisconnect(Component.translatable("multiplayer.disconnect.generic")); } this.queue.clear(); // Free up packet queue. + // Paper start - Add PlayerConnectionCloseEvent diff --git a/patches/unapplied/server/Add-more-Zombie-API.patch b/patches/server/Add-more-Zombie-API.patch similarity index 100% rename from patches/unapplied/server/Add-more-Zombie-API.patch rename to patches/server/Add-more-Zombie-API.patch diff --git a/patches/unapplied/server/Async-command-map-building.patch b/patches/server/Async-command-map-building.patch similarity index 92% rename from patches/unapplied/server/Async-command-map-building.patch rename to patches/server/Async-command-map-building.patch index aba9712138..87998e40da 100644 --- a/patches/unapplied/server/Async-command-map-building.patch +++ b/patches/server/Async-command-map-building.patch @@ -8,9 +8,9 @@ diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -0,0 +0,0 @@ import net.minecraft.network.chat.MutableComponent; - import net.minecraft.network.chat.TextComponent; - import net.minecraft.network.chat.TranslatableComponent; +@@ -0,0 +0,0 @@ import net.minecraft.network.chat.ComponentUtils; + import net.minecraft.network.chat.HoverEvent; + import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.protocol.game.ClientboundCommandsPacket; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.commands.AdvancementCommands; diff --git a/patches/unapplied/server/Block-Entity-remove-from-being-called-on-Players.patch b/patches/server/Block-Entity-remove-from-being-called-on-Players.patch similarity index 100% rename from patches/unapplied/server/Block-Entity-remove-from-being-called-on-Players.patch rename to patches/server/Block-Entity-remove-from-being-called-on-Players.patch diff --git a/patches/unapplied/server/BlockDestroyEvent.patch b/patches/server/BlockDestroyEvent.patch similarity index 100% rename from patches/unapplied/server/BlockDestroyEvent.patch rename to patches/server/BlockDestroyEvent.patch diff --git a/patches/unapplied/server/Book-Size-Limits.patch b/patches/server/Book-Size-Limits.patch similarity index 100% rename from patches/unapplied/server/Book-Size-Limits.patch rename to patches/server/Book-Size-Limits.patch diff --git a/patches/unapplied/server/Don-t-allow-digging-into-unloaded-chunks.patch b/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch similarity index 78% rename from patches/unapplied/server/Don-t-allow-digging-into-unloaded-chunks.patch rename to patches/server/Don-t-allow-digging-into-unloaded-chunks.patch index efb1faba94..1efdd8ca35 100644 --- a/patches/unapplied/server/Don-t-allow-digging-into-unloaded-chunks.patch +++ b/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch @@ -35,25 +35,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1); this.lastSentState = -1; @@ -0,0 +0,0 @@ public class ServerPlayerGameMode { - double d3 = d0 * d0 + d1 * d1 + d2 * d2; - if (d3 > 36.0D) { + public void handleBlockBreakAction(BlockPos pos, ServerboundPlayerActionPacket.Action action, Direction direction, int worldHeight, int sequence) { + if (this.player.getEyePosition().distanceToSqr(Vec3.atCenterOf(pos)) > ServerGamePacketListenerImpl.MAX_INTERACTION_DISTANCE) { + if (true) return; // Paper - Don't notify if unreasonably far away - BlockState iblockdata; - - if (this.player.level.getServer() != null && this.player.chunkPosition().getChessboardDistance(new ChunkPos(pos)) < this.player.level.getServer().getPlayerList().getViewDistance()) { + this.debugLogging(pos, false, sequence, "too far"); + } else if (pos.getY() >= worldHeight) { + this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); @@ -0,0 +0,0 @@ public class ServerPlayerGameMode { - this.player.connection.send(new ClientboundBlockBreakAckPacket(pos, this.level.getBlockState(pos), action, true, "stopped destroying")); + this.debugLogging(pos, true, sequence, "stopped destroying"); } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { this.isDestroyingBlock = false; - if (!Objects.equals(this.destroyPos, pos)) { -+ if (!Objects.equals(this.destroyPos, pos) && !BlockPos.ZERO.equals(this.destroyPos)) { ++ if (!Objects.equals(this.destroyPos, pos) && !BlockPos.ZERO.equals(this.destroyPos)) { // Paper ServerPlayerGameMode.LOGGER.debug("Mismatch in destroy block pos: {} {}", this.destroyPos, pos); // CraftBukkit - SPIGOT-5457 sent by client when interact event cancelled - this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1); -- this.player.connection.send(new ClientboundBlockBreakAckPacket(this.destroyPos, this.level.getBlockState(this.destroyPos), action, true, "aborted mismatched destroying")); +- this.debugLogging(pos, true, sequence, "aborted mismatched destroying"); + BlockState type = this.level.getBlockStateIfLoaded(this.destroyPos); // Paper - don't load unloaded chunks for stale records here -+ if (type != null) this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1); // Paper -+ if (type != null) this.player.connection.send(new ClientboundBlockBreakAckPacket(this.destroyPos, type, action, true, "aborted mismatched destroying")); // Paper ++ if (type != null) this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1); ++ if (type != null) this.debugLogging(pos, true, sequence, "aborted mismatched destroying"); + this.destroyPos = BlockPos.ZERO; // Paper } @@ -68,10 +68,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 case STOP_DESTROY_BLOCK: + // Paper start - Don't allow digging in unloaded chunks + if (this.player.level.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) == null) { ++ this.player.connection.ackBlockChangesUpTo(packet.getSequence()); + return; + } - this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level.getMaxBuildHeight()); + // Paper end - Don't allow digging in unloaded chunks + this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level.getMaxBuildHeight(), packet.getSequence()); + this.player.connection.ackBlockChangesUpTo(packet.getSequence()); return; - default: - throw new IllegalArgumentException("Invalid player action"); diff --git a/patches/unapplied/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch b/patches/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch similarity index 100% rename from patches/unapplied/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch rename to patches/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch diff --git a/patches/unapplied/server/Fix-SpongeAbsortEvent-handling.patch b/patches/server/Fix-SpongeAbsortEvent-handling.patch similarity index 100% rename from patches/unapplied/server/Fix-SpongeAbsortEvent-handling.patch rename to patches/server/Fix-SpongeAbsortEvent-handling.patch diff --git a/patches/unapplied/server/Handle-Large-Packets-disconnecting-client.patch b/patches/server/Handle-Large-Packets-disconnecting-client.patch similarity index 100% rename from patches/unapplied/server/Handle-Large-Packets-disconnecting-client.patch rename to patches/server/Handle-Large-Packets-disconnecting-client.patch diff --git a/patches/unapplied/server/Implement-Brigadier-Mojang-API.patch b/patches/server/Implement-Brigadier-Mojang-API.patch similarity index 96% rename from patches/unapplied/server/Implement-Brigadier-Mojang-API.patch rename to patches/server/Implement-Brigadier-Mojang-API.patch index db93597da6..a00fd60b6c 100644 --- a/patches/unapplied/server/Implement-Brigadier-Mojang-API.patch +++ b/patches/server/Implement-Brigadier-Mojang-API.patch @@ -32,10 +32,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 -public class CommandSourceStack implements SharedSuggestionProvider { +public class CommandSourceStack implements SharedSuggestionProvider, com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource { // Paper - public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(new TranslatableComponent("permissions.requires.player")); - public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(new TranslatableComponent("permissions.requires.entity")); + public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(Component.translatable("permissions.requires.player")); + public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(Component.translatable("permissions.requires.entity")); @@ -0,0 +0,0 @@ public class CommandSourceStack implements SharedSuggestionProvider { - return this.textName; + return this.entity != null ? this.entity.asChatSender() : ChatSender.system(this.getDisplayName()); } + // Paper start diff --git a/patches/unapplied/server/Limit-Client-Sign-length-more.patch b/patches/server/Limit-Client-Sign-length-more.patch similarity index 57% rename from patches/unapplied/server/Limit-Client-Sign-length-more.patch rename to patches/server/Limit-Client-Sign-length-more.patch index 2429a1e00a..304791850c 100644 --- a/patches/unapplied/server/Limit-Client-Sign-length-more.patch +++ b/patches/server/Limit-Client-Sign-length-more.patch @@ -26,26 +26,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser - private int aboveGroundVehicleTickCount; - private int receivedMovePacketCount; - private int knownMovePacketCount; -+ private static final int MAX_SIGN_LINE_LENGTH = Integer.getInteger("Paper.maxSignLength", 80); + private final ChatPreviewThrottler chatPreviewThrottler = new ChatPreviewThrottler(); + private final AtomicReference lastChatTimeStamp; private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit ++ private static final int MAX_SIGN_LINE_LENGTH = Integer.getInteger("Paper.maxSignLength", 80); // Paper public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player) { + this.lastChatTimeStamp = new AtomicReference(Instant.EPOCH); @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser - for (int i = 0; i < signText.size(); ++i) { - TextFilter.FilteredText currentLine = signText.get(i); -+ // Paper start - cap line length - modified clients can send longer data than normal -+ if (MAX_SIGN_LINE_LENGTH > 0 && currentLine.getRaw().length() > MAX_SIGN_LINE_LENGTH) { -+ // This handles multibyte characters as 1 -+ int offset = currentLine.getRaw().codePoints().limit(MAX_SIGN_LINE_LENGTH).map(Character::charCount).sum(); -+ if (offset < currentLine.getRaw().length()) { -+ signText.set(i, currentLine = net.minecraft.server.network.TextFilter.FilteredText.passThrough(currentLine.getRaw().substring(0, offset))); // this will break any filtering, but filtering is NYI as of 1.17 -+ } + @Override + public void handleSignUpdate(ServerboundSignUpdatePacket packet) { +- List list = (List) Stream.of(packet.getLines()).map(ChatFormatting::stripFormatting).collect(Collectors.toList()); ++ // Paper start - cap line length - modified clients can send longer data than normal ++ String[] lines = packet.getLines(); ++ for (int i = 0; i < lines.length; ++i) { ++ if (MAX_SIGN_LINE_LENGTH > 0 && lines[i].length() > MAX_SIGN_LINE_LENGTH) { ++ // This handles multibyte characters as 1 ++ int offset = lines[i].codePoints().limit(MAX_SIGN_LINE_LENGTH).map(Character::charCount).sum(); ++ if (offset < lines[i].length()) { ++ lines[i] = lines[i].substring(0, offset); // this will break any filtering, but filtering is NYI as of 1.17 + } -+ // Paper end ++ } ++ } ++ List list = (List) Stream.of(lines).map(ChatFormatting::stripFormatting).collect(Collectors.toList()); ++ // Paper end - if (this.player.isTextFilteringEnabled()) { - lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterText(currentLine.getFiltered()))); + this.filterTextPacket(list, (list1) -> { + this.updateSignText(packet, list1); diff --git a/patches/unapplied/server/Make-the-default-permission-message-configurable.patch b/patches/server/Make-the-default-permission-message-configurable.patch similarity index 100% rename from patches/unapplied/server/Make-the-default-permission-message-configurable.patch rename to patches/server/Make-the-default-permission-message-configurable.patch diff --git a/patches/unapplied/server/Prevent-Enderman-from-loading-chunks.patch b/patches/server/Prevent-Enderman-from-loading-chunks.patch similarity index 89% rename from patches/unapplied/server/Prevent-Enderman-from-loading-chunks.patch rename to patches/server/Prevent-Enderman-from-loading-chunks.patch index 3b98fe6b0e..4574060fea 100644 --- a/patches/unapplied/server/Prevent-Enderman-from-loading-chunks.patch +++ b/patches/server/Prevent-Enderman-from-loading-chunks.patch @@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java @@ -0,0 +0,0 @@ public class EnderMan extends Monster implements NeutralMob { - int j = Mth.floor(this.enderman.getY() + random.nextDouble() * 2.0D); - int k = Mth.floor(this.enderman.getZ() - 1.0D + random.nextDouble() * 2.0D); + int j = Mth.floor(this.enderman.getY() + randomsource.nextDouble() * 2.0D); + int k = Mth.floor(this.enderman.getZ() - 1.0D + randomsource.nextDouble() * 2.0D); BlockPos blockposition = new BlockPos(i, j, k); - BlockState iblockdata = world.getBlockState(blockposition); + BlockState iblockdata = world.getBlockStateIfLoaded(blockposition); // Paper @@ -19,8 +19,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 BlockState iblockdata1 = world.getBlockState(blockposition1); BlockState iblockdata2 = this.enderman.getCarriedBlock(); @@ -0,0 +0,0 @@ public class EnderMan extends Monster implements NeutralMob { - int j = Mth.floor(this.enderman.getY() + random.nextDouble() * 3.0D); - int k = Mth.floor(this.enderman.getZ() - 2.0D + random.nextDouble() * 4.0D); + int j = Mth.floor(this.enderman.getY() + randomsource.nextDouble() * 3.0D); + int k = Mth.floor(this.enderman.getZ() - 2.0D + randomsource.nextDouble() * 4.0D); BlockPos blockposition = new BlockPos(i, j, k); - BlockState iblockdata = world.getBlockState(blockposition); + BlockState iblockdata = world.getBlockStateIfLoaded(blockposition); // Paper diff --git a/patches/unapplied/server/Prevent-rayTrace-from-loading-chunks.patch b/patches/server/Prevent-rayTrace-from-loading-chunks.patch similarity index 100% rename from patches/unapplied/server/Prevent-rayTrace-from-loading-chunks.patch rename to patches/server/Prevent-rayTrace-from-loading-chunks.patch diff --git a/patches/unapplied/server/Workaround-for-vehicle-tracking-issue-on-disconnect.patch b/patches/server/Workaround-for-vehicle-tracking-issue-on-disconnect.patch similarity index 100% rename from patches/unapplied/server/Workaround-for-vehicle-tracking-issue-on-disconnect.patch rename to patches/server/Workaround-for-vehicle-tracking-issue-on-disconnect.patch diff --git a/patches/unapplied/server/force-entity-dismount-during-teleportation.patch b/patches/server/force-entity-dismount-during-teleportation.patch similarity index 100% rename from patches/unapplied/server/force-entity-dismount-during-teleportation.patch rename to patches/server/force-entity-dismount-during-teleportation.patch