diff --git a/patches/server/0350-Add-tick-times-API-and-mspt-command.patch b/patches/server/0350-Add-tick-times-API-and-mspt-command.patch index 48271b6856..4a333224d6 100644 --- a/patches/server/0350-Add-tick-times-API-and-mspt-command.patch +++ b/patches/server/0350-Add-tick-times-API-and-mspt-command.patch @@ -125,18 +125,18 @@ index 72f2e81b9905a0d57ed8e2a88578f62d5235c456..7b58b2d6297800c2dcdbf7539e5ab8e7 public static void registerCommands(final MinecraftServer server) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 6024a9e0dca38b1c21332f5c131d824190a2be90..ce113cc2bc52c1135799190a22e0be21744b58cc 100644 +index 6407af497c719d0f6a4446192bed622af34d6bc6..7a6b3f50f4379a29a59b33db965a86ef4d5539b0 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -252,6 +252,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0) { -+ // Paper start - Patrol settings ++ // Paper start - Pillager patrol spawn settings and per player options + // Random player selection moved up for per player spawning and configuration + int j = world.players().size(); + if (j < 1) { @@ -82,7 +82,7 @@ index e5918fa3be107ac3a2fc8831fd78733a7506730a..a908652f1ebb426d265ef614746f70cd - if (randomsource.nextInt(5) != 0) { + if (days >= world.paperConfig().entities.behavior.pillagerPatrols.start.day && world.isDay()) { + if (randomsource.nextDouble() >= world.paperConfig().entities.behavior.pillagerPatrols.spawnChance) { -+ // Paper end ++ // Paper end - Pillager patrol spawn settings and per player options return 0; } else { - int j = world.players().size(); diff --git a/patches/server/0354-Remote-Connections-shouldn-t-hold-up-shutdown.patch b/patches/server/0354-Remote-Connections-shouldn-t-hold-up-shutdown.patch index 4000b9b254..9cb8e0b277 100644 --- a/patches/server/0354-Remote-Connections-shouldn-t-hold-up-shutdown.patch +++ b/patches/server/0354-Remote-Connections-shouldn-t-hold-up-shutdown.patch @@ -24,21 +24,21 @@ index 7bc90a4b0cbbb2251122038d374860ff02f5edee..5f4f993243f19f1e88b7f2bc5e40a6b2 System.exit(0); // CraftBukkit diff --git a/src/main/java/net/minecraft/server/rcon/thread/RconThread.java b/src/main/java/net/minecraft/server/rcon/thread/RconThread.java -index 3bf60f640aa9fa4cabd2b3e5d3931e8467b9df24..2c1289aa2bf8b7bb67709190263b82b811c17fff 100644 +index 3bf60f640aa9fa4cabd2b3e5d3931e8467b9df24..b939da2d6309c6d2b3d1ef089adf7cbf70865196 100644 --- a/src/main/java/net/minecraft/server/rcon/thread/RconThread.java +++ b/src/main/java/net/minecraft/server/rcon/thread/RconThread.java @@ -107,6 +107,14 @@ public class RconThread extends GenericThread { this.clients.clear(); } -+ // Paper start ++ // Paper start - don't wait for remote connections + public void stopNonBlocking() { + this.running = false; + for (RconClient client : this.clients) { + client.running = false; + } + } -+ // Paper stop ++ // Paper stop - don't wait for remote connections private void closeSocket(ServerSocket socket) { LOGGER.debug("closeSocket: {}", (Object)socket); diff --git a/patches/server/0355-Do-not-allow-bees-to-load-chunks-for-beehives.patch b/patches/server/0355-Do-not-allow-bees-to-load-chunks-for-beehives.patch index 8de3e9bd41..30a38841ad 100644 --- a/patches/server/0355-Do-not-allow-bees-to-load-chunks-for-beehives.patch +++ b/patches/server/0355-Do-not-allow-bees-to-load-chunks-for-beehives.patch @@ -5,14 +5,14 @@ Subject: [PATCH] Do not allow bees to load chunks for beehives diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index d9297c0b2934084a065af7d7c93af8d44c3de8e1..c6235be64d6fb234734dd816052695ac44aea3ae 100644 +index d9297c0b2934084a065af7d7c93af8d44c3de8e1..3f1502b489e6b3a371572abe3ac045313e8def5e 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java @@ -420,6 +420,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { if (this.hivePos == null) { return false; } else { -+ if (!this.level().isLoadedAndInBounds(this.hivePos)) return false; // Paper ++ if (!this.level().isLoadedAndInBounds(this.hivePos)) return false; // Paper - Do not allow bees to load chunks for beehives BlockEntity tileentity = this.level().getBlockEntity(this.hivePos); return tileentity instanceof BeehiveBlockEntity && ((BeehiveBlockEntity) tileentity).isFireNearby(); @@ -20,7 +20,7 @@ index d9297c0b2934084a065af7d7c93af8d44c3de8e1..c6235be64d6fb234734dd816052695ac } private boolean doesHiveHaveSpace(BlockPos pos) { -+ if (!this.level().isLoadedAndInBounds(pos)) return false; // Paper ++ if (!this.level().isLoadedAndInBounds(pos)) return false; // Paper - Do not allow bees to load chunks for beehives BlockEntity tileentity = this.level().getBlockEntity(pos); return tileentity instanceof BeehiveBlockEntity ? !((BeehiveBlockEntity) tileentity).isFull() : false; @@ -28,7 +28,7 @@ index d9297c0b2934084a065af7d7c93af8d44c3de8e1..c6235be64d6fb234734dd816052695ac @Override public boolean canBeeUse() { if (Bee.this.hasHive() && Bee.this.wantsToEnterHive() && Bee.this.hivePos.closerToCenterThan(Bee.this.position(), 2.0D)) { -+ if (!Bee.this.level().isLoadedAndInBounds(Bee.this.hivePos)) return false; // Paper ++ if (!Bee.this.level().isLoadedAndInBounds(Bee.this.hivePos)) return false; // Paper - Do not allow bees to load chunks for beehives BlockEntity tileentity = Bee.this.level().getBlockEntity(Bee.this.hivePos); if (tileentity instanceof BeehiveBlockEntity) { @@ -36,7 +36,7 @@ index d9297c0b2934084a065af7d7c93af8d44c3de8e1..c6235be64d6fb234734dd816052695ac @Override public void start() { -+ if (!Bee.this.level().isLoadedAndInBounds(Bee.this.hivePos)) return; // Paper ++ if (!Bee.this.level().isLoadedAndInBounds(Bee.this.hivePos)) return; // Paper - Do not allow bees to load chunks for beehives BlockEntity tileentity = Bee.this.level().getBlockEntity(Bee.this.hivePos); if (tileentity instanceof BeehiveBlockEntity) { diff --git a/patches/server/0356-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/patches/server/0356-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index e97ae2aba8..a792a698bf 100644 --- a/patches/server/0356-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/patches/server/0356-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch @@ -7,7 +7,7 @@ Suspected case would be around the technique used in .stopRiding Stack will identify any causer of this and warn instead of crashing. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 1f9efff4ddccf2569fdfe42e6cbc92792643d0ea..876200db872bce89976329c4d6c6fbe9fd155f24 100644 +index 1f9efff4ddccf2569fdfe42e6cbc92792643d0ea..3b7a82761682e29fb42f683b232c789c522b632e 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -993,6 +993,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -20,12 +20,12 @@ index 1f9efff4ddccf2569fdfe42e6cbc92792643d0ea..876200db872bce89976329c4d6c6fbe9 + + ": " + entity + (this.entityMap.containsKey(entity.getId()) ? " ALREADY CONTAINED (This would have crashed your server)" : ""), new Throwable()); + return; + } -+ // Paper end ++ // Paper end - ignore and warn about illegal addEntity calls instead of crashing server if (!(entity instanceof EnderDragonPart)) { EntityType entitytypes = entity.getType(); int i = entitytypes.clientTrackingRange() * 16; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 63437e0cd8ad76e05a3ae40de673d8ff6cae00c6..1c0d2aad70b3817913e93354ccc055b82ae321bc 100644 +index 63437e0cd8ad76e05a3ae40de673d8ff6cae00c6..46101e6bef0f81968cb194303e19e437a3417733 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2514,7 +2514,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -33,7 +33,7 @@ index 63437e0cd8ad76e05a3ae40de673d8ff6cae00c6..1c0d2aad70b3817913e93354ccc055b8 public void onTrackingStart(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot - ServerLevel.this.getChunkSource().addEntity(entity); -+ // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - moved down below valid=true ++ // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true if (entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; diff --git a/patches/server/0360-Don-t-move-existing-players-to-world-spawn.patch b/patches/server/0360-Don-t-move-existing-players-to-world-spawn.patch index e4f380afa5..341028c2d4 100644 --- a/patches/server/0360-Don-t-move-existing-players-to-world-spawn.patch +++ b/patches/server/0360-Don-t-move-existing-players-to-world-spawn.patch @@ -13,7 +13,7 @@ By skipping this, we avoid potential for a large spike on server start. public net.minecraft.server.level.ServerPlayer fudgeSpawnLocation(Lnet/minecraft/server/level/ServerLevel;)V diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index daedb7b5ef086ccbf091274088170cf7eb331f91..3738680d935695930be19cdc18478c62ccb93d3a 100644 +index 9fcd1a7c1532c6343707665d96b1d147ed4d424f..e8470f0cc918ae20caa9aa4de7a81edf31f2f556 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -385,7 +385,7 @@ public class ServerPlayer extends Player { @@ -21,7 +21,7 @@ index daedb7b5ef086ccbf091274088170cf7eb331f91..3738680d935695930be19cdc18478c62 this.advancements = server.getPlayerList().getPlayerAdvancements(this); this.setMaxUpStep(1.0F); - this.fudgeSpawnLocation(world); -+ // this.fudgeSpawnLocation(world); // Paper - don't move to spawn on login, only first join ++ // this.fudgeSpawnLocation(world); // Paper - Don't move existing players to world spawn this.updateOptions(clientOptions); this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper @@ -35,14 +35,14 @@ index daedb7b5ef086ccbf091274088170cf7eb331f91..3738680d935695930be19cdc18478c62 this.gameMode.setLevel((ServerLevel) world); } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index d4ae0a201838dbc9c73f7c1a8a67072b344b71bc..03f8e1775e05293665f995b6c3ee52ed11447e79 100644 +index d4ae0a201838dbc9c73f7c1a8a67072b344b71bc..02cb0a3d2331002a64ceb32027b9112cb7a81808 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -226,6 +226,7 @@ public abstract class PlayerList { // Paper start if (nbttagcompound == null) { player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login -+ player.fudgeSpawnLocation(worldserver1); // only move to spawn on first login, otherwise, stay where you are.... ++ player.fudgeSpawnLocation(worldserver1); // Paper - Don't move existing players to world spawn } // Paper end player.setServerLevel(worldserver1); diff --git a/patches/server/0363-Optimize-Pathfinding.patch b/patches/server/0363-Optimize-Pathfinding.patch index 8fca2b48b1..72f4ca5ac6 100644 --- a/patches/server/0363-Optimize-Pathfinding.patch +++ b/patches/server/0363-Optimize-Pathfinding.patch @@ -7,27 +7,27 @@ Prevents pathfinding from spamming failures for things such as arrow attacks. diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index 68edd488087a6ec1e65797cfbd4118bd0efbab50..b37415d45dda8e658c8995a4519e552dc378bb41 100644 +index 68edd488087a6ec1e65797cfbd4118bd0efbab50..a9922074b6aa6a9898615385bb11d2a758662970 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java @@ -192,9 +192,29 @@ public abstract class PathNavigation { return this.moveTo(this.createPath(x, y, z, 1), speed); } -+ // Paper start - optimise pathfinding ++ // Paper start - Perf: Optimise pathfinding + private int lastFailure = 0; + private int pathfindFailures = 0; -+ // Paper end ++ // Paper end - Perf: Optimise pathfinding + public boolean moveTo(Entity entity, double speed) { -+ // Paper start - Pathfinding optimizations ++ // Paper start - Perf: Optimise pathfinding + if (this.pathfindFailures > 10 && this.path == null && net.minecraft.server.MinecraftServer.currentTick < this.lastFailure + 40) { + return false; + } -+ // Paper end ++ // Paper end - Perf: Optimise pathfinding Path path = this.createPath(entity, 1); - return path != null && this.moveTo(path, speed); -+ // Paper start - Pathfinding optimizations ++ // Paper start - Perf: Optimise pathfinding + if (path != null && this.moveTo(path, speed)) { + this.lastFailure = 0; + this.pathfindFailures = 0; @@ -37,7 +37,7 @@ index 68edd488087a6ec1e65797cfbd4118bd0efbab50..b37415d45dda8e658c8995a4519e552d + this.lastFailure = net.minecraft.server.MinecraftServer.currentTick; + return false; + } -+ // Paper end ++ // Paper end - Perf: Optimise pathfinding } public boolean moveTo(@Nullable Path path, double speed) { diff --git a/patches/server/0364-Reduce-Either-Optional-allocation.patch b/patches/server/0364-Reduce-Either-Optional-allocation.patch index 1833cacdfe..cafe54198d 100644 --- a/patches/server/0364-Reduce-Either-Optional-allocation.patch +++ b/patches/server/0364-Reduce-Either-Optional-allocation.patch @@ -7,7 +7,7 @@ In order to get chunk values, we shouldn't need to create an optional each time. diff --git a/src/main/java/com/mojang/datafixers/util/Either.java b/src/main/java/com/mojang/datafixers/util/Either.java -index de524d485fada3c3cca8c2fe6c63db0e0b33dad8..6eb0c94965a6e96ec8ae112125e98c6c4809805b 100644 +index de524d485fada3c3cca8c2fe6c63db0e0b33dad8..a51e8e3eafff17f4f2ff790bf96a2f0e89abca2a 100644 --- a/src/main/java/com/mojang/datafixers/util/Either.java +++ b/src/main/java/com/mojang/datafixers/util/Either.java @@ -22,7 +22,7 @@ public abstract class Either implements App, L> { @@ -15,7 +15,7 @@ index de524d485fada3c3cca8c2fe6c63db0e0b33dad8..6eb0c94965a6e96ec8ae112125e98c6c private static final class Left extends Either { - private final L value; -+ private final L value; private Optional valueOptional; // Paper - reduce the optional allocation... ++ private final L value; private Optional valueOptional; // Paper - Perf: Reduce Either Optional allocation public Left(final L value) { this.value = value; @@ -24,7 +24,7 @@ index de524d485fada3c3cca8c2fe6c63db0e0b33dad8..6eb0c94965a6e96ec8ae112125e98c6c @Override public Optional left() { - return Optional.of(value); -+ return this.valueOptional == null ? this.valueOptional = Optional.of(this.value) : this.valueOptional; // Paper - reduce the optional allocation... ++ return this.valueOptional == null ? this.valueOptional = Optional.of(this.value) : this.valueOptional; // Paper - Perf: Reduce Either Optional allocation } @Override @@ -33,7 +33,7 @@ index de524d485fada3c3cca8c2fe6c63db0e0b33dad8..6eb0c94965a6e96ec8ae112125e98c6c private static final class Right extends Either { - private final R value; -+ private final R value; private Optional valueOptional; // Paper - reduce the optional allocation... ++ private final R value; private Optional valueOptional; // Paper - Perf: Reduce Either Optional allocation public Right(final R value) { this.value = value; @@ -42,7 +42,7 @@ index de524d485fada3c3cca8c2fe6c63db0e0b33dad8..6eb0c94965a6e96ec8ae112125e98c6c @Override public Optional right() { - return Optional.of(value); -+ return this.valueOptional == null ? this.valueOptional = Optional.of(this.value) : this.valueOptional; // Paper - reduce the optional allocation... ++ return this.valueOptional == null ? this.valueOptional = Optional.of(this.value) : this.valueOptional; // Paper - Perf: Reduce Either Optional allocation } @Override diff --git a/patches/server/0365-Reduce-memory-footprint-of-NBTTagCompound.patch b/patches/server/0365-Reduce-memory-footprint-of-CompoundTag.patch similarity index 83% rename from patches/server/0365-Reduce-memory-footprint-of-NBTTagCompound.patch rename to patches/server/0365-Reduce-memory-footprint-of-CompoundTag.patch index 691d9fdb4f..c714de8792 100644 --- a/patches/server/0365-Reduce-memory-footprint-of-NBTTagCompound.patch +++ b/patches/server/0365-Reduce-memory-footprint-of-CompoundTag.patch @@ -1,14 +1,14 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 6 Apr 2020 17:39:25 -0700 -Subject: [PATCH] Reduce memory footprint of NBTTagCompound +Subject: [PATCH] Reduce memory footprint of CompoundTag Fastutil maps are going to have a lower memory footprint - which is important because we clone chunk data after reading it for safety. So, reduce the impact of the clone on GC. diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/net/minecraft/nbt/CompoundTag.java -index c77a6bb6885ffaaa4d9e1aa9d4770d5e847a590b..135530bc9d7ecd0348ace6474f4ca6d2e1bad283 100644 +index c77a6bb6885ffaaa4d9e1aa9d4770d5e847a590b..2c760084cd1b84a1f2c4f6a6db8d396a1b3c5395 100644 --- a/src/main/java/net/minecraft/nbt/CompoundTag.java +++ b/src/main/java/net/minecraft/nbt/CompoundTag.java @@ -50,7 +50,7 @@ public class CompoundTag implements Tag { @@ -16,7 +16,7 @@ index c77a6bb6885ffaaa4d9e1aa9d4770d5e847a590b..135530bc9d7ecd0348ace6474f4ca6d2 private static CompoundTag loadCompound(DataInput input, NbtAccounter tracker) throws IOException { tracker.accountBytes(48L); - Map map = Maps.newHashMap(); -+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound ++ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - Reduce memory footprint of CompoundTag byte b; while((b = input.readByte()) != 0) { @@ -25,7 +25,7 @@ index c77a6bb6885ffaaa4d9e1aa9d4770d5e847a590b..135530bc9d7ecd0348ace6474f4ca6d2 public CompoundTag() { - this(Maps.newHashMap()); -+ this(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - reduce memory footprint of NBTTagCompound ++ this(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - Reduce memory footprint of CompoundTag } @Override @@ -35,7 +35,7 @@ index c77a6bb6885ffaaa4d9e1aa9d4770d5e847a590b..135530bc9d7ecd0348ace6474f4ca6d2 public CompoundTag copy() { - Map map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy)); - return new CompoundTag(map); -+ // Paper start - reduce memory footprint of NBTTagCompound ++ // Paper start - Reduce memory footprint of CompoundTag + it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f); + java.util.Iterator> iterator = (this.tags instanceof it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) ? ((it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap)this.tags).object2ObjectEntrySet().fastIterator() : this.tags.entrySet().iterator(); + while (iterator.hasNext()) { @@ -44,7 +44,7 @@ index c77a6bb6885ffaaa4d9e1aa9d4770d5e847a590b..135530bc9d7ecd0348ace6474f4ca6d2 + } + + return new CompoundTag(ret); -+ // Paper end - reduce memory footprint of NBTTagCompound ++ // Paper end - Reduce memory footprint of CompoundTag } @Override diff --git a/patches/server/0366-Prevent-opening-inventories-when-frozen.patch b/patches/server/0366-Prevent-opening-inventories-when-frozen.patch index f6702d49e4..0b9ec25c07 100644 --- a/patches/server/0366-Prevent-opening-inventories-when-frozen.patch +++ b/patches/server/0366-Prevent-opening-inventories-when-frozen.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent opening inventories when frozen diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 3738680d935695930be19cdc18478c62ccb93d3a..f0dd4bd0fd71c90577a5b42a803007de8e97d344 100644 +index e8470f0cc918ae20caa9aa4de7a81edf31f2f556..f84be7bff9c054baf5ce0c0183ec986c7d30c352 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -701,7 +701,7 @@ public class ServerPlayer extends Player { @@ -13,7 +13,7 @@ index 3738680d935695930be19cdc18478c62ccb93d3a..f0dd4bd0fd71c90577a5b42a803007de } // Paper end - if (!this.level().isClientSide && !this.containerMenu.stillValid(this)) { -+ if (!this.level().isClientSide && this.containerMenu != this.inventoryMenu && (this.isImmobile() || !this.containerMenu.stillValid(this))) { // Paper - auto close while frozen ++ if (!this.level().isClientSide && this.containerMenu != this.inventoryMenu && (this.isImmobile() || !this.containerMenu.stillValid(this))) { // Paper - Prevent opening inventories when frozen this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper this.containerMenu = this.inventoryMenu; } @@ -22,12 +22,12 @@ index 3738680d935695930be19cdc18478c62ccb93d3a..f0dd4bd0fd71c90577a5b42a803007de // CraftBukkit start this.containerMenu = container; - this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); -+ if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper ++ if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper - Prevent opening inventories when frozen // CraftBukkit end this.initMenu(container); return OptionalInt.of(this.containerCounter); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 0d07501bb9e8721771f5c3fd099f022e41a54337..fa585b6bf914362a7f9e55a20e78811519353608 100644 +index 0d07501bb9e8721771f5c3fd099f022e41a54337..0effc7dfe2c1f2bad7bd00b6a615497d4aa0ba91 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -325,7 +325,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @@ -35,7 +35,7 @@ index 0d07501bb9e8721771f5c3fd099f022e41a54337..fa585b6bf914362a7f9e55a20e788115 //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment - player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper -+ if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper ++ if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen player.containerMenu = container; player.initMenu(container); } @@ -44,7 +44,7 @@ index 0d07501bb9e8721771f5c3fd099f022e41a54337..fa585b6bf914362a7f9e55a20e788115 if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(inventory.getTitle()); // Paper //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment - player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper -+ if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper ++ if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen player.containerMenu = container; player.initMenu(container); } diff --git a/patches/server/0367-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/server/0367-Don-t-run-entity-collision-code-if-not-needed.patch index 36a11c3c1f..5351a728aa 100644 --- a/patches/server/0367-Don-t-run-entity-collision-code-if-not-needed.patch +++ b/patches/server/0367-Don-t-run-entity-collision-code-if-not-needed.patch @@ -12,7 +12,7 @@ The entity's current team collision rule causes them to NEVER collide. Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index f9e2d3cba01fcf39bc29dc8b5b5879ddc3add0e5..0f364937ee7caa0496cfff1f9e5692d83a4dcd97 100644 +index f9e2d3cba01fcf39bc29dc8b5b5879ddc3add0e5..cf946ea3367b7b7656343b48bf8140efc38d07a2 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3398,10 +3398,24 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -37,7 +37,7 @@ index f9e2d3cba01fcf39bc29dc8b5b5879ddc3add0e5..0f364937ee7caa0496cfff1f9e5692d8 if (!list.isEmpty()) { - int i = this.level().getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING); -+ // Paper - moved up ++ // Paper - don't run getEntities if we're not going to use its result; moved up if (i > 0 && list.size() > i - 1 && this.random.nextInt(4) == 0) { int j = 0; diff --git a/patches/server/0368-Implement-Player-Client-Options-API.patch b/patches/server/0368-Implement-Player-Client-Options-API.patch index bad37099c0..385a131978 100644 --- a/patches/server/0368-Implement-Player-Client-Options-API.patch +++ b/patches/server/0368-Implement-Player-Client-Options-API.patch @@ -87,13 +87,13 @@ index 0000000000000000000000000000000000000000..b6f4400df3d8ec7e06a996de54f8cabb + } +} diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index f0dd4bd0fd71c90577a5b42a803007de8e97d344..37af010c2af4b485d19bbf5fef978d6347054c83 100644 +index f84be7bff9c054baf5ce0c0183ec986c7d30c352..cb137fe3aaa14fd4862baa0444bc62d818cf9509 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -386,7 +386,7 @@ public class ServerPlayer extends Player { this.advancements = server.getPlayerList().getPlayerAdvancements(this); this.setMaxUpStep(1.0F); - // this.fudgeSpawnLocation(world); // Paper - don't move to spawn on login, only first join + // this.fudgeSpawnLocation(world); // Paper - Don't move existing players to world spawn - this.updateOptions(clientOptions); + this.updateOptionsNoEvents(clientOptions); // Paper - don't call options events on login diff --git a/patches/server/0369-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/server/0369-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch index e5cdd1f624..fdccb38226 100644 --- a/patches/server/0369-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch +++ b/patches/server/0369-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Don't crash if player is attempted to be removed from I suspect it deals with teleporting as it uses players current x/y/z diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index b01006ade4750f60ceba951812bbc6e2ca04bf9c..33b0be8eb9bff8068ca7bdeffe34b7f2eaa6dbfb 100644 +index 36686a92bd7dc0e29049f72c0e953ff56c2645eb..c80a625f7289e3bb33c6851d2072957e153ca1fb 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -146,8 +146,8 @@ public abstract class DistanceManager { @@ -16,7 +16,7 @@ index b01006ade4750f60ceba951812bbc6e2ca04bf9c..33b0be8eb9bff8068ca7bdeffe34b7f2 - objectset.remove(player); - if (objectset.isEmpty()) { -+ if (objectset != null) objectset.remove(player); // Paper - some state corruption happens here, don't crash, clean up gracefully. ++ if (objectset != null) objectset.remove(player); // Paper - some state corruption happens here, don't crash, clean up gracefully + if (objectset == null || objectset.isEmpty()) { // Paper this.playersPerChunk.remove(i); this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false); diff --git a/patches/server/0370-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/patches/server/0370-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch similarity index 74% rename from patches/server/0370-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch rename to patches/server/0370-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch index 40f07de971..f60e83e579 100644 --- a/patches/server/0370-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch +++ b/patches/server/0370-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 19 Apr 2020 00:05:46 -0400 -Subject: [PATCH] Fix Longstanding Broken behavior of PlayerJoinEvent +Subject: [PATCH] Fire PlayerJoinEvent when Player is actually ready For years, plugin developers have had to delay many things they do inside of the PlayerJoinEvent by 1 tick to make it actually work. @@ -31,43 +31,43 @@ delays anymore. public net.minecraft.server.level.ChunkMap addEntity(Lnet/minecraft/world/entity/Entity;)V diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 876200db872bce89976329c4d6c6fbe9fd155f24..2db3236bc9d676c86b0af38bd4bfaf9d3332c250 100644 +index 3b7a82761682e29fb42f683b232c789c522b632e..cafc332e5828e53999210b06980c4bdb09d5cedb 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -999,6 +999,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - + ": " + entity + (this.entityMap.containsKey(entity.getId()) ? " ALREADY CONTAINED (This would have crashed your server)" : ""), new Throwable()); +@@ -1000,6 +1000,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider return; } -+ if (entity instanceof ServerPlayer && ((ServerPlayer) entity).supressTrackerForLogin) return; // Delay adding to tracker until after list packets - // Paper end + // Paper end - ignore and warn about illegal addEntity calls instead of crashing server ++ if (entity instanceof ServerPlayer && ((ServerPlayer) entity).supressTrackerForLogin) return; // Paper - Fire PlayerJoinEvent when Player is actually ready; Delay adding to tracker until after list packets if (!(entity instanceof EnderDragonPart)) { EntityType entitytypes = entity.getType(); + int i = entitytypes.clientTrackingRange() * 16; diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 37af010c2af4b485d19bbf5fef978d6347054c83..71068a285ff039b609f4551d522481f2dff8235e 100644 +index cb137fe3aaa14fd4862baa0444bc62d818cf9509..32b41d88af7565665a19663227475d984cbfd7b2 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -271,6 +271,7 @@ public class ServerPlayer extends Player { public double maxHealthCache; public boolean joining = true; public boolean sentListPacket = false; -+ public boolean supressTrackerForLogin = false; // Paper ++ public boolean supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent // CraftBukkit end public boolean isRealPlayer; // Paper diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 8c9dcd895f73765327ac00d7cc706b6ae8b9d81f..66a39d00c23bf6bced8ea9c177d84d1409cd2c11 100644 +index 077ae008b817d38082a068f4bbd76181510403bf..ffdd5b7417bb748ee5e8ad4d126bf3489c5d32ed 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -295,6 +295,12 @@ public abstract class PlayerList { this.playersByUUID.put(player.getUUID(), player); // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer))); // CraftBukkit - replaced with loop below -+ // Paper start - correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks ++ // Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks + player.supressTrackerForLogin = true; + worldserver1.addNewPlayer(player); + this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below worldserver.addPlayerJoin(entityplayer); + mountSavedVehicle(player, worldserver1, nbttagcompound); -+ // Paper end ++ // Paper end - Fire PlayerJoinEvent when Player is actually ready // CraftBukkit start CraftPlayer bukkitPlayer = player.getBukkitEntity(); @@ -75,8 +75,8 @@ index 8c9dcd895f73765327ac00d7cc706b6ae8b9d81f..66a39d00c23bf6bced8ea9c177d84d14 player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer1))); } player.sentListPacket = true; -+ player.supressTrackerForLogin = false; // Paper -+ ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - track entity now ++ player.supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready ++ ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now // CraftBukkit end player.getEntityData().refresh(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn @@ -84,11 +84,11 @@ index 8c9dcd895f73765327ac00d7cc706b6ae8b9d81f..66a39d00c23bf6bced8ea9c177d84d14 playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect)); } -+ // Paper start - move vehicle into method so it can be called above - short circuit around that code ++ // Paper start - Fire PlayerJoinEvent when Player is actually ready; move vehicle into method so it can be called above - short circuit around that code + onPlayerJoinFinish(player, worldserver1, s1); + } + private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, CompoundTag nbttagcompound) { -+ // Paper end ++ // Paper end - Fire PlayerJoinEvent when Player is actually ready if (nbttagcompound != null && nbttagcompound.contains("RootVehicle", 10)) { CompoundTag nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); // CraftBukkit start @@ -96,10 +96,10 @@ index 8c9dcd895f73765327ac00d7cc706b6ae8b9d81f..66a39d00c23bf6bced8ea9c177d84d14 } } -+ // Paper start ++ // Paper start - Fire PlayerJoinEvent when Player is actually ready + } + public void onPlayerJoinFinish(ServerPlayer player, ServerLevel worldserver1, String s1) { -+ // Paper end ++ // Paper end - Fire PlayerJoinEvent when Player is actually ready player.initInventoryMenu(); // CraftBukkit - Moved from above, added world // Paper start - Add to collideRule team if needed diff --git a/patches/server/0371-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/server/0371-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch index a80ab4fdbf..b2bba66ea4 100644 --- a/patches/server/0371-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch +++ b/patches/server/0371-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch @@ -10,7 +10,7 @@ Co-authored-by: Wyatt Childers Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 66a39d00c23bf6bced8ea9c177d84d1409cd2c11..5c5d1e387ea00a17db99b3ef1f68eede01b09789 100644 +index ffdd5b7417bb748ee5e8ad4d126bf3489c5d32ed..538ba950d194ec823443d1bdaf38a32eddf85df7 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -194,7 +194,7 @@ public abstract class PlayerList { @@ -79,11 +79,11 @@ index 66a39d00c23bf6bced8ea9c177d84d1409cd2c11..5c5d1e387ea00a17db99b3ef1f68eede // Paper start if (nbttagcompound == null) { player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login -+ // Paper start - reset to main world spawn if first spawn or invalid world ++ // Paper start - reset to main world spawn if first spawn or invalid world + } + if (nbttagcompound == null || invalidPlayerWorld) { -+ // Paper end - player.fudgeSpawnLocation(worldserver1); // only move to spawn on first login, otherwise, stay where you are.... ++ // Paper end - reset to main world spawn if first spawn or invalid world + player.fudgeSpawnLocation(worldserver1); // Paper - Don't move existing players to world spawn } // Paper end diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java diff --git a/patches/server/0372-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/server/0372-Add-PlayerAttackEntityCooldownResetEvent.patch index 63d51833e1..e25e7d2507 100644 --- a/patches/server/0372-Add-PlayerAttackEntityCooldownResetEvent.patch +++ b/patches/server/0372-Add-PlayerAttackEntityCooldownResetEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerAttackEntityCooldownResetEvent diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 0f364937ee7caa0496cfff1f9e5692d83a4dcd97..a4b1066bbb36cce7505e5e6dc033b0266ce85974 100644 +index cf946ea3367b7b7656343b48bf8140efc38d07a2..d3bb5a6ee350043e7f5c173b9496c1d71b3957b1 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -2190,7 +2190,16 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -22,7 +22,7 @@ index 0f364937ee7caa0496cfff1f9e5692d83a4dcd97..a4b1066bbb36cce7505e5e6dc033b026 + } else { + ((net.minecraft.world.entity.player.Player) damagesource.getEntity()).resetAttackStrengthTicker(); + } -+ // Paper end ++ // Paper end - PlayerAttackEntityCooldownResetEvent } if (event.isCancelled()) { return false; diff --git a/patches/server/0373-Don-t-fire-BlockFade-on-worldgen-threads.patch b/patches/server/0373-Don-t-fire-BlockFade-on-worldgen-threads.patch index 2d41b1259c..833140ffaa 100644 --- a/patches/server/0373-Don-t-fire-BlockFade-on-worldgen-threads.patch +++ b/patches/server/0373-Don-t-fire-BlockFade-on-worldgen-threads.patch @@ -3,10 +3,9 @@ From: Aikar Date: Thu, 23 Apr 2020 01:36:39 -0400 Subject: [PATCH] Don't fire BlockFade on worldgen threads -Caused a deadlock diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java -index 80e90bae3c05bbaf978a66629d9c4132c22efd1a..8fce3ad36a6ee8166f4abd9e0e369b641d487af9 100644 +index 80e90bae3c05bbaf978a66629d9c4132c22efd1a..a447231db1362ebda706d6069a92be4ead196c21 100644 --- a/src/main/java/net/minecraft/world/level/block/FireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java @@ -108,6 +108,7 @@ public class FireBlock extends BaseFireBlock { @@ -22,7 +21,7 @@ index 80e90bae3c05bbaf978a66629d9c4132c22efd1a..8fce3ad36a6ee8166f4abd9e0e369b64 } } - return this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)); -+ return this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)); // Paper - diff on change, see "don't fire events in world generation" ++ return this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)); // Paper - don't fire events in world generation; diff on change, see "don't fire events in world generation" // CraftBukkit end } diff --git a/patches/server/0374-Add-phantom-creative-and-insomniac-controls.patch b/patches/server/0374-Add-phantom-creative-and-insomniac-controls.patch index 47e6a46746..5a377dbb7f 100644 --- a/patches/server/0374-Add-phantom-creative-and-insomniac-controls.patch +++ b/patches/server/0374-Add-phantom-creative-and-insomniac-controls.patch @@ -5,31 +5,31 @@ Subject: [PATCH] Add phantom creative and insomniac controls diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index 170fbb1d80947b9b21c2106497baae5c37bcdc0c..68e4440765636295a74ea942862d772d47282ad6 100644 +index 170fbb1d80947b9b21c2106497baae5c37bcdc0c..c9c7833755af3c7bef1d40f2ca425cbec59efa68 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java @@ -28,6 +28,7 @@ public final class EntitySelector { return !entity.isSpectator(); }; public static final Predicate CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith); -+ public static Predicate IS_INSOMNIAC = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper ++ public static Predicate IS_INSOMNIAC = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper - Add phantom creative and insomniac controls private EntitySelector() {} // Paper start diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index 658393f451e46a93c5665fe3c580aa395ace68d1..a40852acf5d175cc3a06bc17fb021c76f0c11a28 100644 +index 658393f451e46a93c5665fe3c580aa395ace68d1..ea980c2fdf01988ba25bffc7f8963d775101bee1 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java @@ -568,6 +568,7 @@ public class Phantom extends FlyingMob implements Enemy { Player entityhuman = (Player) iterator.next(); if (Phantom.this.canAttack(entityhuman, TargetingConditions.DEFAULT)) { -+ if (!level().paperConfig().entities.behavior.phantomsOnlyAttackInsomniacs || EntitySelector.IS_INSOMNIAC.test(entityhuman)) // Paper ++ if (!level().paperConfig().entities.behavior.phantomsOnlyAttackInsomniacs || EntitySelector.IS_INSOMNIAC.test(entityhuman)) // Paper - Add phantom creative and insomniac controls Phantom.this.setTarget(entityhuman, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit - reason return true; } diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index 94ee9c399f59e0198b4d9bc2a4255e8b821bcd36..b1fc786970b5288a02cc3a46e3fe7784ac566c07 100644 +index 94ee9c399f59e0198b4d9bc2a4255e8b821bcd36..8c9caa324402568ce9f55e733f4d14430159347a 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -49,7 +49,7 @@ public class PhantomSpawner implements CustomSpawner { @@ -37,7 +37,7 @@ index 94ee9c399f59e0198b4d9bc2a4255e8b821bcd36..b1fc786970b5288a02cc3a46e3fe7784 ServerPlayer entityplayer = (ServerPlayer) iterator.next(); - if (!entityplayer.isSpectator()) { -+ if (!entityplayer.isSpectator() && (!world.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !entityplayer.isCreative())) { // Paper ++ if (!entityplayer.isSpectator() && (!world.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !entityplayer.isCreative())) { // Paper - Add phantom creative and insomniac controls BlockPos blockposition = entityplayer.blockPosition(); if (!world.dimensionType().hasSkyLight() || blockposition.getY() >= world.getSeaLevel() && world.canSeeSky(blockposition)) { diff --git a/patches/server/0375-Fix-numerous-item-duplication-issues-and-teleport-is.patch b/patches/server/0375-Fix-item-duplication-and-teleport-issues.patch similarity index 92% rename from patches/server/0375-Fix-numerous-item-duplication-issues-and-teleport-is.patch rename to patches/server/0375-Fix-item-duplication-and-teleport-issues.patch index e18ab6411f..265b5f8726 100644 --- a/patches/server/0375-Fix-numerous-item-duplication-issues-and-teleport-is.patch +++ b/patches/server/0375-Fix-item-duplication-and-teleport-issues.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 25 Apr 2020 06:46:35 -0400 -Subject: [PATCH] Fix numerous item duplication issues and teleport issues +Subject: [PATCH] Fix item duplication and teleport issues This notably fixes the newest "Donkey Dupe", but also fixes a lot of dupe bugs in general around nether portals and entity world transfer @@ -16,7 +16,7 @@ So even if something NEW comes up, it would be impossible to drop the same item twice because the source was destroyed. diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b2dc3729a8312179d219bd93a755729c86f4dece..88632cf1baea828f6442ac37b8c13a3356445fe3 100644 +index b2dc3729a8312179d219bd93a755729c86f4dece..d13759736cf802cae56e68c11f09f15e1e08d09c 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2467,11 +2467,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S @@ -38,12 +38,12 @@ index b2dc3729a8312179d219bd93a755729c86f4dece..88632cf1baea828f6442ac37b8c13a33 @Nullable public Entity teleportTo(ServerLevel worldserver, Vec3 location) { // CraftBukkit end -+ // Paper start - fix bad state entities causing dupes ++ // Paper start - Fix item duplication and teleport issues + if (!this.isAlive() || !this.valid) { + LOGGER.warn("Illegal Entity Teleport " + this + " to " + worldserver + ":" + location, new Throwable()); + return null; + } -+ // Paper end ++ // Paper end - Fix item duplication and teleport issues if (this.level() instanceof ServerLevel && !this.isRemoved()) { this.level().getProfiler().push("changeDimension"); // CraftBukkit start @@ -51,11 +51,11 @@ index b2dc3729a8312179d219bd93a755729c86f4dece..88632cf1baea828f6442ac37b8c13a33 // CraftBukkit end this.level().getProfiler().popPush("reloading"); -+ // Paper start - Change lead drop timing to prevent dupe ++ // Paper start - Fix item duplication and teleport issues + if (this instanceof Mob) { + ((Mob) this).dropLeash(true, true); // Paper drop lead + } -+ // Paper end ++ // Paper end - Fix item duplication and teleport issues Entity entity = this.getType().create(worldserver); if (entity != null) { @@ -75,12 +75,12 @@ index b2dc3729a8312179d219bd93a755729c86f4dece..88632cf1baea828f6442ac37b8c13a33 public boolean canChangeDimensions() { - return !this.isPassenger() && !this.isVehicle(); -+ return !this.isPassenger() && !this.isVehicle() && isAlive() && valid; // Paper ++ return !this.isPassenger() && !this.isVehicle() && isAlive() && valid; // Paper - Fix item duplication and teleport issues } public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a4b1066bbb36cce7505e5e6dc033b0266ce85974..2fa60d96da53ca954dc1421745fafaeb2e806ed0 100644 +index d3bb5a6ee350043e7f5c173b9496c1d71b3957b1..0af0b62a4bd9b3c027a5a608b81831864d54fd11 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -1705,9 +1705,9 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -90,7 +90,7 @@ index a4b1066bbb36cce7505e5e6dc033b0266ce85974..2fa60d96da53ca954dc1421745fafaeb - if (this.deathScore >= 0 && entityliving != null) { - entityliving.awardKillScore(this, this.deathScore, damageSource); - } -+ // if (this.deathScore >= 0 && entityliving != null) { // Paper moved to be run earlier in #dropAllDeathLoot before destroying the drop items in CraftEventFactory#callEntityDeathEvent ++ // if (this.deathScore >= 0 && entityliving != null) { // Paper - Fix item duplication and teleport issues; moved to be run earlier in #dropAllDeathLoot before destroying the drop items in CraftEventFactory#callEntityDeathEvent + // entityliving.awardKillScore(this, this.deathScore, damageSource); + // } // Paper start - clear equipment if event is not cancelled diff --git a/patches/server/0377-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/server/0377-Validate-PickItem-Packet-and-kick-for-invalid.patch index 9010a829f8..28e4d939a3 100644 --- a/patches/server/0377-Validate-PickItem-Packet-and-kick-for-invalid.patch +++ b/patches/server/0377-Validate-PickItem-Packet-and-kick-for-invalid.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Validate PickItem Packet and kick for invalid diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 00fa6126ca51b6ffdb46b59f07725ffdcca9f20a..a6d72d4ace089c76deb87ade48194ccd0517bee0 100644 +index 00fa6126ca51b6ffdb46b59f07725ffdcca9f20a..18c8dc09b75dbaff13a3cf7ba8594c49ed168c45 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -867,7 +867,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -20,7 +20,7 @@ index 00fa6126ca51b6ffdb46b59f07725ffdcca9f20a..a6d72d4ace089c76deb87ade48194ccd + return; + } + this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed -+ // Paper end ++ // Paper end - validate pick item position this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, this.player.getInventory().selected, this.player.getInventory().getItem(this.player.getInventory().selected))); this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, packet.getSlot(), this.player.getInventory().getItem(packet.getSlot()))); this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.getInventory().selected)); diff --git a/patches/server/0380-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch b/patches/server/0380-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch index cdc7743697..7a21f2b215 100644 --- a/patches/server/0380-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch +++ b/patches/server/0380-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch @@ -17,14 +17,14 @@ keeping long lived large direct buffers in cache. Set system properly at server startup if not set already to help protect from this. diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index fa9c17c49a17b8325a7510316de89e3ff3b6f1cf..37faa5ce82ae9ca2893250d86cc2eb21c00cc81f 100644 +index 787dc5702bce3b5171f834ad3177013ac684be72..01b616143562d41aeba7f1340e0affa21d0655b8 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -26,6 +26,7 @@ public class Main { } // Paper end // Todo: Installation script -+ if (System.getProperty("jdk.nio.maxCachedBufferSize") == null) System.setProperty("jdk.nio.maxCachedBufferSize", "262144"); // Paper - cap per-thread NIO cache size ++ if (System.getProperty("jdk.nio.maxCachedBufferSize") == null) System.setProperty("jdk.nio.maxCachedBufferSize", "262144"); // Paper - cap per-thread NIO cache size; https://www.evanjones.ca/java-bytebuffer-leak.html OptionParser parser = new OptionParser() { { this.acceptsAll(Main.asList("?", "help"), "Show the help"); diff --git a/patches/server/0381-misc-debugging-dumps.patch b/patches/server/0381-misc-debugging-dumps.patch index 8fda4d258f..ac8206b2e8 100644 --- a/patches/server/0381-misc-debugging-dumps.patch +++ b/patches/server/0381-misc-debugging-dumps.patch @@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..2d5494d2813b773e60ddba6790b750a9 + } +} diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index b27256d251e5db5781197319f79f89cc7638c80b..337ff2b3e8ea6f106656cf4bef029d81998e0e58 100644 +index b27256d251e5db5781197319f79f89cc7638c80b..043541d0c93ed7c06c2c01fe6065dd57dd4c0916 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java @@ -341,7 +341,7 @@ public class Commands { @@ -37,19 +37,19 @@ index b27256d251e5db5781197319f79f89cc7638c80b..337ff2b3e8ea6f106656cf4bef029d81 MutableComponent ichatmutablecomponent = Component.literal(exception.getMessage() == null ? exception.getClass().getName() : exception.getMessage()); - if (Commands.LOGGER.isDebugEnabled()) { -+ if (commandlistenerwrapper.getServer().isDebugging() || Commands.LOGGER.isDebugEnabled()) { // Paper ++ if (commandlistenerwrapper.getServer().isDebugging() || Commands.LOGGER.isDebugEnabled()) { // Paper - Debugging Commands.LOGGER.error("Command exception: /{}", s, exception); StackTraceElement[] astacktraceelement = exception.getStackTrace(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 9a25d351df1141e9218d37c0f90e2d67f9c8c3ef..eab8da0689dcb159cb54b418804e86b6364273fb 100644 +index 3f33f6764665e79433226ebe495bf4cfa8100123..b61dd9730ed56fc0c1a10f9c4e0a9630bb668206 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -918,6 +918,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop set) { // Paper -+ // Paper start ++ // Paper start - Prevent teleporting dead entities + if (player.isRemoved()) { + LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName()); + if (server.isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Attempt to teleport removed player"); + return; + } -+ // Paper end ++ // Paper end - Prevent teleporting dead entities // CraftBukkit start if (Float.isNaN(f)) { f = 0; diff --git a/patches/server/0383-Deobfuscate-stacktraces-in-log-messages-crash-report.patch b/patches/server/0383-Deobfuscate-stacktraces-in-log-messages-crash-report.patch index 0343b8f952..582d9f7ef8 100644 --- a/patches/server/0383-Deobfuscate-stacktraces-in-log-messages-crash-report.patch +++ b/patches/server/0383-Deobfuscate-stacktraces-in-log-messages-crash-report.patch @@ -557,7 +557,7 @@ index c9cca6ba3500791485bf19155156c38c24f1c761..684e9e9d78f0d410176fa8b9c9d0fbfd this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess()); this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess()); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 1c0d2aad70b3817913e93354ccc055b82ae321bc..51379dc93af2eaa3294179debe067d62627b60e1 100644 +index 46101e6bef0f81968cb194303e19e437a3417733..1bab7d1c76a087e5bd22d7adbee5e065e8e2241e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -222,7 +222,9 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -581,17 +581,17 @@ index 1c0d2aad70b3817913e93354ccc055b82ae321bc..51379dc93af2eaa3294179debe067d62 } // Paper end diff --git a/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java -index e48b287d6229f8043fba8a417f0b7558d6079783..cae10b963d153fb1777b18054796a45b2809342b 100644 +index d130f843975236018df4fa2ccc3ca6aaca7a06b8..76f31845fe50200d09e5ab6a6c08da00444414ad 100644 --- a/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java @@ -133,7 +133,7 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis ServerConfigurationPacketListenerImpl.LOGGER.error("Couldn't place player in world", exception); - // Paper start + // Paper start - Debugging if (MinecraftServer.getServer().isDebugging()) { - exception.printStackTrace(); + io.papermc.paper.util.TraceUtil.printStackTrace(exception); } - // Paper end + // Paper end - Debugging this.connection.send(new ClientboundDisconnectPacket(ServerConfigurationPacketListenerImpl.DISCONNECT_REASON_INVALID_DATA)); diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java index caeead6c6082855f1651ee28263cc9f60423ca0c..b2bfb3893200362ac35ae60982f203f86a1148ec 100644 diff --git a/patches/server/0384-Implement-Mob-Goal-API.patch b/patches/server/0384-Implement-Mob-Goal-API.patch index 46c6388063..e5f9766f2e 100644 --- a/patches/server/0384-Implement-Mob-Goal-API.patch +++ b/patches/server/0384-Implement-Mob-Goal-API.patch @@ -744,20 +744,20 @@ index 0000000000000000000000000000000000000000..0d30e0b21b9024df939a9d070bd4a99b + } +} diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java -index 4379b9948f1eecfe6fd7dea98e298ad5f761019a..3f081183521603824430709886a9cc313c28e7cb 100644 +index 4379b9948f1eecfe6fd7dea98e298ad5f761019a..b0ee4fbd4a52e30a9dff4179aa0fbf62ee1767ad 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java @@ -7,6 +7,14 @@ public abstract class Goal { private final EnumSet flags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector -+ // Paper start make sure goaltypes is never empty ++ // Paper start - Mob goal API; make sure goaltypes is never empty + public Goal() { + if (this.goalTypes.size() == 0) { + this.goalTypes.addUnchecked(Flag.UNKNOWN_BEHAVIOR); + } + } -+ // Paper end ++ // Paper end - Mob goal API + public abstract boolean canUse(); @@ -777,7 +777,7 @@ index 4379b9948f1eecfe6fd7dea98e298ad5f761019a..3f081183521603824430709886a9cc31 return Mth.positiveCeilDiv(serverTicks, 2); } -+ // Paper start - mob goal api ++ // Paper start - Mob goal api + private com.destroystokyo.paper.entity.ai.PaperVanillaGoal vanillaGoal = null; + public com.destroystokyo.paper.entity.ai.Goal asPaperVanillaGoal() { + if(this.vanillaGoal == null) { @@ -786,7 +786,7 @@ index 4379b9948f1eecfe6fd7dea98e298ad5f761019a..3f081183521603824430709886a9cc31 + //noinspection unchecked + return (com.destroystokyo.paper.entity.ai.Goal) this.vanillaGoal; + } -+ // Paper end - mob goal api ++ // Paper end - Mob goal api + public static enum Flag { + UNKNOWN_BEHAVIOR, // Paper - add UNKNOWN_BEHAVIOR @@ -794,7 +794,7 @@ index 4379b9948f1eecfe6fd7dea98e298ad5f761019a..3f081183521603824430709886a9cc31 LOOK, JUMP, diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 2d799bd4903113e35acfc7068996a85ddf3d119e..1931e33d8a187a5adbd4fa9591f681ee6adc5cc3 100644 +index 2333858596a76ff8dddb014f31ad2a3d7e926baf..6fd94e54abe92b1a081591a64af8da09b9303d08 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -2881,5 +2881,11 @@ public final class CraftServer implements Server { diff --git a/patches/server/0385-Add-villager-reputation-API.patch b/patches/server/0385-Add-villager-reputation-API.patch index 95494c8d09..04891189ff 100644 --- a/patches/server/0385-Add-villager-reputation-API.patch +++ b/patches/server/0385-Add-villager-reputation-API.patch @@ -9,7 +9,7 @@ public net.minecraft.world.entity.ai.gossip.GossipContainer$EntityGossips public net.minecraft.world.entity.ai.gossip.GossipContainer gossips diff --git a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java -index a28f359202e6502c6ea5e9c918ec0b3e9a3fca61..76dffb2705e5207db96895f82f1c7c5638f817c6 100644 +index a28f359202e6502c6ea5e9c918ec0b3e9a3fca61..f1e717dc8320a00c0cc0ff53d97b74e7c1e109fe 100644 --- a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java +++ b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java @@ -231,6 +231,43 @@ public class GossipContainer { @@ -52,7 +52,7 @@ index a28f359202e6502c6ea5e9c918ec0b3e9a3fca61..76dffb2705e5207db96895f82f1c7c56 + case TRADING -> com.destroystokyo.paper.entity.villager.ReputationType.TRADING; + }; + } -+ // Paper end ++ // Paper end - Add villager reputation API } static record GossipEntry(UUID target, GossipType type, int value) { diff --git a/patches/server/0386-Option-for-maximum-exp-value-when-merging-orbs.patch b/patches/server/0386-Option-for-maximum-exp-value-when-merging-orbs.patch index ad51f871bb..e5b269cb1d 100644 --- a/patches/server/0386-Option-for-maximum-exp-value-when-merging-orbs.patch +++ b/patches/server/0386-Option-for-maximum-exp-value-when-merging-orbs.patch @@ -5,14 +5,14 @@ Subject: [PATCH] Option for maximum exp value when merging orbs diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 5d28312a03f1571bb44c31f82e27288d02776a5a..85cad0c7437642c72d806f59cb077db4056a4282 100644 +index 5d28312a03f1571bb44c31f82e27288d02776a5a..7fe49c85e3bebe460c7d61864ed3878ef8cd999f 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -702,16 +702,30 @@ public class CraftEventFactory { if (entity instanceof net.minecraft.world.entity.ExperienceOrb xp) { double radius = world.spigotConfig.expMerge; if (radius > 0) { -+ // Paper start - Maximum exp value when merging - Whole section has been tweaked, see comments for specifics ++ // Paper start - Maximum exp value when merging; Whole section has been tweaked, see comments for specifics + final int maxValue = world.paperConfig().entities.behavior.experienceMergeMaxValue; + final boolean mergeUnconditionally = world.paperConfig().entities.behavior.experienceMergeMaxValue <= 0; + if (mergeUnconditionally || xp.value < maxValue) { // Paper - Skip iteration if unnecessary @@ -31,7 +31,7 @@ index 5d28312a03f1571bb44c31f82e27288d02776a5a..85cad0c7437642c72d806f59cb077db4 + } else { xp.value += loopItem.value; loopItem.discard(); -+ } // Paper end ++ } // Paper end - Maximum exp value when merging } } } diff --git a/patches/server/0390-Wait-for-Async-Tasks-during-shutdown.patch b/patches/server/0390-Wait-for-Async-Tasks-during-shutdown.patch index 2a06bb5735..61437d4f28 100644 --- a/patches/server/0390-Wait-for-Async-Tasks-during-shutdown.patch +++ b/patches/server/0390-Wait-for-Async-Tasks-during-shutdown.patch @@ -10,26 +10,26 @@ Adds a 5 second grace period for any async tasks to finish and warns if any are still running after that delay just as reload does. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index eab8da0689dcb159cb54b418804e86b6364273fb..728858a2a52bd23c7b42d0e7340abf5f09d24fc5 100644 +index b61dd9730ed56fc0c1a10f9c4e0a9630bb668206..e6271f1c0bb5a3debeb5bf2e33e02fb0f6af6976 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -958,6 +958,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0.0F; f -= 0.22500001F) { BlockPos blockposition = BlockPos.containing(d4, d5, d6); BlockState iblockdata = this.level.getBlockState(blockposition); -+ if (!iblockdata.isDestroyable()) continue; // Paper ++ if (!iblockdata.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed FluidState fluid = iblockdata.getFluidState(); // Paper if (!this.level.isInWorldBounds(blockposition)) { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 1bb5867bb2e99be1696c89ec47cd3aa0d655fdfb..a7fca2d662e013809fef088213cf0275b596629d 100644 +index 1bb5867bb2e99be1696c89ec47cd3aa0d655fdfb..6941a14b37d4637a1414c4a6c9380a5d7a72711d 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -521,6 +521,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) { // CraftBukkit start - tree generation if (this.captureTreeGeneration) { -+ // Paper start ++ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed + BlockState type = getBlockState(pos); + if (!type.isDestroyable()) return false; -+ // Paper end ++ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed CraftBlockState blockstate = this.capturedBlockStates.get(pos); if (blockstate == null) { blockstate = CapturedBlockState.getTreeBlockState(this, pos, flags); @@ -64,19 +64,19 @@ index 89a62fbeeb78c864938a1cea84178478c6dc1b34..5e5199b50847958f7abc6d8e42cfb680 public co.aikar.timings.Timing getTiming() { if (timing == null) { diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index b3732a6246a2b011e36c5c35fa2ac7749e75db16..bb6c38bb7a054b94a63690f6fd6036d6f376dae4 100644 +index b3732a6246a2b011e36c5c35fa2ac7749e75db16..e4a3c937950b26e81b89d6ddcf3d6c2794ed934d 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java @@ -212,6 +212,12 @@ public class PistonBaseBlock extends DirectionalBlock { @Override public boolean triggerEvent(BlockState state, Level world, BlockPos pos, int type, int data) { Direction enumdirection = (Direction) state.getValue(PistonBaseBlock.FACING); -+ // Paper start - prevent retracting when we're facing the wrong way (we were replaced before retraction could occur) ++ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed; prevent retracting when we're facing the wrong way (we were replaced before retraction could occur) + Direction directionQueuedAs = Direction.from3DDataValue(data & 7); // Paper - copied from below + if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits && enumdirection != directionQueuedAs) { + return false; + } -+ // Paper end - prevent retracting when we're facing the wrong way ++ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed BlockState iblockdata1 = (BlockState) state.setValue(PistonBaseBlock.EXTENDED, true); if (!world.isClientSide) { @@ -85,7 +85,7 @@ index b3732a6246a2b011e36c5c35fa2ac7749e75db16..bb6c38bb7a054b94a63690f6fd6036d6 world.setBlock(pos, iblockdata2, 20); - world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true)); -+ world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true)); // Paper - diff on change ++ world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true)); // Paper - Protect Bedrock and End Portal/Frames from being destroyed; diff on change world.blockUpdated(pos, iblockdata2.getBlock()); iblockdata2.updateNeighbourShapes(world, pos, 2); if (this.isSticky) { @@ -94,19 +94,19 @@ index b3732a6246a2b011e36c5c35fa2ac7749e75db16..bb6c38bb7a054b94a63690f6fd6036d6 } } else { - world.removeBlock(pos.relative(enumdirection), false); -+ // Paper start - fix headless pistons breaking blocks ++ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed; fix headless pistons breaking blocks + BlockPos headPos = pos.relative(enumdirection); + if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || world.getBlockState(headPos) == Blocks.PISTON_HEAD.defaultBlockState().setValue(FACING, enumdirection)) { // double check to make sure we're not a headless piston. + world.removeBlock(headPos, false); + } else { -+ ((ServerLevel)world).getChunkSource().blockChanged(headPos); // ... fix client desync ++ ((ServerLevel) world).getChunkSource().blockChanged(headPos); // ... fix client desync + } -+ // Paper end - fix headless pistons breaking blocks ++ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed } world.playSound((Player) null, pos, SoundEvents.PISTON_CONTRACT, SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.15F + 0.6F); diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index 2c7d025b2af3a66772c3f394620483045fb80242..79ff216e473ebc4bf7ab3ade42b0fa224f7e4c19 100644 +index 2c7d025b2af3a66772c3f394620483045fb80242..0475c153ac1ba73a56bae35820d1d2a31e771865 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java @@ -182,7 +182,7 @@ public abstract class BlockBehaviour implements FeatureElement { @@ -114,7 +114,7 @@ index 2c7d025b2af3a66772c3f394620483045fb80242..79ff216e473ebc4bf7ab3ade42b0fa22 @Deprecated public void onExplosionHit(BlockState state, Level world, BlockPos pos, Explosion explosion, BiConsumer stackMerger) { - if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK) { -+ if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK && state.isDestroyable()) { // Paper ++ if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK && state.isDestroyable()) { // Paper - Protect Bedrock and End Portal/Frames from being destroyed Block block = state.getBlock(); boolean flag = explosion.getIndirectSourceEntity() instanceof Player; @@ -123,7 +123,7 @@ index 2c7d025b2af3a66772c3f394620483045fb80242..79ff216e473ebc4bf7ab3ade42b0fa22 @Deprecated public boolean canBeReplaced(BlockState state, BlockPlaceContext context) { - return state.canBeReplaced() && (context.getItemInHand().isEmpty() || !context.getItemInHand().is(this.asItem())); -+ return state.canBeReplaced() && (context.getItemInHand().isEmpty() || !context.getItemInHand().is(this.asItem())) && (state.isDestroyable() || (context.getPlayer() != null && context.getPlayer().getAbilities().instabuild)); // Paper; ++ return state.canBeReplaced() && (context.getItemInHand().isEmpty() || !context.getItemInHand().is(this.asItem())) && (state.isDestroyable() || (context.getPlayer() != null && context.getPlayer().getAbilities().instabuild)); // Paper - Protect Bedrock and End Portal/Frames from being destroyed } /** @deprecated */ @@ -131,11 +131,11 @@ index 2c7d025b2af3a66772c3f394620483045fb80242..79ff216e473ebc4bf7ab3ade42b0fa22 return this.legacySolid; } -+ // Paper start ++ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed + public final boolean isDestroyable() { + return getBlock().isDestroyable(); + } -+ // Paper end ++ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed + public boolean isValidSpawn(BlockGetter world, BlockPos pos, EntityType type) { return this.getBlock().properties.isValidSpawn.test(this.asState(), world, pos, type); @@ -145,25 +145,25 @@ index 2c7d025b2af3a66772c3f394620483045fb80242..79ff216e473ebc4bf7ab3ade42b0fa22 public PushReaction getPistonPushReaction() { - return this.pushReaction; -+ return !this.isDestroyable() ? PushReaction.BLOCK : this.pushReaction; // Paper ++ return !this.isDestroyable() ? PushReaction.BLOCK : this.pushReaction; // Paper - Protect Bedrock and End Portal/Frames from being destroyed } public boolean isSolidRender(BlockGetter world, BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java -index ed5210c63d964be7c28f59df315766794ec3ea1f..08325c055b04355089d75031522c7b74d83c6cca 100644 +index ed5210c63d964be7c28f59df315766794ec3ea1f..f610ece91a04bd321fdd75814a7b40e622c2bd1e 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java @@ -221,6 +221,13 @@ public class PortalForcer { for (int j = -1; j < 3; ++j) { for (int k = -1; k < 4; ++k) { temp.setWithOffset(pos, portalDirection.getStepX() * j + enumdirection1.getStepX() * distanceOrthogonalToPortal, k, portalDirection.getStepZ() * j + enumdirection1.getStepZ() * distanceOrthogonalToPortal); -+ // Paper start - prevent destroying unbreakable blocks ++ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed + if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits) { + if (!this.level.getBlockState(temp).isDestroyable()) { + return false; + } + } -+ // Paper end - prevent destroying unbreakable blocks ++ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed if (k < 0 && !this.level.getBlockState(temp).isSolid()) { return false; } diff --git a/patches/server/0393-Ensure-safe-gateway-teleport.patch b/patches/server/0393-Ensure-safe-gateway-teleport.patch index 6ca5181f90..f0c0928d23 100644 --- a/patches/server/0393-Ensure-safe-gateway-teleport.patch +++ b/patches/server/0393-Ensure-safe-gateway-teleport.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Ensure safe gateway teleport diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -index 223550eccdf0a5596b8595a30f02ad891ffd91ea..b7a0d8ffd1823a1d1edee6baaa62c15f69e6af3d 100644 +index 223550eccdf0a5596b8595a30f02ad891ffd91ea..d0e8842a2c4f7dbd0d6ac3694b2a6a5395d8a542 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java @@ -105,7 +105,14 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { @@ -13,14 +13,14 @@ index 223550eccdf0a5596b8595a30f02ad891ffd91ea..b7a0d8ffd1823a1d1edee6baaa62c15f if (!list.isEmpty()) { - TheEndGatewayBlockEntity.teleportEntity(world, pos, state, (Entity) list.get(world.random.nextInt(list.size())), blockEntity); -+ // Paper start ++ // Paper start - Ensure safe gateway teleport + for (Entity entity : list) { + if (entity.canChangeDimensions()) { + TheEndGatewayBlockEntity.teleportEntity(world, pos, state, entity, blockEntity); + break; + } + } -+ // Paper end ++ // Paper end - Ensure safe gateway teleport } if (blockEntity.age % 2400L == 0L) { diff --git a/patches/server/0395-Fix-villager-trading-demand-MC-163962.patch b/patches/server/0395-Fix-villager-trading-demand-MC-163962.patch index 79eb053dba..5396bba5ab 100644 --- a/patches/server/0395-Fix-villager-trading-demand-MC-163962.patch +++ b/patches/server/0395-Fix-villager-trading-demand-MC-163962.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix villager trading demand - MC-163962 Prevent demand from going negative and tending to negative infinity diff --git a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java -index a580011cd3b2b7129f2d09f37a3c26cdaafeefe8..1d755d04515f20dbd69931084b4cc894e52d35c9 100644 +index a580011cd3b2b7129f2d09f37a3c26cdaafeefe8..7da5c4a45f8fd46fedd4386e0faac57445475e3a 100644 --- a/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java +++ b/src/main/java/net/minecraft/world/item/trading/MerchantOffer.java @@ -130,7 +130,7 @@ public class MerchantOffer { @@ -14,7 +14,7 @@ index a580011cd3b2b7129f2d09f37a3c26cdaafeefe8..1d755d04515f20dbd69931084b4cc894 public void updateDemand() { - this.demand = this.demand + this.uses - (this.maxUses - this.uses); -+ this.demand = Math.max(0, this.demand + this.uses - (this.maxUses - this.uses)); // Paper ++ this.demand = Math.max(0, this.demand + this.uses - (this.maxUses - this.uses)); // Paper - Fix MC-163962 } public ItemStack assemble() { diff --git a/patches/server/0397-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch b/patches/server/0397-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch index 2fe0708669..ff8699f85d 100644 --- a/patches/server/0397-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch +++ b/patches/server/0397-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Use seed based lookup for Treasure Maps - Fixes lag from diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java -index e46ceae916f6396d96226db6d8e90bd29088f765..d4b4da03dcd98336a15eaa045d6b0ce361b15b76 100644 +index e46ceae916f6396d96226db6d8e90bd29088f765..f643d3c06bd8fc37f6c571a19d5691694b0ce8d3 100644 --- a/src/main/java/net/minecraft/world/item/MapItem.java +++ b/src/main/java/net/minecraft/world/item/MapItem.java @@ -242,14 +242,13 @@ public class MapItem extends ComplexItem { @@ -21,7 +21,7 @@ index e46ceae916f6396d96226db6d8e90bd29088f765..d4b4da03dcd98336a15eaa045d6b0ce3 for (j1 = 0; j1 < 128; ++j1) { for (k1 = 0; k1 < 128; ++k1) { - Holder holder = world.getBiome(blockposition_mutableblockposition.set((l + k1) * i, 0, (i1 + j1) * i)); -+ Holder holder = world.getUncachedNoiseBiome((l + k1) * i, 0, (i1 + j1) * i); // Paper ++ Holder holder = world.getUncachedNoiseBiome((l + k1) * i, 0, (i1 + j1) * i); // Paper - Perf: Use seed based lookup for treasure maps aboolean[j1 * 128 + k1] = holder.is(BiomeTags.WATER_ON_MAP_OUTLINES); } diff --git a/patches/server/0399-Fix-piston-physics-inconsistency-MC-188840.patch b/patches/server/0399-Fix-piston-physics-inconsistency-MC-188840.patch index 3bef753cf5..564e1578ce 100644 --- a/patches/server/0399-Fix-piston-physics-inconsistency-MC-188840.patch +++ b/patches/server/0399-Fix-piston-physics-inconsistency-MC-188840.patch @@ -32,7 +32,7 @@ This patch fixes https://bugs.mojang.com/browse/MC-188840 This patch also fixes rail duping and carpet duping. diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index bb6c38bb7a054b94a63690f6fd6036d6f376dae4..565da027ca7c395f9b965505cbe9e85e62367834 100644 +index e4a3c937950b26e81b89d6ddcf3d6c2794ed934d..c34b34a6be594c502d1cb59703ace8ad8dd96915 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java @@ -426,14 +426,26 @@ public class PistonBaseBlock extends DirectionalBlock { @@ -66,7 +66,7 @@ index bb6c38bb7a054b94a63690f6fd6036d6f376dae4..565da027ca7c395f9b965505cbe9e85e } diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -index 17a6327ab7b26dfab38881bbc0689b0b25f8f025..1ef87580574919796dbba707f44a413ee5c5781b 100644 +index 17a6327ab7b26dfab38881bbc0689b0b25f8f025..c71690dbc3dc52803945f1608f0ee3ba94146354 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java @@ -288,7 +288,7 @@ public class PistonMovingBlockEntity extends BlockEntity { @@ -74,7 +74,7 @@ index 17a6327ab7b26dfab38881bbc0689b0b25f8f025..1ef87580574919796dbba707f44a413e BlockState blockState = Block.updateFromNeighbourShapes(blockEntity.movedState, world, pos); if (blockState.isAir()) { - world.setBlock(pos, blockEntity.movedState, 84); -+ world.setBlock(pos, blockEntity.movedState, io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPistonDuplication ? 84 : (84 | Block.UPDATE_CLIENTS)); // Paper - force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air ++ world.setBlock(pos, blockEntity.movedState, io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPistonDuplication ? 84 : (84 | Block.UPDATE_CLIENTS)); // Paper - fix a variety of piston desync dupes; force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air Block.updateOrDestroy(blockEntity.movedState, blockState, world, pos, 3); } else { if (blockState.hasProperty(BlockStateProperties.WATERLOGGED) && blockState.getValue(BlockStateProperties.WATERLOGGED)) { diff --git a/patches/server/0485-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/server/0485-Climbing-should-not-bypass-cramming-gamerule.patch index 6ab51cf1c7..a987291004 100644 --- a/patches/server/0485-Climbing-should-not-bypass-cramming-gamerule.patch +++ b/patches/server/0485-Climbing-should-not-bypass-cramming-gamerule.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Climbing should not bypass cramming gamerule diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index cdfc00e4bee78fc7ac7dc9f52301f16cd7846698..180f87a67c84fc0cf3f54755da9801365d4158f8 100644 +index af49c7e0531ef73646d74c9770fea302a8b8fea3..1471bfcb0a7b193866cfa7ee0e14e7b044755e88 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2064,6 +2064,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S @@ -22,7 +22,7 @@ index cdfc00e4bee78fc7ac7dc9f52301f16cd7846698..180f87a67c84fc0cf3f54755da980136 } diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index 68e4440765636295a74ea942862d772d47282ad6..7bd719db017425627c982728abec7b7f99edbc66 100644 +index c9c7833755af3c7bef1d40f2ca425cbec59efa68..75cdddbfbbc4c0c521194dde27ba5f5d17221842 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java @@ -46,11 +46,16 @@ public final class EntitySelector { @@ -44,7 +44,7 @@ index 68e4440765636295a74ea942862d772d47282ad6..7bd719db017425627c982728abec7b7f } else if (entity.level().isClientSide && (!(entity1 instanceof Player) || !((Player) entity1).isLocalPlayer())) { return false; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 05fe4828af59e3cd894c9979ecb08ad0e1c6b2d3..720b889796cd023308cf6f8e8a75b2548ca0e45f 100644 +index a3fd295ce44bce34c7f0a364abc27b70e546a383..428a5e8c4a4fb9e00402dd6164cebeec008e192e 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -3426,7 +3426,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -55,7 +55,7 @@ index 05fe4828af59e3cd894c9979ecb08ad0e1c6b2d3..720b889796cd023308cf6f8e8a75b254 + List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushable(this, this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule)); // Paper - Climbing should not bypass cramming gamerule if (!list.isEmpty()) { - // Paper - moved up + // Paper - don't run getEntities if we're not going to use its result; moved up @@ -3616,9 +3616,16 @@ public abstract class LivingEntity extends Entity implements Attackable { return !this.isRemoved() && this.collides; // CraftBukkit } diff --git a/patches/server/0617-Fix-kick-event-leave-message-not-being-sent.patch b/patches/server/0617-Fix-kick-event-leave-message-not-being-sent.patch index 939dfabba0..1e7706bbb1 100644 --- a/patches/server/0617-Fix-kick-event-leave-message-not-being-sent.patch +++ b/patches/server/0617-Fix-kick-event-leave-message-not-being-sent.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Fix kick event leave message not being sent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index eabab52143ff490c4ec646628a9dc96cf15efb72..d848119476e5ba254ce86873f1d997d0fe3da876 100644 +index 61d439af863603c669c45f38045dbad9068f285a..ade79a794a7485e0141a430d62236daf1e566b21 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -273,7 +273,6 @@ public class ServerPlayer extends Player { public boolean joining = true; public boolean sentListPacket = false; - public boolean supressTrackerForLogin = false; // Paper + public boolean supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready - public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent // CraftBukkit end public boolean isRealPlayer; // Paper public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 761dd36bcf0318e28613d852f95566879d835912..5d0500ee2740977c6b6eb89ed51e29b5a2e66760 100644 +index 3049377685ee4fe75f0c4b68eab39a916ac20785..f5f2d65d2e02b0d79352585d9d4ef588ab59dce7 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java @@ -77,6 +77,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @@ -50,7 +50,7 @@ index 761dd36bcf0318e28613d852f95566879d835912..5d0500ee2740977c6b6eb89ed51e29b5 MinecraftServer minecraftserver = this.server; Connection networkmanager = this.connection; diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index c477c6c47d6b707fcee671152bfb516eeea2cebd..8fb479bcf55f71857404d9b34eef6cd26cf0babf 100644 +index 5dfebe60caa47af3bab4a667ca5d0b6438367161..fe8ba3890d5b21273aca68777de56d7f7f644c0d 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1882,6 +1882,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -96,7 +96,7 @@ index c477c6c47d6b707fcee671152bfb516eeea2cebd..8fb479bcf55f71857404d9b34eef6cd2 this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(quitMessage), false); // Paper end diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 3e88b648cf4fcc19598fb50ca5651af1a52a0a84..60e60166485bc87a5ff9919f9c1603dc4eaeecc9 100644 +index 0f04b29ff000c0b0f0692eecf26675f5520d9e07..3f8f7d7db41b73d0d449b653d3ba55a097c00566 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -570,6 +570,11 @@ public abstract class PlayerList { diff --git a/patches/server/0657-Improve-and-expand-AsyncCatcher.patch b/patches/server/0657-Improve-and-expand-AsyncCatcher.patch index 3d5d345fb4..7c1452f4d8 100644 --- a/patches/server/0657-Improve-and-expand-AsyncCatcher.patch +++ b/patches/server/0657-Improve-and-expand-AsyncCatcher.patch @@ -17,7 +17,7 @@ Async catch modifications to critical entity state Co-authored-by: Jake Potrebic diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 09ce054d260bd7143eb9d58611144de2666166f3..5bc6b7298c253bd2ee1d5a16b8f237c824f8719a 100644 +index f111ab02d91e936284fc183969117c172127a000..db12ed933d09090f45ff2aa1045d2990901b27a2 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1570,6 +1570,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -25,11 +25,11 @@ index 09ce054d260bd7143eb9d58611144de2666166f3..5bc6b7298c253bd2ee1d5a16b8f237c8 public void internalTeleport(double d0, double d1, double d2, float f, float f1, Set set) { // Paper + org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper - // Paper start + // Paper start - Prevent teleporting dead entities if (player.isRemoved()) { LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName()); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 0292ca014fd8319fe9f5e7a1465ee5c112ef6515..4516b12d1856653c0a28f8edfc28d4644316f763 100644 +index 48d5f1522e1bfda886e1791055bbddab510d464b..93c9fae42a1115f4442e8633946dc0ebde4606bb 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -1118,7 +1118,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -166,7 +166,7 @@ index bbbf6dd8e566ecdca8794e3b03765fe7e426a2bd..66ab901956ca394c251c420338643d39 PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason}); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 40ca827fed0e69c50ad8857ec29cfa99570b1d07..e3faafc565c180467c235aa1695e80b746c03cf1 100644 +index 9fd6e12aedc670fcb3523e8093e922bf385723d7..189c0ab39f56e7a6d92aa6ee24f29a232b446cdf 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1803,6 +1803,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0718-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch b/patches/server/0718-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch index 5eefef38a3..1a1afc823f 100644 --- a/patches/server/0718-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch +++ b/patches/server/0718-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch @@ -27,7 +27,7 @@ Co-authored-by: Zach Brown Co-authored-by: Madeline Miller diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java -index de9102f943fe90122b2fe7f94228b4248244374a..1818ab63209017b45a46a80802d500f2d042a208 100644 +index 4342bc4535ea812fef3fab56917e5de15947c42d..be74adc86f0ca467f3b59e7b57fd47a8f381d86e 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java @@ -159,15 +159,15 @@ public class PistonBaseBlock extends DirectionalBlock { @@ -67,7 +67,7 @@ index de9102f943fe90122b2fe7f94228b4248244374a..1818ab63209017b45a46a80802d500f2 + } + // Paper end - Fix sticky pistons and BlockPistonRetractEvent world.setBlock(pos, iblockdata2, 20); - world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true)); // Paper - diff on change + world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true)); // Paper - Protect Bedrock and End Portal/Frames from being destroyed; diff on change world.blockUpdated(pos, iblockdata2.getBlock()); @@ -276,6 +283,13 @@ public class PistonBaseBlock extends DirectionalBlock { if (type == 1 && !iblockdata3.isAir() && PistonBaseBlock.isPushable(iblockdata3, world, blockposition1, enumdirection.getOpposite(), false, enumdirection) && (iblockdata3.getPistonPushReaction() == PushReaction.NORMAL || iblockdata3.is(Blocks.PISTON) || iblockdata3.is(Blocks.STICKY_PISTON))) { diff --git a/patches/server/0751-Force-close-world-loading-screen.patch b/patches/server/0751-Force-close-world-loading-screen.patch index bc5f26e530..7988006f3a 100644 --- a/patches/server/0751-Force-close-world-loading-screen.patch +++ b/patches/server/0751-Force-close-world-loading-screen.patch @@ -10,12 +10,12 @@ so we do not need that. The client only needs the chunk it is currently in to be loaded to close the loading screen, so we just send an empty one. diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 8364d86a75174d1b37cfbf6cf9dbc5ed952c432e..f173b0f4cd2cffc90a0f609cbc8bf29fdc1cf122 100644 +index d0be35600770a25b208ef72816798928847ff9ce..b9d1ee41775719050c14f172cf8fb308804d8097 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -398,6 +398,16 @@ public abstract class PlayerList { - // Paper start - move vehicle into method so it can be called above - short circuit around that code + // Paper start - Fire PlayerJoinEvent when Player is actually ready; move vehicle into method so it can be called above - short circuit around that code onPlayerJoinFinish(player, worldserver1, s1); + // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead + if (player.isDeadOrDying()) { @@ -29,4 +29,4 @@ index 8364d86a75174d1b37cfbf6cf9dbc5ed952c432e..f173b0f4cd2cffc90a0f609cbc8bf29f + // Paper end - Send empty chunk } private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, CompoundTag nbttagcompound) { - // Paper end + // Paper end - Fire PlayerJoinEvent when Player is actually ready diff --git a/patches/server/0860-Ability-to-control-player-s-insomnia-and-phantoms.patch b/patches/server/0860-Ability-to-control-player-s-insomnia-and-phantoms.patch index 620ab413a9..3e5f525d0d 100644 --- a/patches/server/0860-Ability-to-control-player-s-insomnia-and-phantoms.patch +++ b/patches/server/0860-Ability-to-control-player-s-insomnia-and-phantoms.patch @@ -5,14 +5,14 @@ Subject: [PATCH] Ability to control player's insomnia and phantoms diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index 93a41156a01a1638f3ef469b1518a07e7961f378..dbbce471c35849ea7d7ad07e9db9b7d8d85690df 100644 +index 75cdddbfbbc4c0c521194dde27ba5f5d17221842..b350d41a724048af06f9aa9bbef039d3d719c3a8 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java @@ -28,7 +28,18 @@ public final class EntitySelector { return !entity.isSpectator(); }; public static final Predicate CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith); -- public static Predicate IS_INSOMNIAC = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper +- public static Predicate IS_INSOMNIAC = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper - Add phantom creative and insomniac controls + // Paper start - Ability to control player's insomnia and phantoms + public static Predicate IS_INSOMNIAC = (player) -> { + net.minecraft.server.level.ServerPlayer serverPlayer = (net.minecraft.server.level.ServerPlayer) player; @@ -29,7 +29,7 @@ index 93a41156a01a1638f3ef469b1518a07e7961f378..dbbce471c35849ea7d7ad07e9db9b7d8 private EntitySelector() {} // Paper start diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index b1fc786970b5288a02cc3a46e3fe7784ac566c07..7d7d37334321c844958ce09e77547dd61dcba6c8 100644 +index 8c9caa324402568ce9f55e733f4d14430159347a..eab7b0c18389a6980c621c2a0a0879dca9b53121 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -33,13 +33,22 @@ public class PhantomSpawner implements CustomSpawner { diff --git a/patches/server/0865-Properly-resend-entities.patch b/patches/server/0865-Properly-resend-entities.patch index cfc0a45b15..7ca3f62502 100644 --- a/patches/server/0865-Properly-resend-entities.patch +++ b/patches/server/0865-Properly-resend-entities.patch @@ -85,7 +85,7 @@ index d088479d160dbd2fc90b48a30553be141db8eef2..ccb7d92b6c36b6225a2e640f8cea6c0d public static class DataItem { diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1db6455f72ce9b91b04d0b5ba76d0a1d29b98110..3d7dd28e73c3d4419766ad37b9c494b3ce2e2d21 100644 +index e14c4e09fbfcd19bd53fcc1560aae317587cee0f..903d04140739f6c1df58bdfcc6a3aa690b289d66 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2653,7 +2653,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -98,11 +98,11 @@ index 1db6455f72ce9b91b04d0b5ba76d0a1d29b98110..3d7dd28e73c3d4419766ad37b9c494b3 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 12a3aa585ca60b47107da85d88b3a7d502a0ae9f..66296aa930a1afe3c3d89afe69d5619e5ed146bc 100644 +index b8213713b54e0bfaa0ddca41ec76f6840c0e1d20..7968ebbd3c56ff1b33491ffcfdab254f799ddeef 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -376,7 +376,7 @@ public abstract class PlayerList { - ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - track entity now + ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now // CraftBukkit end - player.getEntityData().refresh(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn diff --git a/patches/server/0881-Use-single-player-info-update-packet-on-join.patch b/patches/server/0881-Use-single-player-info-update-packet-on-join.patch index ff4b5e759b..2ab5c52eb0 100644 --- a/patches/server/0881-Use-single-player-info-update-packet-on-join.patch +++ b/patches/server/0881-Use-single-player-info-update-packet-on-join.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Use single player info update packet on join diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0a70260f8d01ebbf6d35f852461a1d7710bb4b1b..8bcd8a7fa65e05ccef0a205319cad9e84b4341b5 100644 +index b9d4e5e49088065a60087ee2587e7e25ca72f5db..ad086107f9be8da3816ab1d80576be0718dc0054 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -3420,7 +3420,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -18,7 +18,7 @@ index 0a70260f8d01ebbf6d35f852461a1d7710bb4b1b..8bcd8a7fa65e05ccef0a205319cad9e8 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 66296aa930a1afe3c3d89afe69d5619e5ed146bc..79e2fbad2c03d6187671a073553a573022aeb060 100644 +index 7968ebbd3c56ff1b33491ffcfdab254f799ddeef..09397946cb9fa82e20772ea981bdadbc6a5c93c7 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -358,6 +358,7 @@ public abstract class PlayerList { @@ -47,5 +47,5 @@ index 66296aa930a1afe3c3d89afe69d5619e5ed146bc..79e2fbad2c03d6187671a073553a5730 + } + // Paper end - Use single player info update packet on join player.sentListPacket = true; - player.supressTrackerForLogin = false; // Paper - ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - track entity now + player.supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready + ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now diff --git a/patches/server/0942-ExperienceOrb-should-call-EntitySpawnEvent.patch b/patches/server/0942-ExperienceOrb-should-call-EntitySpawnEvent.patch index afca54d6a6..7a1b5662c3 100644 --- a/patches/server/0942-ExperienceOrb-should-call-EntitySpawnEvent.patch +++ b/patches/server/0942-ExperienceOrb-should-call-EntitySpawnEvent.patch @@ -5,18 +5,16 @@ Subject: [PATCH] ExperienceOrb should call EntitySpawnEvent diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 3f8195475fbad4d517d5417ece9555831377d1cc..cf4e32d5199b15bd8d72e412982dfbecde183f91 100644 +index 4697d69180d7ef9eafe742948067001478cc934b..f8999d0b4cb068618cf196a9da9b8be793d30491 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -734,7 +734,10 @@ public class CraftEventFactory { +@@ -734,7 +734,8 @@ public class CraftEventFactory { // Spigot start - SPIGOT-7523: Merge after spawn event and only merge if the event was not cancelled (gets checked above) if (entity instanceof net.minecraft.world.entity.ExperienceOrb xp) { double radius = world.spigotConfig.expMerge; - if (radius > 0) { -+ // Paper start - Call EntitySpawnEvent for ExperienceOrb entities -+ event = CraftEventFactory.callEntitySpawnEvent(entity); ++ event = CraftEventFactory.callEntitySpawnEvent(entity); // Call spawn event for ExperienceOrb entities + if (radius > 0 && !event.isCancelled() && !entity.isRemoved()) { -+ // Paper end - Call EntitySpawnEvent for ExperienceOrb entities - // Paper start - Maximum exp value when merging - Whole section has been tweaked, see comments for specifics + // Paper start - Maximum exp value when merging; Whole section has been tweaked, see comments for specifics final int maxValue = world.paperConfig().entities.behavior.experienceMergeMaxValue; final boolean mergeUnconditionally = world.paperConfig().entities.behavior.experienceMergeMaxValue <= 0; diff --git a/patches/server/0973-Add-PlayerPickItemEvent.patch b/patches/server/0973-Add-PlayerPickItemEvent.patch index d1e7e6fc93..33b9f608e2 100644 --- a/patches/server/0973-Add-PlayerPickItemEvent.patch +++ b/patches/server/0973-Add-PlayerPickItemEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add PlayerPickItemEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 57e7a1d60ae3644fa33ed619e8fdb4441fc3f8ce..96d44798583ee876ca8121c381638cd741d8338c 100644 +index eab3edcd040269ecd920c15ec96b25499aef83e1..4563032ea2acca60014b90c696c0e7d59cdd8132 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -941,8 +941,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -13,7 +13,7 @@ index 57e7a1d60ae3644fa33ed619e8fdb4441fc3f8ce..96d44798583ee876ca8121c381638cd7 return; } - this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed - // Paper end + // Paper end - validate pick item position + // Paper start - Add PlayerPickItemEvent + Player bukkitPlayer = this.player.getBukkitEntity(); + int targetSlot = this.player.getInventory().getSuitableHotbarSlot(); diff --git a/patches/server/0980-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/server/0980-Add-titleOverride-to-InventoryOpenEvent.patch index 3a604472c7..79db0dc05d 100644 --- a/patches/server/0980-Add-titleOverride-to-InventoryOpenEvent.patch +++ b/patches/server/0980-Add-titleOverride-to-InventoryOpenEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add titleOverride to InventoryOpenEvent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index e32a2ea53f61410f0470bdccf1e479af1a571469..23ede7bc9fcf923a70715a6f60449779ae52c62a 100644 +index 33ba61a71d3989ca53366d7c40a6d625fee524e8..6f06262d358a7f63a2ea35c0fd70b0c5aaa96182 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -1573,12 +1573,17 @@ public class ServerPlayer extends Player { @@ -31,13 +31,13 @@ index e32a2ea53f61410f0470bdccf1e479af1a571469..23ede7bc9fcf923a70715a6f60449779 } else { // CraftBukkit start this.containerMenu = container; -- if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper +- if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper - Prevent opening inventories when frozen + if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), Objects.requireNonNullElseGet(title, container::getTitle))); // Paper - Add titleOverride to InventoryOpenEvent // CraftBukkit end this.initMenu(container); return OptionalInt.of(this.containerCounter); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 897e693492bdf9293154535d5772929bc2b1a523..827fe201a7b74f485abb46b127a28bf0cb479c3b 100644 +index da586f935efa62f7ddd2ea27a8ec364a6b46bc86..5d4d45703212da37417aa98fa61ee479dac03ae5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -357,12 +357,16 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @@ -57,7 +57,7 @@ index 897e693492bdf9293154535d5772929bc2b1a523..827fe201a7b74f485abb46b127a28bf0 + if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper - Add titleOverride to InventoryOpenEvent //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment - if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper + if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen @@ -438,7 +442,10 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { } @@ -74,15 +74,15 @@ index 897e693492bdf9293154535d5772929bc2b1a523..827fe201a7b74f485abb46b127a28bf0 //String title = inventory.getTitle(); // Paper - comment net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(inventory.getTitle()); // Paper -+ if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper - Add titleOverride to InventoryOpenEvent ++ if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper - Add titleOverride to InventoryOpenEvent //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment - if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper + if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen player.containerMenu = container; diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 92584ad04d35c021e1f16ca2338eafe9b07e8ff7..6e3d13d6c60491b7147f8bb3d60354b01d047cc7 100644 +index a57341356e3813423bb551902544ea9edb5950d7..9f279f469304ad83035035100eeb2559b4e8ea2e 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1440,10 +1440,21 @@ public class CraftEventFactory { +@@ -1438,10 +1438,21 @@ public class CraftEventFactory { } public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container) { @@ -105,7 +105,7 @@ index 92584ad04d35c021e1f16ca2338eafe9b07e8ff7..6e3d13d6c60491b7147f8bb3d60354b0 if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper } -@@ -1458,10 +1469,10 @@ public class CraftEventFactory { +@@ -1456,10 +1467,10 @@ public class CraftEventFactory { if (event.isCancelled()) { container.transferTo(player.containerMenu, craftPlayer); diff --git a/patches/server/0991-Actually-optimise-explosions.patch b/patches/server/0991-Actually-optimise-explosions.patch index a91b2d5ee8..f6cc1519c0 100644 --- a/patches/server/0991-Actually-optimise-explosions.patch +++ b/patches/server/0991-Actually-optimise-explosions.patch @@ -34,7 +34,7 @@ The results indicate that this logic is 5 times faster than Vanilla and 2.3 times faster than Lithium. diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index d8a57d38d263e1d402327c7df21641b0f1ba0668..1fa02130dcb65b3109fde0cb612b538b1c4cd4cb 100644 +index 10f17478a148060ad2724bb5c79868cea3047ded..1fa02130dcb65b3109fde0cb612b538b1c4cd4cb 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java @@ -111,6 +111,271 @@ public class Explosion { @@ -370,7 +370,7 @@ index d8a57d38d263e1d402327c7df21641b0f1ba0668..1fa02130dcb65b3109fde0cb612b538b for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) { - BlockPos blockposition = BlockPos.containing(d4, d5, d6); - BlockState iblockdata = this.level.getBlockState(blockposition); -- if (!iblockdata.isDestroyable()) continue; // Paper +- if (!iblockdata.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed - FluidState fluid = iblockdata.getFluidState(); // Paper + // Paper start - optimise explosions + final int blockX = Mth.floor(d4); @@ -403,11 +403,10 @@ index d8a57d38d263e1d402327c7df21641b0f1ba0668..1fa02130dcb65b3109fde0cb612b538b - if (optional.isPresent()) { - f -= ((Float) optional.get() + 0.3F) * 0.3F; - } -- -- if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) { + if (!iblockdata.isDestroyable()) continue; // Paper + // Paper - optimise explosions -+ + +- if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) { + f -= cachedBlock.resistance; // Paper - optimise explosions + + if (f > 0.0F && cachedBlock.shouldExplode == null) { // Paper - optimise explosions diff --git a/patches/server/0995-Optimise-chunk-tick-iteration.patch b/patches/server/0995-Optimise-chunk-tick-iteration.patch index 617d6849fd..f92bae64b8 100644 --- a/patches/server/0995-Optimise-chunk-tick-iteration.patch +++ b/patches/server/0995-Optimise-chunk-tick-iteration.patch @@ -108,7 +108,7 @@ index 2b998bdbe49bf8211b755e0eb7c1bf13ac280eab..627a88ec8c3b215b19b55a6d461c8754 List list; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 6e51837a99bb69240f82a061f2c808f78a8346a6..c6e764f140d3fe6342c6f224fe0d9643a3185cba 100644 +index 8984a159dbdaab16a1a69e98a504f6d9621bf69a..6a106d4b9db8265d1a62e7ae13b0f05596fa3587 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -191,6 +191,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -140,7 +140,7 @@ index 6e51837a99bb69240f82a061f2c808f78a8346a6..c6e764f140d3fe6342c6f224fe0d9643 double d1 = (double) SectionPos.sectionToBlockCoord(pos.z, 8); double d2 = d0 - entity.getX(); diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index 33b0be8eb9bff8068ca7bdeffe34b7f2eaa6dbfb..328aba4a638f6147eb0c521cc464163ad7bd5840 100644 +index c80a625f7289e3bb33c6851d2072957e153ca1fb..7c425ac50c83757b66a2178bc19d4c920b82f12f 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -50,7 +50,7 @@ public abstract class DistanceManager { @@ -162,7 +162,7 @@ index 33b0be8eb9bff8068ca7bdeffe34b7f2eaa6dbfb..328aba4a638f6147eb0c521cc464163a //this.tickingTicketsTracker.addTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair); // Paper - no longer used } @@ -149,7 +149,7 @@ public abstract class DistanceManager { - if (objectset != null) objectset.remove(player); // Paper - some state corruption happens here, don't crash, clean up gracefully. + if (objectset != null) objectset.remove(player); // Paper - some state corruption happens here, don't crash, clean up gracefully if (objectset == null || objectset.isEmpty()) { // Paper this.playersPerChunk.remove(i); - this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false); @@ -187,7 +187,7 @@ index 33b0be8eb9bff8068ca7bdeffe34b7f2eaa6dbfb..328aba4a638f6147eb0c521cc464163a public String getDebugStatus() { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 5152979bf81345fc365e7b16028c7d970d2f5856..44ada45d9bf2d9b48e5de1c3cb1a855902f3884b 100644 +index 5d8a3d4bd7be3092a1e2959d122f5bc1c87f0ae1..a9ec46a5a751b8b06046c58525f7f6d0894adc8f 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -516,18 +516,10 @@ public class ServerChunkCache extends ChunkSource { @@ -365,7 +365,7 @@ index 5152979bf81345fc365e7b16028c7d970d2f5856..44ada45d9bf2d9b48e5de1c3cb1a8559 gameprofilerfiller.pop(); } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 23ede7bc9fcf923a70715a6f60449779ae52c62a..86038d8e2998b1100706171c814b0ef34a20ee14 100644 +index 6f06262d358a7f63a2ea35c0fd70b0c5aaa96182..ad6fd14f7f19c20967906a8e01a4f76ee80aaf84 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -325,6 +325,9 @@ public class ServerPlayer extends Player { diff --git a/patches/server/1024-Restore-vanilla-entity-drops-behavior.patch b/patches/server/1024-Restore-vanilla-entity-drops-behavior.patch index 6e51929640..42a6b5c0cb 100644 --- a/patches/server/1024-Restore-vanilla-entity-drops-behavior.patch +++ b/patches/server/1024-Restore-vanilla-entity-drops-behavior.patch @@ -9,7 +9,7 @@ on dropping the item instead of generalizing it for all dropped items like CB does. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 86038d8e2998b1100706171c814b0ef34a20ee14..6872e223ff4b450af89a838f4caf7cf2ebcb818e 100644 +index ad6fd14f7f19c20967906a8e01a4f76ee80aaf84..ce2e29de3628aba893a96688c9bbc58d1fc984bc 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -944,22 +944,20 @@ public class ServerPlayer extends Player { @@ -50,7 +50,7 @@ index 86038d8e2998b1100706171c814b0ef34a20ee14..6872e223ff4b450af89a838f4caf7cf2 if (entityitem == null) { return null; diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index a70633d9585f94e673c58fc69660d984ca169561..8814ffc0f3ebe352cd72f50d9f68704e4ee0e88c 100644 +index 18c73edca59c8bbd4ee57196c4455fb18d7869d9..0de5d58c9ed08292a2d0b478c5ce9f50a67f8a05 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2703,6 +2703,25 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S @@ -104,7 +104,7 @@ index a70633d9585f94e673c58fc69660d984ca169561..8814ffc0f3ebe352cd72f50d9f68704e return this.spawnAtLocation(entityitem); } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 6860e588ad9daaf3d9afa11132967a50eeefe860..7fc84405bc96d768fd373dd6844de4204a39cd6a 100644 +index 14880c5cd67eec5f92e4c7058b41c332bc0f871c..d59a38c62c1b13e6ecb2841fba65017104ed46dc 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -254,7 +254,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -134,7 +134,7 @@ index 45906d273e6d6ec20cf44b4d07efdac68752ee9b..ac9eaeaf7df1e84ee588f371628c0a10 } diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index ab708b256183fc54fe8e13f341d8a38acf611739..a9c1f99ba2461333bd154ac16e812031f234f7a6 100644 +index 1e42372f038757b48990643aa2f118be415e0463..69f29af64c55e68d1906a0d46943751d7de66cf4 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java @@ -610,7 +610,7 @@ public class ArmorStand extends LivingEntity { @@ -165,10 +165,10 @@ index ab708b256183fc54fe8e13f341d8a38acf611739..a9c1f99ba2461333bd154ac16e812031 } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 6e3d13d6c60491b7147f8bb3d60354b01d047cc7..24917c3996d06677e9da72ab53902c9868e00d86 100644 +index 9f279f469304ad83035035100eeb2559b4e8ea2e..311175ea5979d22766d897bd9a5172abcb91f1be 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -939,17 +939,21 @@ public class CraftEventFactory { +@@ -937,17 +937,21 @@ public class CraftEventFactory { } public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim) { @@ -194,7 +194,7 @@ index 6e3d13d6c60491b7147f8bb3d60354b01d047cc7..24917c3996d06677e9da72ab53902c98 populateFields(victim, event); // Paper - make cancellable CraftWorld world = (CraftWorld) entity.getWorld(); Bukkit.getServer().getPluginManager().callEvent(event); -@@ -963,19 +967,23 @@ public class CraftEventFactory { +@@ -961,19 +965,23 @@ public class CraftEventFactory { victim.expToDrop = event.getDroppedExp(); lootCheck.run(); // Paper - advancement triggers before destroying items @@ -222,7 +222,7 @@ index 6e3d13d6c60491b7147f8bb3d60354b01d047cc7..24917c3996d06677e9da72ab53902c98 event.setKeepInventory(keepInventory); event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel populateFields(victim, event); // Paper - make cancellable -@@ -994,10 +1002,14 @@ public class CraftEventFactory { +@@ -992,10 +1000,14 @@ public class CraftEventFactory { victim.expToDrop = event.getDroppedExp(); victim.newExp = event.getNewExp(); diff --git a/patches/server/1035-Add-drops-to-shear-events.patch b/patches/server/1035-Add-drops-to-shear-events.patch index d65d09d7d0..e8dc631fb5 100644 --- a/patches/server/1035-Add-drops-to-shear-events.patch +++ b/patches/server/1035-Add-drops-to-shear-events.patch @@ -233,10 +233,10 @@ index 8adcfc8f6772a32b5915e4a07100e8eb735f907a..b5d6857eaf2bed14adcb5f5e80d91b44 } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 24917c3996d06677e9da72ab53902c9868e00d86..55c26840957f69860816c917c16f59d02074b388 100644 +index 311175ea5979d22766d897bd9a5172abcb91f1be..0620857b4a248657c8fdcb9b12715fa02379a291 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1718,20 +1718,20 @@ public class CraftEventFactory { +@@ -1716,20 +1716,20 @@ public class CraftEventFactory { return event; }