diff --git a/paper-server/patches/sources/net/minecraft/server/network/LegacyQueryHandler.java.patch b/paper-server/patches/sources/net/minecraft/server/network/LegacyQueryHandler.java.patch index 5ba39612d8..5e6a096b22 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/LegacyQueryHandler.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/LegacyQueryHandler.java.patch @@ -26,26 +26,24 @@ byteBuf.markReaderIndex(); boolean flag = true; -@@ -33,9 +_,21 @@ +@@ -33,9 +_,19 @@ SocketAddress socketAddress = context.channel().remoteAddress(); int i = byteBuf.readableBytes(); + String string = null; // Paper -+ // org.bukkit.event.server.ServerListPingEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callServerListPingEvent(socketAddress, this.server.getMotd(), this.server.getPlayerCount(), this.server.getMaxPlayers()); // CraftBukkit // Paper -+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event; // Paper if (i == 0) { - LOGGER.debug("Ping: (<1.3.x) from {}", socketAddress); - String string = createVersion0Response(this.server); + LOGGER.debug("Ping: (<1.3.x) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? socketAddress: ""); // Paper - Respect logIPs option + // Paper start - Call PaperServerListPingEvent and use results -+ event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), (java.net.InetSocketAddress) socketAddress, 39, null); ++ com.destroystokyo.paper.event.server.PaperServerListPingEvent event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), (java.net.InetSocketAddress) socketAddress, 39, null); + if (event == null) { + context.close(); + byteBuf.release(); + flag = false; + return; + } -+ string = String.format(Locale.ROOT, "%s\u00a7%d\u00a7%d", com.destroystokyo.paper.network.PaperLegacyStatusClient.getUnformattedMotd(event), event.getNumPlayers(), event.getMaxPlayers()); ++ string = String.format(Locale.ROOT, "%s§%d§%d", com.destroystokyo.paper.network.PaperLegacyStatusClient.getUnformattedMotd(event), event.getNumPlayers(), event.getMaxPlayers()); + // Paper end - Call PaperServerListPingEvent and use results sendFlushAndClose(context, createLegacyDisconnectPacket(context.alloc(), string)); } else { @@ -74,7 +72,7 @@ + + if (string == null) { + // Paper start - Call PaperServerListPingEvent and use results -+ event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), (java.net.InetSocketAddress) socketAddress, 127, null); // Paper ++ com.destroystokyo.paper.event.server.PaperServerListPingEvent event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), (java.net.InetSocketAddress) socketAddress, 127, null); // Paper + if (event == null) { + context.close(); + byteBuf.release(); @@ -85,7 +83,7 @@ - LOGGER.debug("Ping: (1.6) from {}", socketAddress); - } else { - LOGGER.debug("Ping: (1.4-1.5.x) from {}", socketAddress); -+ string = String.format(Locale.ROOT, "\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", event.getProtocolVersion(), this.server.getServerVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit ++ string = String.format(Locale.ROOT, "§1\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", event.getProtocolVersion(), this.server.getServerVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit + // Paper end - Call PaperServerListPingEvent and use results } - @@ -93,25 +91,11 @@ sendFlushAndClose(context, createLegacyDisconnectPacket(context.alloc(), string)); } -@@ -95,21 +_,97 @@ - } +@@ -110,6 +_,98 @@ + server.getMaxPlayers() + ); } - -- private static String createVersion0Response(ServerInfo server) { -- return String.format(Locale.ROOT, "%s§%d§%d", server.getMotd(), server.getPlayerCount(), server.getMaxPlayers()); -- } -- -- private static String createVersion1Response(ServerInfo server) { -- return String.format( -- Locale.ROOT, -- "§1\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", -- 127, -- server.getServerVersion(), -- server.getMotd(), -- server.getPlayerCount(), -- server.getMaxPlayers() -- ); -- } ++ + // Paper start + private static String readLegacyString(ByteBuf buf) { + int size = buf.readShort() * Character.BYTES; diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index 3d98b71ca6..43bacc9139 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -281,8 +281,8 @@ + public void disconnect(final net.kyori.adventure.text.Component reason, PlayerKickEvent.Cause cause) { + this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(reason), cause); + } -+ + // Paper end - adventure ++ + @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - kick event causes public void disconnect(Component reason) { - this.disconnect(new DisconnectionDetails(reason)); diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java.patch index 08bccdf22e..2ff7ea70fa 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java.patch @@ -13,14 +13,15 @@ this.gameProfile = cookie.gameProfile(); this.clientInformation = cookie.clientInformation(); } -@@ -61,6 +_,10 @@ +@@ -61,6 +_,11 @@ @Override public void onDisconnect(DisconnectionDetails details) { + // Paper start - Debugging + if (this.server.isDebugging()) { + ServerConfigurationPacketListenerImpl.LOGGER.info("{} lost connection: {}, while in configuration phase {}", this.gameProfile, details.reason().getString(), this.currentTask != null ? this.currentTask.type().id() : "null"); -+ } else // Paper end ++ } else ++ // Paper end LOGGER.info("{} lost connection: {}", this.gameProfile, details.reason().getString()); super.onDisconnect(details); } diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerConnectionListener.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerConnectionListener.java.patch index fa6e15d0d7..97e6b6ed34 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerConnectionListener.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerConnectionListener.java.patch @@ -68,7 +68,7 @@ ? new RateKickingConnection(rateLimitPacketsPerSecond) : new Connection(PacketFlow.SERVERBOUND)); - ServerConnectionListener.this.connections.add(connection); -+ // ServerConnectionListener.this.connections.add(connection); ++ // ServerConnectionListener.this.connections.add(connection); // Paper + // Paper start - Add support for Proxy Protocol + if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.proxyProtocol) { + channel.pipeline().addAfter("timeout", "haproxy-decoder", new io.netty.handler.codec.haproxy.HAProxyMessageDecoder()); @@ -98,7 +98,7 @@ + }); + } + // Paper end - Add support for proxy protocol -+ pending.add(connection); // Paper - prevent blocking on adding a new connection while the server is ticking ++ ServerConnectionListener.this.pending.add(connection); // Paper - prevent blocking on adding a new connection while the server is ticking connection.configurePacketHandler(channelPipeline); connection.setListenerForServerboundHandshake( new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, connection) diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 80b64ccf25..7058df616f 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -147,7 +147,7 @@ + } + // Paper start - Prevent causing expired keys from impacting new joins + if (!this.hasLoggedExpiry && this.chatSession != null && this.chatSession.profilePublicKey().data().hasExpired()) { -+ LOGGER.info("Player profile key for {} has expired!", this.player.getGameProfile().getName()); ++ LOGGER.info("Player profile key for {} has expired!", this.player.getName().getString()); + this.hasLoggedExpiry = true; + } + // Paper end - Prevent causing expired keys from impacting new joins @@ -374,7 +374,7 @@ this.player.getRecipeBook().setBookSetting(packet.getBookType(), packet.isOpen(), packet.isFiltering()); } -@@ -536,14 +_,84 @@ +@@ -536,25 +_,110 @@ } } @@ -386,7 +386,7 @@ @Override public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); -+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); ++ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async + // CraftBukkit start + if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits + this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect @@ -458,9 +458,16 @@ + private void sendServerSuggestions(final ServerboundCommandSuggestionPacket packet, final StringReader stringReader) { + // Paper end - AsyncTabCompleteEvent ParseResults parseResults = this.server.getCommands().getDispatcher().parse(stringReader, this.player.createCommandSourceStack()); ++ // Paper start - Handle non-recoverable exceptions ++ if (!parseResults.getExceptions().isEmpty() ++ && parseResults.getExceptions().values().stream().anyMatch(e -> e instanceof io.papermc.paper.brigadier.TagParseCommandSyntaxException)) { ++ this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); ++ return; ++ } ++ // Paper end - Handle non-recoverable exceptions this.server .getCommands() -@@ -551,10 +_,18 @@ + .getDispatcher() .getCompletionSuggestions(parseResults) .thenAccept( suggestions -> { @@ -802,7 +809,7 @@ d3 = d - this.player.getX(); d4 = d1 - this.player.getY(); if (d4 > -0.5 || d4 < 0.5) { -@@ -970,21 +_,106 @@ +@@ -970,20 +_,104 @@ d5 = d2 - this.player.getZ(); d7 = d3 * d3 + d4 * d4 + d5 * d5; @@ -815,21 +822,20 @@ && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { - flag2 = true; -- LOGGER.warn("{} moved wrongly!", this.player.getName().getString()); -- } -- -- if (this.player.noPhysics -- || this.player.isSleeping() -- || (!flag2 || !serverLevel.noCollision(this.player, boundingBox)) -- && !this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2)) { + // Paper start - Add fail move event + io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_WRONGLY, + toX, toY, toZ, toYaw, toPitch, true); + if (!event.isAllowed()) { + movedWrongly = true; + if (event.getLogWarning()) -+ // Paper end -+ LOGGER.warn("{} moved wrongly!", this.player.getName().getString()); ++ // Paper end + LOGGER.warn("{} moved wrongly!", this.player.getName().getString()); +- } +- +- if (this.player.noPhysics +- || this.player.isSleeping() +- || (!flag2 || !serverLevel.noCollision(this.player, boundingBox)) +- && !this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2)) { + } // Paper + } + @@ -915,18 +921,8 @@ + } + // CraftBukkit end this.player.absMoveTo(d, d1, d2, f, f1); -+ boolean isAutoSpinAttack = this.player.isAutoSpinAttack(); this.clientIsFloating = d4 >= -0.03125 - && !flag1 -@@ -996,6 +_,7 @@ - && !isAutoSpinAttack - && this.noBlocksAround(this.player); - this.player.serverLevel().getChunkSource().move(this.player); -+ - Vec3 vec3 = new Vec3(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z); - this.player.setOnGroundWithMovement(packet.isOnGround(), packet.horizontalCollision(), vec3); - this.player.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.isOnGround()); @@ -1018,9 +_,6 @@ this.lastGoodX = this.player.getX(); this.lastGoodY = this.player.getY(); @@ -945,12 +941,11 @@ return true; } else { -@@ -1076,10 +_,78 @@ +@@ -1076,10 +_,77 @@ } public void teleport(double x, double y, double z, float yaw, float pitch) { - this.teleport(new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), Collections.emptySet()); -+ //this.teleport(new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), Collections.emptySet()); + // CraftBukkit start - Delegate to teleport(Location) + this.teleport(x, y, z, yaw, pitch, PlayerTeleportEvent.TeleportCause.UNKNOWN); + } @@ -1412,7 +1407,7 @@ ParseResults parseResults = this.parseCommand(command); if (this.server.enforceSecureProfile() && SignableCommand.hasSignableArguments(parseResults)) { LOGGER.error( -@@ -1335,13 +_,29 @@ +@@ -1335,26 +_,55 @@ Optional optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages()); if (!optional.isEmpty()) { this.tryHandleChat(packet.command(), () -> { @@ -1440,14 +1435,18 @@ + this.cserver.getPluginManager().callEvent(event); + command = event.getMessage().substring(1); + -+ // Paper start - Fix cancellation and message changing ParseResults parseResults = this.parseCommand(packet.command()); Map map; -@@ -1352,9 +_,21 @@ + try { ++ // Paper - Always parse the original command to add to the chat chain + map = this.collectSignedArguments(packet, SignableCommand.of(parseResults), lastSeenMessages); + } catch (SignedMessageChain.DecodeException var6) { + this.handleMessageDecodeFailure(var6); return; } ++ // Paper start - Fix cancellation and message changing + if (event.isCancelled()) { + // Only now are we actually good to return + return; @@ -1492,6 +1491,15 @@ } } +@@ -1434,7 +_,7 @@ + Optional optional = this.lastSeenMessages.applyUpdate(update); + if (optional.isEmpty()) { + LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); +- this.disconnect(CHAT_VALIDATION_FAILED); ++ this.disconnectAsync(CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes & add proper async disconnect + } + + return optional; @@ -1451,22 +_,155 @@ return false; } @@ -1818,7 +1826,7 @@ AABB boundingBox = target.getBoundingBox(); - if (this.player.canInteractWithEntity(boundingBox, 3.0)) { -+ if (this.player.canInteractWithEntity(boundingBox, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(3.0D))) { // Paper - configurable lenience value for interact range ++ if (this.player.canInteractWithEntity(boundingBox, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(3.0))) { // Paper - configurable lenience value for interact range packet.dispatch( new ServerboundInteractPacket.Handler() { - private void performInteraction(InteractionHand hand, ServerGamePacketListenerImpl.EntityInteraction entityInteraction) { @@ -2068,7 +2076,7 @@ + } + } + break; -+ // TODO check on updates ++ // TODO check on updates + case QUICK_MOVE: + if (packet.getButtonNum() == 0) { + click = ClickType.SHIFT_LEFT; @@ -2289,13 +2297,13 @@ + break; + // Modified cursor only + case DROP_ALL_CURSOR: -+ case DROP_ONE_CURSOR: -+ case CLONE_STACK: ++ case DROP_ONE_CURSOR: ++ case CLONE_STACK: + this.player.connection.send(new net.minecraft.network.protocol.game.ClientboundSetCursorItemPacket(this.player.containerMenu.getCarried().copy())); // Paper - correctly set cursor + break; + // Nothing + case NOTHING: -+ break; ++ break; + } + } + diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerStatusPacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerStatusPacketListenerImpl.java.patch index 7a4ce9578f..b6419959d2 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerStatusPacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerStatusPacketListenerImpl.java.patch @@ -5,7 +5,7 @@ } else { this.hasRequestedStatus = true; - this.connection.send(new ClientboundStatusResponsePacket(this.status)); -+ // this.connection.send(new ClientboundStatusResponsePacket(this.status)); ++ // this.connection.send(new ClientboundStatusResponsePacket(this.status)); // Paper + com.destroystokyo.paper.network.StandardPaperServerListPingEventImpl.processRequest(net.minecraft.server.MinecraftServer.getServer(), this.connection); // Paper - handle status request } }