From 2a2cdc2d1aaf8e9d951bb91c3a7e05acaa747328 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Mon, 22 Jan 2024 18:04:55 +0100 Subject: [PATCH] [ci skip] Add more patch identifying comments --- patches/server/Add-API-for-quit-reason.patch | 2 +- ...PlayerAdvancementCriterionGrantEvent.patch | 4 +-- .../server/Add-PlayerArmorChangeEvent.patch | 2 +- patches/server/Add-PlayerJumpEvent.patch | 4 +-- .../server/Add-PlayerKickEvent-causes.patch | 8 ++--- patches/server/Add-critical-damage-API.patch | 2 +- .../server/Add-experience-points-API.patch | 2 +- ...-a-custom-authentication-servers-dow.patch | 2 +- patches/server/AsyncTabCompleteEvent.patch | 14 ++++---- .../Block-Enderpearl-Travel-Exploit.patch | 4 +-- patches/server/Brand-support.patch | 2 +- ...nd-make-tab-spam-limits-configurable.patch | 4 +-- patches/server/Brigadier-Mojang-API.patch | 2 +- ...urable-sprint-interruption-on-attack.patch | 4 +-- ...le-Explicit-Network-Manager-Flushing.patch | 4 +-- ...-ServerboundCommandSuggestionPacket-.patch | 2 +- .../Dont-resend-blocks-on-interactions.patch | 2 +- patches/server/EndermanEscapeEvent.patch | 12 +++---- .../server/Execute-chunk-tasks-mid-tick.patch | 2 +- .../Extend-Player-Interact-cancellation.patch | 2 +- .../server/Fill-Profile-Property-Events.patch | 2 +- ...17075-Block-entity-unload-lag-spike.patch} | 10 +++--- ...nt-extended-PaperServerListPingEvent.patch | 2 +- ...ng-PreCreatureSpawnEvent-with-per-pl.patch | 2 +- .../Optimise-chunk-tick-iteration.patch | 4 +-- ...-Manager-and-add-advanced-packet-sup.patch | 2 +- .../Optional-per-player-mob-spawns.patch | 4 +-- .../PlayerNaturallySpawnCreaturesEvent.patch | 10 +++--- .../server/PlayerPickupExperienceEvent.patch | 2 +- patches/server/PreCreatureSpawnEvent.patch | 34 +++++++++---------- ...rom-being-processed-when-the-player-.patch | 2 +- patches/server/Rewrite-chunk-system.patch | 2 +- ...dEffects-only-to-players-who-can-see.patch | 4 +-- ...nt.patch => Toggleable-player-crits.patch} | 4 +-- ...dle-ServerboundKeepAlivePacket-async.patch | 4 +-- ...rt-serverside-behavior-of-keepalives.patch | 2 +- 36 files changed, 85 insertions(+), 85 deletions(-) rename patches/server/{Fix-MC-117075-TE-Unload-Lag-Spike.patch => Fix-MC-117075-Block-entity-unload-lag-spike.patch} (82%) rename patches/server/{Toggleable-player-crits-helps-mitigate-hacked-client.patch => Toggleable-player-crits.patch} (89%) diff --git a/patches/server/Add-API-for-quit-reason.patch b/patches/server/Add-API-for-quit-reason.patch index da86222089..5e1b6d843b 100644 --- a/patches/server/Add-API-for-quit-reason.patch +++ b/patches/server/Add-API-for-quit-reason.patch @@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -0,0 +0,0 @@ public class ServerPlayer extends Player { public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper - public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent public @Nullable String clientBrandName = null; // Paper - Brand support + public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event diff --git a/patches/server/Add-PlayerAdvancementCriterionGrantEvent.patch b/patches/server/Add-PlayerAdvancementCriterionGrantEvent.patch index 35a61ff910..8d47ecde0e 100644 --- a/patches/server/Add-PlayerAdvancementCriterionGrantEvent.patch +++ b/patches/server/Add-PlayerAdvancementCriterionGrantEvent.patch @@ -12,12 +12,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 boolean flag1 = advancementprogress.isDone(); if (advancementprogress.grantProgress(criterionName)) { -+ // Paper start ++ // Paper start - Add PlayerAdvancementCriterionGrantEvent + if (!new com.destroystokyo.paper.event.player.PlayerAdvancementCriterionGrantEvent(this.player.getBukkitEntity(), advancement.toBukkit(), criterionName).callEvent()) { + advancementprogress.revokeProgress(criterionName); + return false; + } -+ // Paper end ++ // Paper end - Add PlayerAdvancementCriterionGrantEvent this.unregisterListeners(advancement); this.progressChanged.add(advancement); flag = true; diff --git a/patches/server/Add-PlayerArmorChangeEvent.patch b/patches/server/Add-PlayerArmorChangeEvent.patch index d70a0bdb25..376e162d8d 100644 --- a/patches/server/Add-PlayerArmorChangeEvent.patch +++ b/patches/server/Add-PlayerArmorChangeEvent.patch @@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1); + new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); + } -+ // Paper end ++ // Paper end - PlayerArmorChangeEvent if (map == null) { map = Maps.newEnumMap(EquipmentSlot.class); } diff --git a/patches/server/Add-PlayerJumpEvent.patch b/patches/server/Add-PlayerJumpEvent.patch index 0ecf44effa..d83dd9ac68 100644 --- a/patches/server/Add-PlayerJumpEvent.patch +++ b/patches/server/Add-PlayerJumpEvent.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.player.onGround() && !packet.isOnGround() && flag) { - this.player.jumpFromGround(); -+ // Paper start - Add player jump event ++ // Paper start - Add PlayerJumpEvent + Player player = this.getCraftPlayer(); + Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. + Location to = player.getLocation().clone(); // Start off the To location as the Players current location. @@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.internalTeleport(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet()); + return; + } -+ // Paper end ++ // Paper end - Add PlayerJumpEvent } boolean flag1 = this.player.verticalCollisionBelow; diff --git a/patches/server/Add-PlayerKickEvent-causes.patch b/patches/server/Add-PlayerKickEvent-causes.patch index df77573c22..9d0b7811bf 100644 --- a/patches/server/Add-PlayerKickEvent-causes.patch +++ b/patches/server/Add-PlayerKickEvent-causes.patch @@ -110,7 +110,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE); + this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause }); - // Paper endg + // Paper endg - This needs to be handled on the main thread for plugins } @@ -0,0 +0,0 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } @@ -258,11 +258,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - run this async + // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper - configurable tab spam limits -- server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper -+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause +- server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam"))); // Paper - AsyncTabCompleteEvent ++ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - AsyncTabCompleteEvent & kick event cause return; } // Paper start diff --git a/patches/server/Add-critical-damage-API.patch b/patches/server/Add-critical-damage-API.patch index 0e34b898ce..a4cadcf76e 100644 --- a/patches/server/Add-critical-damage-API.patch +++ b/patches/server/Add-critical-damage-API.patch @@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity; + boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity; // Paper - Add critical damage API; diff on change - flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper + flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits flag2 = flag2 && !this.isSprinting(); @@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity { } diff --git a/patches/server/Add-experience-points-API.patch b/patches/server/Add-experience-points-API.patch index 548916b614..9604fa3dbb 100644 --- a/patches/server/Add-experience-points-API.patch +++ b/patches/server/Add-experience-points-API.patch @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); + return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); // Paper - diff on change; calculateTotalExperiencePoints } - // Paper start - send SoundEffect to everyone who can see fromEntity + // Paper start - send while respecting visibility private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Allow-specifying-a-custom-authentication-servers-dow.patch b/patches/server/Allow-specifying-a-custom-authentication-servers-dow.patch index 41de4fbb8e..637cf55035 100644 --- a/patches/server/Allow-specifying-a-custom-authentication-servers-dow.patch +++ b/patches/server/Allow-specifying-a-custom-authentication-servers-dow.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(s1)); // Spigot } else { - ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.authservers_down")); -+ ServerLoginPacketListenerImpl.this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.authenticationServersDown)); // Paper ++ ServerLoginPacketListenerImpl.this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.authenticationServersDown)); // Paper - Configurable kick message ServerLoginPacketListenerImpl.LOGGER.error("Couldn't verify username because servers are unavailable"); } // CraftBukkit start - catch all exceptions diff --git a/patches/server/AsyncTabCompleteEvent.patch b/patches/server/AsyncTabCompleteEvent.patch index 349bbdae77..de3a841b62 100644 --- a/patches/server/AsyncTabCompleteEvent.patch +++ b/patches/server/AsyncTabCompleteEvent.patch @@ -23,18 +23,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } -+ // Paper start ++ // Paper start - AsyncTabCompleteEvent + private static final java.util.concurrent.ExecutorService TAB_COMPLETE_EXECUTOR = java.util.concurrent.Executors.newFixedThreadPool(4, + new com.google.common.util.concurrent.ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Tab Complete Thread - #%d").setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)).build()); -+ // Paper end ++ // Paper end - AsyncTabCompleteEvent @Override public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); -+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - run this async ++ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start if (this.chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { - this.disconnect(Component.translatable("disconnect.spam")); -+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper ++ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam"))); // Paper - AsyncTabCompleteEvent return; } // Paper start @@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // Paper end // CraftBukkit end -+ // Paper start - async tab completion ++ // Paper start - AsyncTabCompleteEvent + TAB_COMPLETE_EXECUTOR.execute(() -> { StringReader stringreader = new StringReader(packet.getCommand()); @@ -86,7 +86,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + player.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), builder.buildFuture().join())); + } }); -+ // Paper end - async tab completion ++ // Paper end - AsyncTabCompleteEvent } @Override @@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } - TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers); -+ TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers, message.startsWith("/") || forceCommand, pos != null ? io.papermc.paper.util.MCUtil.toLocation(((CraftWorld) player.getWorld()).getHandle(), BlockPos.containing(pos)) : null); // Paper ++ TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers, message.startsWith("/") || forceCommand, pos != null ? io.papermc.paper.util.MCUtil.toLocation(((CraftWorld) player.getWorld()).getHandle(), BlockPos.containing(pos)) : null); // Paper - AsyncTabCompleteEvent this.getPluginManager().callEvent(tabEvent); return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions(); diff --git a/patches/server/Block-Enderpearl-Travel-Exploit.patch b/patches/server/Block-Enderpearl-Travel-Exploit.patch index 6e87855cfb..66ff671e0a 100644 --- a/patches/server/Block-Enderpearl-Travel-Exploit.patch +++ b/patches/server/Block-Enderpearl-Travel-Exploit.patch @@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + pearl.cachedOwner = null; + pearl.ownerUUID = null; + } -+ // Paper end ++ // Paper end - Reset pearls when they stop being ticked } public void onTrackingStart(Entity entity) { @@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (nbt.hasUUID("Owner")) { this.ownerUUID = nbt.getUUID("Owner"); this.cachedOwner = null; -+ if (this instanceof ThrownEnderpearl && this.level() != null && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit) { this.ownerUUID = null; } // Paper - Don't store shooter name for pearls to block enderpearl travel exploit ++ if (this instanceof ThrownEnderpearl && this.level() != null && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit) { this.ownerUUID = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit } this.leftOwner = nbt.getBoolean("LeftOwner"); diff --git a/patches/server/Brand-support.patch b/patches/server/Brand-support.patch index f277adc28a..569c55c6ac 100644 --- a/patches/server/Brand-support.patch +++ b/patches/server/Brand-support.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ServerPlayer extends Player { public boolean isRealPlayer; // Paper public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper - public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent + public @Nullable String clientBrandName = null; // Paper - Brand support // Paper start - replace player chunk loader diff --git a/patches/server/Break-up-and-make-tab-spam-limits-configurable.patch b/patches/server/Break-up-and-make-tab-spam-limits-configurable.patch index f0679286d5..31e847c6eb 100644 --- a/patches/server/Break-up-and-make-tab-spam-limits-configurable.patch +++ b/patches/server/Break-up-and-make-tab-spam-limits-configurable.patch @@ -43,10 +43,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --this.chatSpamTickCount; @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) { - // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - run this async + // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start - if (this.chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { + if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper - configurable tab spam limits - server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper + server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam"))); // Paper - AsyncTabCompleteEvent return; } diff --git a/patches/server/Brigadier-Mojang-API.patch b/patches/server/Brigadier-Mojang-API.patch index 48a4aa8e6a..f525d15bd4 100644 --- a/patches/server/Brigadier-Mojang-API.patch +++ b/patches/server/Brigadier-Mojang-API.patch @@ -163,7 +163,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - Brigadier API } }); - // Paper end - async tab completion + // Paper end - AsyncTabCompleteEvent diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java diff --git a/patches/server/Configurable-sprint-interruption-on-attack.patch b/patches/server/Configurable-sprint-interruption-on-attack.patch index 0f7d80c74f..caa8a4210b 100644 --- a/patches/server/Configurable-sprint-interruption-on-attack.patch +++ b/patches/server/Configurable-sprint-interruption-on-attack.patch @@ -14,11 +14,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D)); - this.setSprinting(false); -+ // Paper start - Configuration option to disable automatic sprint interruption ++ // Paper start - Configurable sprint interruption on attack + if (!this.level().paperConfig().misc.disableSprintInterruptionOnAttack) { + this.setSprinting(false); + } -+ // Paper end ++ // Paper end - Configurable sprint interruption on attack } if (flag3) { diff --git a/patches/server/Disable-Explicit-Network-Manager-Flushing.patch b/patches/server/Disable-Explicit-Network-Manager-Flushing.patch index f992263de5..ceafd260ad 100644 --- a/patches/server/Disable-Explicit-Network-Manager-Flushing.patch +++ b/patches/server/Disable-Explicit-Network-Manager-Flushing.patch @@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Paper start - NetworkClient implementation public int protocolVersion; public java.net.InetSocketAddress virtualHost; -+ private static boolean enableExplicitFlush = Boolean.getBoolean("paper.explicit-flush"); ++ private static boolean enableExplicitFlush = Boolean.getBoolean("paper.explicit-flush"); // Paper - Disable explicit network manager flushing // Paper end // Paper start - add utility methods @@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.channel != null) { - this.channel.flush(); -+ if (enableExplicitFlush) this.channel.eventLoop().execute(() -> this.channel.flush()); // Paper - we don't need to explicit flush here, but allow opt in incase issues are found to a better version ++ if (enableExplicitFlush) this.channel.eventLoop().execute(() -> this.channel.flush()); // Paper - Disable explicit network manager flushing; we don't need to explicit flush here, but allow opt in incase issues are found to a better version } if (this.tickCount++ % 20 == 0) { diff --git a/patches/server/Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch b/patches/server/Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch index b865a5b70f..2a8350cde3 100644 --- a/patches/server/Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch +++ b/patches/server/Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch @@ -18,6 +18,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return; + } + // Paper end - Don't suggest if tab-complete is disabled - // Paper start - async tab completion + // Paper start - AsyncTabCompleteEvent TAB_COMPLETE_EXECUTOR.execute(() -> { StringReader stringreader = new StringReader(packet.getCommand()); diff --git a/patches/server/Dont-resend-blocks-on-interactions.patch b/patches/server/Dont-resend-blocks-on-interactions.patch index 6f52d9166b..8058f13b59 100644 --- a/patches/server/Dont-resend-blocks-on-interactions.patch +++ b/patches/server/Dont-resend-blocks-on-interactions.patch @@ -123,7 +123,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // send a correcting update to the client for the block above as well, this because of replaceable blocks (such as grass, sea grass etc) - player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above())); + //player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above())); // Paper - Don't resync blocks - // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method + // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method } else if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.StructureBlock) { player.connection.send(new net.minecraft.network.protocol.game.ClientboundContainerClosePacket(this.player.containerMenu.containerId)); diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java diff --git a/patches/server/EndermanEscapeEvent.patch b/patches/server/EndermanEscapeEvent.patch index 21976b9f4f..5149283ce7 100644 --- a/patches/server/EndermanEscapeEvent.patch +++ b/patches/server/EndermanEscapeEvent.patch @@ -15,11 +15,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.setTarget(target, EntityTargetEvent.TargetReason.UNKNOWN, true); } -+ // Paper start ++ // Paper start - EndermanEscapeEvent + private boolean tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason reason) { + return new com.destroystokyo.paper.event.entity.EndermanEscapeEvent((org.bukkit.craftbukkit.entity.CraftEnderman) this.getBukkitEntity(), reason).callEvent(); + } -+ // Paper end ++ // Paper end - EndermanEscapeEvent + @Override public boolean setTarget(LivingEntity entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) { @@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 float f = this.getLightLevelDependentMagicValue(); - if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) { -+ if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper ++ if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper - EndermanEscapeEvent this.setTarget((LivingEntity) null); this.teleport(); } @@ -37,13 +37,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else { flag1 = flag && this.hurtWithCleanWater(source, (ThrownPotion) source.getDirectEntity(), amount); -+ if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper start ++ if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent for (int i = 0; i < 64; ++i) { if (this.teleport()) { return true; } } -+ } // Paper end ++ } // Paper - EndermanEscapeEvent return flag1; } @@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.target != null && !this.enderman.isPassenger()) { if (this.enderman.isLookingAtMe((Player) this.target)) { - if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D) { -+ if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D && this.enderman.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.STARE)) { // Paper ++ if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D && this.enderman.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.STARE)) { // Paper - EndermanEscapeEvent this.enderman.teleport(); } diff --git a/patches/server/Execute-chunk-tasks-mid-tick.patch b/patches/server/Execute-chunk-tasks-mid-tick.patch index e4f1063a50..136f2ce010 100644 --- a/patches/server/Execute-chunk-tasks-mid-tick.patch +++ b/patches/server/Execute-chunk-tasks-mid-tick.patch @@ -165,7 +165,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - execute chunk tasks during tick } } - this.blockEntityTickers.removeAll(toRemove); + this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public void guardEntityTick(Consumer tickConsumer, T entity) { try { diff --git a/patches/server/Extend-Player-Interact-cancellation.patch b/patches/server/Extend-Player-Interact-cancellation.patch index 3a31b159a5..0f65b957cd 100644 --- a/patches/server/Extend-Player-Interact-cancellation.patch +++ b/patches/server/Extend-Player-Interact-cancellation.patch @@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // send a correcting update to the client for the block above as well, this because of replaceable blocks (such as grass, sea grass etc) player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above())); -+ // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method ++ // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method + } else if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.StructureBlock) { + player.connection.send(new net.minecraft.network.protocol.game.ClientboundContainerClosePacket(this.player.containerMenu.containerId)); + } else if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.CommandBlock) { diff --git a/patches/server/Fill-Profile-Property-Events.patch b/patches/server/Fill-Profile-Property-Events.patch index c5d92dfcdd..703fd5bbab 100644 --- a/patches/server/Fill-Profile-Property-Events.patch +++ b/patches/server/Fill-Profile-Property-Events.patch @@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (optional.isPresent() && !booleansupplier.getAsBoolean()) { UUID uuid = ((GameProfile) optional.get()).getId(); - ProfileResult profileresult = apiServices.sessionService().fetchProfile(uuid, true); -+ ProfileResult profileresult = apiServices.sessionService() instanceof com.destroystokyo.paper.profile.PaperMinecraftSessionService paperMinecraftSessionService ? paperMinecraftSessionService.fetchProfile(optional.get(), true) : apiServices.sessionService().fetchProfile(uuid, true); // Paper ++ ProfileResult profileresult = apiServices.sessionService() instanceof com.destroystokyo.paper.profile.PaperMinecraftSessionService paperMinecraftSessionService ? paperMinecraftSessionService.fetchProfile(optional.get(), true) : apiServices.sessionService().fetchProfile(uuid, true); // Paper - FillProfileEvent return profileresult != null ? Optional.ofNullable(profileresult.profile()) : optional; } else { diff --git a/patches/server/Fix-MC-117075-TE-Unload-Lag-Spike.patch b/patches/server/Fix-MC-117075-Block-entity-unload-lag-spike.patch similarity index 82% rename from patches/server/Fix-MC-117075-TE-Unload-Lag-Spike.patch rename to patches/server/Fix-MC-117075-Block-entity-unload-lag-spike.patch index 863c961174..92238a2190 100644 --- a/patches/server/Fix-MC-117075-TE-Unload-Lag-Spike.patch +++ b/patches/server/Fix-MC-117075-Block-entity-unload-lag-spike.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: mezz Date: Wed, 9 Aug 2017 17:51:22 -0500 -Subject: [PATCH] Fix MC-117075: TE Unload Lag Spike +Subject: [PATCH] Fix MC-117075: Block entity unload lag spike diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java @@ -12,8 +12,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 boolean flag = this.tickRateManager().runsNormally(); int tilesThisCycle = 0; -+ var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - use removeAll -+ toRemove.add(null); ++ var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll ++ toRemove.add(null); // Paper - Fix MC-117075 for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters this.tileTickPosition = (this.tileTickPosition < this.blockEntityTickers.size()) ? this.tileTickPosition : 0; TickingBlockEntity tickingblockentity = (TickingBlockEntity) this.blockEntityTickers.get(this.tileTickPosition); @@ -22,13 +22,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Spigot start tilesThisCycle--; - this.blockEntityTickers.remove(this.tileTickPosition--); -+ toRemove.add(tickingblockentity); // Paper - use removeAll ++ toRemove.add(tickingblockentity); // Paper - Fix MC-117075; use removeAll // Spigot end } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); } } -+ this.blockEntityTickers.removeAll(toRemove); ++ this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 this.timings.tileEntityTick.stopTiming(); // Spigot this.tickingBlockEntities = false; diff --git a/patches/server/Implement-extended-PaperServerListPingEvent.patch b/patches/server/Implement-extended-PaperServerListPingEvent.patch index 18f8425c53..cbea780543 100644 --- a/patches/server/Implement-extended-PaperServerListPingEvent.patch +++ b/patches/server/Implement-extended-PaperServerListPingEvent.patch @@ -199,7 +199,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return new ServerStatus.Players(i, list.size(), List.of()); } else { - int j = Math.min(list.size(), 12); -+ int j = Math.min(list.size(), org.spigotmc.SpigotConfig.playerSample); // Paper ++ int j = Math.min(list.size(), org.spigotmc.SpigotConfig.playerSample); // Paper - PaperServerListPingEvent ObjectArrayList objectarraylist = new ObjectArrayList(j); int k = Mth.nextInt(this.random, 0, list.size() - j); diff --git a/patches/server/Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/patches/server/Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch index ae1c5e5fdb..c25fff011f 100644 --- a/patches/server/Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch +++ b/patches/server/Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch @@ -78,7 +78,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -0,0 +0,0 @@ public final class NaturalSpawner { - // Paper start + // Paper start - PreCreatureSpawnEvent PreSpawnStatus doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2); + // Paper start - per player mob count backoff + if (doSpawning == PreSpawnStatus.ABORT || doSpawning == PreSpawnStatus.CANCELLED) { diff --git a/patches/server/Optimise-chunk-tick-iteration.patch b/patches/server/Optimise-chunk-tick-iteration.patch index 65168afa41..b6d1a0289e 100644 --- a/patches/server/Optimise-chunk-tick-iteration.patch +++ b/patches/server/Optimise-chunk-tick-iteration.patch @@ -216,7 +216,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit - Util.shuffle(list, this.level.random); -- // Paper start - call player naturally spawn event +- // Paper start - PlayerNaturallySpawnCreaturesEvent - int chunkRange = level.spigotConfig.mobSpawnRange; - chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange; - chunkRange = Math.min(chunkRange, 8); @@ -257,7 +257,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in anyPlayerCloseEnoughForSpawning + player.playerNaturallySpawnedEvent = event; } -- // Paper end +- // Paper end - PlayerNaturallySpawnCreaturesEvent + // Paper end - optimise chunk tick iteration int l = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit diff --git a/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch index 8143e9fdf6..3442c50a9d 100644 --- a/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch +++ b/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch @@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Spigot Start @@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler> { public java.net.InetSocketAddress virtualHost; - private static boolean enableExplicitFlush = Boolean.getBoolean("paper.explicit-flush"); + private static boolean enableExplicitFlush = Boolean.getBoolean("paper.explicit-flush"); // Paper - Disable explicit network manager flushing // Paper end + // Paper start - Optimize network + public boolean isPending = true; diff --git a/patches/server/Optional-per-player-mob-spawns.patch b/patches/server/Optional-per-player-mob-spawns.patch index 17e26788b3..10612f971c 100644 --- a/patches/server/Optional-per-player-mob-spawns.patch +++ b/patches/server/Optional-per-player-mob-spawns.patch @@ -194,14 +194,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 while (k < 3) { @@ -0,0 +0,0 @@ public final class NaturalSpawner { - // Paper start + // Paper start - PreCreatureSpawnEvent PreSpawnStatus doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2); if (doSpawning == PreSpawnStatus.ABORT) { - return; + return j; // Paper - Optional per player mob spawns } if (doSpawning == PreSpawnStatus.SUCCESS && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) { - // Paper end + // Paper end - PreCreatureSpawnEvent Mob entityinsentient = NaturalSpawner.getMobForSpawn(world, biomesettingsmobs_c.type); if (entityinsentient == null) { diff --git a/patches/server/PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/PlayerNaturallySpawnCreaturesEvent.patch index d73a2e25b3..4a900da4b1 100644 --- a/patches/server/PlayerNaturallySpawnCreaturesEvent.patch +++ b/patches/server/PlayerNaturallySpawnCreaturesEvent.patch @@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } entityplayer = (ServerPlayer) iterator.next(); -+ // Paper start - add PlayerNaturallySpawnCreaturesEvent ++ // Paper start - PlayerNaturallySpawnCreaturesEvent + com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event; + blockRange = 16384.0D; + if (reducedRange) { @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (event == null || event.isCancelled()) return false; + blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4)); + } -+ // Paper end ++ // Paper end - PlayerNaturallySpawnCreaturesEvent } while (!this.playerIsCloseEnoughForSpawning(entityplayer, chunkcoordintpair, blockRange)); // Spigot return true; @@ -47,7 +47,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit Util.shuffle(list, this.level.random); -+ // Paper start - call player naturally spawn event ++ // Paper start - PlayerNaturallySpawnCreaturesEvent + int chunkRange = level.spigotConfig.mobSpawnRange; + chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange; + chunkRange = Math.min(chunkRange, 8); @@ -55,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange); + entityPlayer.playerNaturallySpawnedEvent.callEvent(); + } -+ // Paper end ++ // Paper end - PlayerNaturallySpawnCreaturesEvent int l = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit Iterator iterator1 = list.iterator(); @@ -67,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit end public boolean isRealPlayer; // Paper public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper -+ public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper ++ public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent // Paper start - replace player chunk loader private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); diff --git a/patches/server/PlayerPickupExperienceEvent.patch b/patches/server/PlayerPickupExperienceEvent.patch index bba1bc73cf..0d12051913 100644 --- a/patches/server/PlayerPickupExperienceEvent.patch +++ b/patches/server/PlayerPickupExperienceEvent.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void playerTouch(Player player) { if (!this.level().isClientSide) { - if (player.takeXpDelay == 0) { -+ if (player.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper ++ if (player.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent player.takeXpDelay = CraftEventFactory.callPlayerXpCooldownEvent(player, 2, PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2; player.take(this, 1); int i = this.repairPlayerItems(player, this.value); diff --git a/patches/server/PreCreatureSpawnEvent.patch b/patches/server/PreCreatureSpawnEvent.patch index f01034f65c..1a4ddbcb99 100644 --- a/patches/server/PreCreatureSpawnEvent.patch +++ b/patches/server/PreCreatureSpawnEvent.patch @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 blockposition_mutableblockposition.setWithOffset(blockposition, i1, k, j1); if (worldserver.getWorldBorder().isWithinBounds((BlockPos) blockposition_mutableblockposition) && SpawnUtil.moveToPossibleSpawnPosition(worldserver, k, blockposition_mutableblockposition, spawnutil_a)) { -+ // Paper start ++ // Paper start - PreCreatureSpawnEvent + String key = EntityType.getKey(entitytypes).getPath(); + org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key); + @@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + break; + } -+ // Paper end ++ // Paper end - PreCreatureSpawnEvent T t0 = entitytypes.create(worldserver, (CompoundTag) null, null, blockposition_mutableblockposition, enummobspawn, false, false); // CraftBukkit - decompile error if (t0 != null) { @@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Nullable public T spawn(ServerLevel worldserver, @Nullable CompoundTag nbttagcompound, @Nullable Consumer consumer, BlockPos blockposition, MobSpawnType enummobspawn, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { // CraftBukkit end -+ // Paper start - Call PreCreatureSpawnEvent ++ // Paper start - PreCreatureSpawnEvent + org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityType.getKey(this).getPath()); + if (type != null) { + com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; @@ -79,7 +79,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return null; + } + } -+ // Paper end ++ // Paper end - PreCreatureSpawnEvent T t0 = this.create(worldserver, nbttagcompound, consumer, blockposition, enummobspawn, flag, flag1); if (t0 != null) { @@ -104,7 +104,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else if (!SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, MobSpawnType.SPAWNER, blockposition1, world.getRandom())) { continue; } -+ // Paper start ++ // Paper start - PreCreatureSpawnEvent + EntityType entityType = optional.get(); + String key = EntityType.getKey(entityType).getPath(); + @@ -124,7 +124,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + continue; + } + } -+ // Paper end ++ // Paper end - PreCreatureSpawnEvent Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, (entity1) -> { entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot()); @@ -137,13 +137,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } - if (NaturalSpawner.isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2) && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) { -+ // Paper start ++ // Paper start - PreCreatureSpawnEvent + PreSpawnStatus doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2); + if (doSpawning == PreSpawnStatus.ABORT) { + return; + } + if (doSpawning == PreSpawnStatus.SUCCESS && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) { -+ // Paper end ++ // Paper end - PreCreatureSpawnEvent Mob entityinsentient = NaturalSpawner.getMobForSpawn(world, biomesettingsmobs_c.type); if (entityinsentient == null) { @@ -152,7 +152,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } - private static boolean isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) { -+ // Paper start ++ // Paper start - PreCreatureSpawnEvent + private enum PreSpawnStatus { + FAIL, + SUCCESS, @@ -160,10 +160,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ABORT + } + private static PreSpawnStatus isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) { -+ // Paper end ++ // Paper end - PreCreatureSpawnEvent EntityType entitytypes = spawnEntry.type; -+ // Paper start ++ // Paper start - PreCreatureSpawnEvent + com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; + org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityType.getKey(entitytypes).getPath()); + if (type != null) { @@ -178,22 +178,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return PreSpawnStatus.CANCELLED; // Paper + } + } -+ // Paper end ++ // Paper end - PreCreatureSpawnEvent if (entitytypes.getCategory() == MobCategory.MISC) { - return false; -+ return PreSpawnStatus.FAIL; // Paper ++ return PreSpawnStatus.FAIL; // Paper - PreCreatureSpawnEvent } else if (!entitytypes.canSpawnFarFromPlayer() && squaredDistance > (double) (entitytypes.getCategory().getDespawnDistance() * entitytypes.getCategory().getDespawnDistance())) { - return false; -+ return PreSpawnStatus.FAIL; // Paper ++ return PreSpawnStatus.FAIL; // Paper - PreCreatureSpawnEvent } else if (entitytypes.canSummon() && NaturalSpawner.canSpawnMobAt(world, structureAccessor, chunkGenerator, group, spawnEntry, pos)) { SpawnPlacements.Type entitypositiontypes_surface = SpawnPlacements.getPlacementType(entitytypes); - return !NaturalSpawner.isSpawnPositionOk(entitypositiontypes_surface, world, pos, entitytypes) ? false : (!SpawnPlacements.checkSpawnRules(entitytypes, world, MobSpawnType.NATURAL, pos, world.random) ? false : world.noCollision(entitytypes.getAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D))); -+ boolean isValid = !NaturalSpawner.isSpawnPositionOk(entitypositiontypes_surface, world, pos, entitytypes) ? false : (!SpawnPlacements.checkSpawnRules(entitytypes, world, MobSpawnType.NATURAL, pos, world.random) ? false : world.noCollision(entitytypes.getAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D))); // Paper -+ return isValid ? PreSpawnStatus.SUCCESS : PreSpawnStatus.FAIL; // Paper ++ boolean isValid = !NaturalSpawner.isSpawnPositionOk(entitypositiontypes_surface, world, pos, entitytypes) ? false : (!SpawnPlacements.checkSpawnRules(entitytypes, world, MobSpawnType.NATURAL, pos, world.random) ? false : world.noCollision(entitytypes.getAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D))); // Paper - PreCreatureSpawnEvent ++ return isValid ? PreSpawnStatus.SUCCESS : PreSpawnStatus.FAIL; // Paper - PreCreatureSpawnEvent } else { - return false; -+ return PreSpawnStatus.FAIL; // Paper ++ return PreSpawnStatus.FAIL; // Paper - PreCreatureSpawnEvent } } diff --git a/patches/server/Prevent-logins-from-being-processed-when-the-player-.patch b/patches/server/Prevent-logins-from-being-processed-when-the-player-.patch index 37da157d74..d32197f55c 100644 --- a/patches/server/Prevent-logins-from-being-processed-when-the-player-.patch +++ b/patches/server/Prevent-logins-from-being-processed-when-the-player-.patch @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.state == ServerLoginPacketListenerImpl.State.VERIFYING) { + if (this.connection.isConnected()) { // Paper - prevent logins to be processed even though disconnect was called this.verifyLoginAndFinishConnectionSetup((GameProfile) Objects.requireNonNull(this.authenticatedProfile)); -+ } // Paper ++ } // Paper - prevent logins to be processed even though disconnect was called } if (this.state == ServerLoginPacketListenerImpl.State.WAITING_FOR_DUPE_DISCONNECT && !this.isPlayerAlreadyInWorld((GameProfile) Objects.requireNonNull(this.authenticatedProfile))) { diff --git a/patches/server/Rewrite-chunk-system.patch b/patches/server/Rewrite-chunk-system.patch index dacd07c942..e75bc7d922 100644 --- a/patches/server/Rewrite-chunk-system.patch +++ b/patches/server/Rewrite-chunk-system.patch @@ -20504,7 +20504,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + String str = packet.getCommand(); int index = -1; + if (str.length() > 64 && ((index = str.indexOf(' ')) == -1 || index >= 64)) { -+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper ++ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam"))); // Paper + return; + } + // Paper end diff --git a/patches/server/Send-attack-SoundEffects-only-to-players-who-can-see.patch b/patches/server/Send-attack-SoundEffects-only-to-players-who-can-see.patch index 2ff4073c52..88bfa78225 100644 --- a/patches/server/Send-attack-SoundEffects-only-to-players-who-can-see.patch +++ b/patches/server/Send-attack-SoundEffects-only-to-players-who-can-see.patch @@ -59,14 +59,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public int getXpNeededForNextLevel() { return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); } -+ // Paper start - send SoundEffect to everyone who can see fromEntity ++ // Paper start - send while respecting visibility + private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { + fromEntity.level().playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity himself + if (fromEntity instanceof ServerPlayer) { + ((ServerPlayer) fromEntity).connection.send(new net.minecraft.network.protocol.game.ClientboundSoundPacket(net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.wrapAsHolder(soundEffect), soundCategory, x, y, z, volume, pitch, fromEntity.random.nextLong())); + } + } -+ // Paper end ++ // Paper end - send while respecting visibility // CraftBukkit start public void causeFoodExhaustion(float exhaustion) { diff --git a/patches/server/Toggleable-player-crits-helps-mitigate-hacked-client.patch b/patches/server/Toggleable-player-crits.patch similarity index 89% rename from patches/server/Toggleable-player-crits-helps-mitigate-hacked-client.patch rename to patches/server/Toggleable-player-crits.patch index 0ee6d7397e..73d2d8062c 100644 --- a/patches/server/Toggleable-player-crits-helps-mitigate-hacked-client.patch +++ b/patches/server/Toggleable-player-crits.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sat, 10 Mar 2018 00:50:24 +0100 -Subject: [PATCH] Toggleable player crits, helps mitigate hacked clients. +Subject: [PATCH] Toggleable player crits diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity; -+ flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper ++ flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits flag2 = flag2 && !this.isSprinting(); if (flag2) { f *= 1.5F; diff --git a/patches/server/handle-ServerboundKeepAlivePacket-async.patch b/patches/server/handle-ServerboundKeepAlivePacket-async.patch index a8958816a0..be68a56d12 100644 --- a/patches/server/handle-ServerboundKeepAlivePacket-async.patch +++ b/patches/server/handle-ServerboundKeepAlivePacket-async.patch @@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void handleKeepAlive(ServerboundKeepAlivePacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // CraftBukkit -+ //PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // CraftBukkit // Paper - This shouldn't be on the main thread ++ //PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // CraftBukkit // Paper - handle ServerboundKeepAlivePacket async if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) { int i = (int) (Util.getMillis() - this.keepAliveTime); @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + server.submit(() -> { + this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE); + }); -+ // Paper endg ++ // Paper endg - This needs to be handled on the main thread for plugins } } diff --git a/patches/server/revert-serverside-behavior-of-keepalives.patch b/patches/server/revert-serverside-behavior-of-keepalives.patch index 5a91ac0c42..eaf9f16f4a 100644 --- a/patches/server/revert-serverside-behavior-of-keepalives.patch +++ b/patches/server/revert-serverside-behavior-of-keepalives.patch @@ -64,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.send(new ClientboundKeepAlivePacket(this.keepAliveChallenge)); } } -+ // Paper end ++ // Paper end - give clients a longer time to respond to pings as per pre 1.12.2 timings this.server.getProfiler().pop(); }