aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/unapplied
diff options
context:
space:
mode:
authorOwen1212055 <[email protected]>2024-10-23 10:04:01 -0400
committerOwen1212055 <[email protected]>2024-10-23 10:04:01 -0400
commitaf125d26a94147ff40555819d5a9687d24b65d50 (patch)
tree12c00f31e82906203d1d1885b6023f7142f02ed4 /patches/unapplied
parentaa37f7250d168e94318e975d3c6d1002e7b82c29 (diff)
downloadPaper-af125d26a94147ff40555819d5a9687d24b65d50.tar.gz
Paper-af125d26a94147ff40555819d5a9687d24b65d50.zip
Patch
Diffstat (limited to 'patches/unapplied')
-rw-r--r--patches/unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch47
-rw-r--r--patches/unapplied/server/0332-Don-t-tick-dead-players.patch21
-rw-r--r--patches/unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch21
-rw-r--r--patches/unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch48
-rw-r--r--patches/unapplied/server/0335-Optimize-Pathfinding.patch47
-rw-r--r--patches/unapplied/server/0336-Reduce-Either-Optional-allocation.patch48
-rw-r--r--patches/unapplied/server/0337-Reduce-memory-footprint-of-CompoundTag.patch50
-rw-r--r--patches/unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch50
-rw-r--r--patches/unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch43
-rw-r--r--patches/unapplied/server/0340-Implement-Player-Client-Options-API.patch194
-rw-r--r--patches/unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch23
-rw-r--r--patches/unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch105
-rw-r--r--patches/unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch119
-rw-r--r--patches/unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch29
-rw-r--r--patches/unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch27
-rw-r--r--patches/unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch43
-rw-r--r--patches/unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch156
-rw-r--r--patches/unapplied/server/0348-Villager-Restocks-API.patch31
-rw-r--r--patches/unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch26
-rw-r--r--patches/unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch30
-rw-r--r--patches/unapplied/server/0351-misc-debugging-dumps.patch118
-rw-r--r--patches/unapplied/server/0352-Prevent-teleporting-dead-entities.patch24
22 files changed, 0 insertions, 1300 deletions
diff --git a/patches/unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/patches/unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
deleted file mode 100644
index e7c3500d18..0000000000
--- a/patches/unapplied/server/0331-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Thu, 2 Apr 2020 01:42:39 -0400
-Subject: [PATCH] Prevent Double PlayerChunkMap adds crashing server
-
-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 ee54706b36bd227edacea2a1b6099009bd652039..8206ec366b429858d9582e437781191e5aa0fa02 100644
---- a/src/main/java/net/minecraft/server/level/ChunkMap.java
-+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1241,6 +1241,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-
- public void addEntity(Entity entity) {
- org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot
-+ // Paper start - ignore and warn about illegal addEntity calls instead of crashing server
-+ if (!entity.valid || entity.level() != this.level || this.entityMap.containsKey(entity.getId())) {
-+ LOGGER.error("Illegal ChunkMap::addEntity for world " + this.level.getWorld().getName()
-+ + ": " + entity + (this.entityMap.containsKey(entity.getId()) ? " ALREADY CONTAINED (This would have crashed your server)" : ""), new Throwable());
-+ return;
-+ }
-+ // 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 b465f05d78e79ffbf70114b18204d85d32761c67..5b89d834a7c01530807e61ea25af2b01f004ce86 100644
---- a/src/main/java/net/minecraft/server/level/ServerLevel.java
-+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -2151,7 +2151,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
-
- public void onTrackingStart(Entity entity) {
- org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot
-- ServerLevel.this.getChunkSource().addEntity(entity);
-+ // 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 entityplayer) {
- ServerLevel.this.players.add(entityplayer);
- ServerLevel.this.updateSleepingPlayerList();
-@@ -2181,6 +2181,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
- entity.updateDynamicGameEventListener(DynamicGameEventListener::add);
- entity.inWorld = true; // CraftBukkit - Mark entity as in world
- entity.valid = true; // CraftBukkit
-+ ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server
- // Paper start - Entity origin API
- if (entity.getOriginVector() == null) {
- entity.setOrigin(entity.getBukkitEntity().getLocation());
diff --git a/patches/unapplied/server/0332-Don-t-tick-dead-players.patch b/patches/unapplied/server/0332-Don-t-tick-dead-players.patch
deleted file mode 100644
index 0633c8502c..0000000000
--- a/patches/unapplied/server/0332-Don-t-tick-dead-players.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Thu, 2 Apr 2020 17:16:48 -0400
-Subject: [PATCH] Don't tick dead players
-
-Causes sync chunk loads and who knows what all else.
-This is safe because Spectators are skipped in unloaded chunks too in vanilla.
-
-diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index d4bda65d10bee880a341196364db63523f36e380..47982f87ce93658c73ee3d7a5f7dd680e2f9aa36 100644
---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
-+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -765,7 +765,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
-
- public void doTick() {
- try {
-- if (!this.isSpectator() || !this.touchingUnloadedChunk()) {
-+ if (valid && !this.isSpectator() || !this.touchingUnloadedChunk()) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
- super.tick();
- }
-
diff --git a/patches/unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch b/patches/unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch
deleted file mode 100644
index d10a5a50c4..0000000000
--- a/patches/unapplied/server/0333-Dead-Player-s-shouldn-t-be-able-to-move.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Thu, 2 Apr 2020 19:31:16 -0400
-Subject: [PATCH] Dead Player's shouldn't be able to move
-
-This fixes a lot of game state issues where packets were delayed for processing
-due to 1.15's new queue but processed while dead.
-
-diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
-index fa906334a1c569748d3f2dc073ec03a85bd09d3b..cb89b020d93ac838843ec2cbad562326a1e4257b 100644
---- a/src/main/java/net/minecraft/world/entity/player/Player.java
-+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
-@@ -1173,7 +1173,7 @@ public abstract class Player extends LivingEntity {
-
- @Override
- protected boolean isImmobile() {
-- return super.isImmobile() || this.isSleeping();
-+ return super.isImmobile() || this.isSleeping() || this.isRemoved() || !valid; // Paper - player's who are dead or not in a world shouldn't move...
- }
-
- @Override
diff --git a/patches/unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch b/patches/unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch
deleted file mode 100644
index 4c59557ecb..0000000000
--- a/patches/unapplied/server/0334-Don-t-move-existing-players-to-world-spawn.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Thu, 9 Apr 2020 21:20:33 -0400
-Subject: [PATCH] Don't move existing players to world spawn
-
-This can cause a nasty server lag the spawn chunks are not kept loaded
-or they aren't finished loading yet, or if the world spawn radius is
-larger than the keep loaded range.
-
-By skipping this, we avoid potential for a large spike on server start.
-
-== AT ==
-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 47982f87ce93658c73ee3d7a5f7dd680e2f9aa36..f8d4bd18f98ed914e116d0cc4a80140e4e8d759f 100644
---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
-+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -358,7 +358,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
- this.server = server;
- this.stats = server.getPlayerList().getPlayerStats(this);
- this.advancements = server.getPlayerList().getPlayerAdvancements(this);
-- this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
-+ // this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); // Paper - Don't move existing players to world spawn
- this.updateOptions(clientOptions);
- this.object = null;
-
-@@ -628,7 +628,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
- position = Vec3.atCenterOf(world.getSharedSpawnPos());
- }
- this.setLevel(world);
-- this.setPos(position);
-+ this.setPosRaw(position.x(), position.y(), position.z()); // Paper - don't register to chunks yet
- }
- 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 8cd80ea83ddcfd5052c8d8c19d3edb42538d1e15..2cbdcdf0349e7efa797802d0d339d158153690af 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 - Entity#getEntitySpawnReason
- if (optional.isEmpty()) {
- player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login
-+ player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
- }
- // Paper end - Entity#getEntitySpawnReason
- player.setServerLevel(worldserver1);
diff --git a/patches/unapplied/server/0335-Optimize-Pathfinding.patch b/patches/unapplied/server/0335-Optimize-Pathfinding.patch
deleted file mode 100644
index 281988ce37..0000000000
--- a/patches/unapplied/server/0335-Optimize-Pathfinding.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Thu, 3 Mar 2016 02:02:07 -0600
-Subject: [PATCH] Optimize Pathfinding
-
-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 188904c9f0f81db1d63eec953d6746f2dc23dc81..2e9991e6b3c05584002744a2ee2579b1dba218b2 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,13 +192,33 @@ public abstract class PathNavigation {
- return this.moveTo(this.createPath(x, y, z, 1), speed);
- }
-
-+ // Paper start - Perf: Optimise pathfinding
-+ private int lastFailure = 0;
-+ private int pathfindFailures = 0;
-+ // Paper end - Perf: Optimise pathfinding
-+
- public boolean moveTo(double x, double y, double z, int distance, double speed) {
- return this.moveTo(this.createPath(x, y, z, distance), speed);
- }
-
- public boolean moveTo(Entity entity, double speed) {
-+ // Paper start - Perf: Optimise pathfinding
-+ if (this.pathfindFailures > 10 && this.path == null && net.minecraft.server.MinecraftServer.currentTick < this.lastFailure + 40) {
-+ return false;
-+ }
-+ // Paper end - Perf: Optimise pathfinding
- Path path = this.createPath(entity, 1);
-- return path != null && this.moveTo(path, speed);
-+ // Paper start - Perf: Optimise pathfinding
-+ if (path != null && this.moveTo(path, speed)) {
-+ this.lastFailure = 0;
-+ this.pathfindFailures = 0;
-+ return true;
-+ } else {
-+ this.pathfindFailures++;
-+ this.lastFailure = net.minecraft.server.MinecraftServer.currentTick;
-+ return false;
-+ }
-+ // Paper end - Perf: Optimise pathfinding
- }
-
- public boolean moveTo(@Nullable Path path, double speed) {
diff --git a/patches/unapplied/server/0336-Reduce-Either-Optional-allocation.patch b/patches/unapplied/server/0336-Reduce-Either-Optional-allocation.patch
deleted file mode 100644
index d42e0ac184..0000000000
--- a/patches/unapplied/server/0336-Reduce-Either-Optional-allocation.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Spottedleaf <[email protected]>
-Date: Mon, 6 Apr 2020 18:35:09 -0700
-Subject: [PATCH] Reduce Either Optional allocation
-
-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 698ff6caf5924ce5c731254acd466c381c55c9b3..d54e617fc583ae7a045ebba8fde6bc5a486d73d5 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<L, R> implements App<Either.Mu<R>, L> {
- }
-
- private static final class Left<L, R> extends Either<L, R> {
-- private final L value;
-+ private final L value; private Optional<L> valueOptional; // Paper - Perf: Reduce Either Optional allocation
-
- public Left(final L value) {
- this.value = value;
-@@ -51,7 +51,7 @@ public abstract class Either<L, R> implements App<Either.Mu<R>, L> {
-
- @Override
- public Optional<L> left() {
-- return Optional.of(value);
-+ return this.valueOptional == null ? this.valueOptional = Optional.of(this.value) : this.valueOptional; // Paper - Perf: Reduce Either Optional allocation
- }
-
- @Override
-@@ -83,7 +83,7 @@ public abstract class Either<L, R> implements App<Either.Mu<R>, L> {
- }
-
- private static final class Right<L, R> extends Either<L, R> {
-- private final R value;
-+ private final R value; private Optional<R> valueOptional; // Paper - Perf: Reduce Either Optional allocation
-
- public Right(final R value) {
- this.value = value;
-@@ -117,7 +117,7 @@ public abstract class Either<L, R> implements App<Either.Mu<R>, L> {
-
- @Override
- public Optional<R> right() {
-- return Optional.of(value);
-+ return this.valueOptional == null ? this.valueOptional = Optional.of(this.value) : this.valueOptional; // Paper - Perf: Reduce Either Optional allocation
- }
-
- @Override
diff --git a/patches/unapplied/server/0337-Reduce-memory-footprint-of-CompoundTag.patch b/patches/unapplied/server/0337-Reduce-memory-footprint-of-CompoundTag.patch
deleted file mode 100644
index c29c346e90..0000000000
--- a/patches/unapplied/server/0337-Reduce-memory-footprint-of-CompoundTag.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Spottedleaf <[email protected]>
-Date: Mon, 6 Apr 2020 17:39:25 -0700
-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 d721ae6d9b54cbace5b7ade657e9739fc7c42d14..e88161e662d5605b50aead673c9b3794874e5f7f 100644
---- a/src/main/java/net/minecraft/nbt/CompoundTag.java
-+++ b/src/main/java/net/minecraft/nbt/CompoundTag.java
-@@ -49,7 +49,7 @@ public class CompoundTag implements Tag {
-
- private static CompoundTag loadCompound(DataInput input, NbtAccounter tracker) throws IOException {
- tracker.accountBytes(48L);
-- Map<String, Tag> map = Maps.newHashMap();
-+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - Reduce memory footprint of CompoundTag
-
- byte b;
- while ((b = input.readByte()) != 0) {
-@@ -166,7 +166,7 @@ public class CompoundTag implements Tag {
- }
-
- public CompoundTag() {
-- this(Maps.newHashMap());
-+ this(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - Reduce memory footprint of CompoundTag
- }
-
- @Override
-@@ -481,8 +481,16 @@ public class CompoundTag implements Tag {
-
- @Override
- public CompoundTag copy() {
-- Map<String, Tag> map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy));
-- return new CompoundTag(map);
-+ // Paper start - Reduce memory footprint of CompoundTag
-+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f);
-+ java.util.Iterator<java.util.Map.Entry<String, Tag>> 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()) {
-+ Map.Entry<String, Tag> entry = iterator.next();
-+ ret.put(entry.getKey(), entry.getValue().copy());
-+ }
-+
-+ return new CompoundTag(ret);
-+ // Paper end - Reduce memory footprint of CompoundTag
- }
-
- @Override
diff --git a/patches/unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch b/patches/unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch
deleted file mode 100644
index 3f6f9857e6..0000000000
--- a/patches/unapplied/server/0338-Prevent-opening-inventories-when-frozen.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Shane Freeder <[email protected]>
-Date: Mon, 13 Apr 2020 07:31:44 +0100
-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 f8d4bd18f98ed914e116d0cc4a80140e4e8d759f..7daa310dd5d3eb1befb9983ce85e0354771af71d 100644
---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
-+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -710,7 +710,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
- containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate;
- }
- // Paper end - Configurable container update tick rate
-- if (!this.level().isClientSide && !this.containerMenu.stillValid(this)) {
-+ 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 - Inventory close reason
- this.containerMenu = this.inventoryMenu;
- }
-@@ -1634,7 +1634,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
- } else {
- // 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 - 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 ee7cf7f1d491ffdf26c3f156d299e2f517a05608..ba63c58d40cb3b8655fdb8177c423c67ac7cc3ef 100644
---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
-+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
-@@ -334,7 +334,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
- if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(container.getBukkitView().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 - Prevent opening inventories when frozen
- player.containerMenu = container;
- player.initMenu(container);
- }
-@@ -409,7 +409,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
- 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
- //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 - Prevent opening inventories when frozen
- player.containerMenu = container;
- player.initMenu(container);
- }
diff --git a/patches/unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch
deleted file mode 100644
index 4e134e507c..0000000000
--- a/patches/unapplied/server/0339-Don-t-run-entity-collision-code-if-not-needed.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Spottedleaf <[email protected]>
-Date: Wed, 15 Apr 2020 17:56:07 -0700
-Subject: [PATCH] Don't run entity collision code if not needed
-
-Will not run if:
-Max entity cramming is disabled and the max collisions per entity is less than or equal to 0.
-Entity#isPushable() returns false, meaning all entities will not be able to collide with this
-entity anyways.
-The entity's current team collision rule causes them to NEVER collide.
-
-Co-authored-by: Owen1212055 <[email protected]>
-
-diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index 4c32b26e29ca3db0a2f62052e14bcc3e4c1cdea5..cf18f17f181bc94a2b5f4ac6926c2388ec3178c8 100644
---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
-+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-@@ -3544,10 +3544,24 @@ public abstract class LivingEntity extends Entity implements Attackable {
- if (this.level().isClientSide()) {
- this.level().getEntities(EntityTypeTest.forClass(net.minecraft.world.entity.player.Player.class), this.getBoundingBox(), EntitySelector.pushableBy(this)).forEach(this::doPush);
- } else {
-+ // Paper start - don't run getEntities if we're not going to use its result
-+ if (!this.isPushable()) {
-+ return;
-+ }
-+ net.minecraft.world.scores.Team team = this.getTeam();
-+ if (team != null && team.getCollisionRule() == net.minecraft.world.scores.Team.CollisionRule.NEVER) {
-+ return;
-+ }
-+
-+ int i = this.level().getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING);
-+ if (i <= 0 && this.level().paperConfig().collisions.maxEntityCollisions <= 0) {
-+ return;
-+ }
-+ // Paper end - don't run getEntities if we're not going to use its result
- List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this));
-
- if (!list.isEmpty()) {
-- int i = this.level().getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING);
-+ // 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/unapplied/server/0340-Implement-Player-Client-Options-API.patch b/patches/unapplied/server/0340-Implement-Player-Client-Options-API.patch
deleted file mode 100644
index d190884bb0..0000000000
--- a/patches/unapplied/server/0340-Implement-Player-Client-Options-API.patch
+++ /dev/null
@@ -1,194 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: MiniDigger <[email protected]>
-Date: Mon, 20 Jan 2020 21:38:15 +0100
-Subject: [PATCH] Implement Player Client Options API
-
-== AT ==
-public net.minecraft.world.entity.player.Player DATA_PLAYER_MODE_CUSTOMISATION
-
-diff --git a/src/main/java/com/destroystokyo/paper/PaperSkinParts.java b/src/main/java/com/destroystokyo/paper/PaperSkinParts.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..b6f4400df3d8ec7e06a996de54f8cabba57885e1
---- /dev/null
-+++ b/src/main/java/com/destroystokyo/paper/PaperSkinParts.java
-@@ -0,0 +1,74 @@
-+package com.destroystokyo.paper;
-+
-+import com.google.common.base.Objects;
-+
-+import java.util.StringJoiner;
-+
-+public class PaperSkinParts implements SkinParts {
-+
-+ private final int raw;
-+
-+ public PaperSkinParts(int raw) {
-+ this.raw = raw;
-+ }
-+
-+ public boolean hasCapeEnabled() {
-+ return (raw & 1) == 1;
-+ }
-+
-+ public boolean hasJacketEnabled() {
-+ return (raw >> 1 & 1) == 1;
-+ }
-+
-+ public boolean hasLeftSleeveEnabled() {
-+ return (raw >> 2 & 1) == 1;
-+ }
-+
-+ public boolean hasRightSleeveEnabled() {
-+ return (raw >> 3 & 1) == 1;
-+ }
-+
-+ public boolean hasLeftPantsEnabled() {
-+ return (raw >> 4 & 1) == 1;
-+ }
-+
-+ public boolean hasRightPantsEnabled() {
-+ return (raw >> 5 & 1) == 1;
-+ }
-+
-+ public boolean hasHatsEnabled() {
-+ return (raw >> 6 & 1) == 1;
-+ }
-+
-+ @Override
-+ public int getRaw() {
-+ return raw;
-+ }
-+
-+ @Override
-+ public boolean equals(Object o) {
-+ if (this == o) return true;
-+ if (o == null || getClass() != o.getClass()) return false;
-+ PaperSkinParts that = (PaperSkinParts) o;
-+ return raw == that.raw;
-+ }
-+
-+ @Override
-+ public int hashCode() {
-+ return Objects.hashCode(raw);
-+ }
-+
-+ @Override
-+ public String toString() {
-+ return new StringJoiner(", ", PaperSkinParts.class.getSimpleName() + "[", "]")
-+ .add("raw=" + raw)
-+ .add("cape=" + hasCapeEnabled())
-+ .add("jacket=" + hasJacketEnabled())
-+ .add("leftSleeve=" + hasLeftSleeveEnabled())
-+ .add("rightSleeve=" + hasRightSleeveEnabled())
-+ .add("leftPants=" + hasLeftPantsEnabled())
-+ .add("rightPants=" + hasRightPantsEnabled())
-+ .add("hats=" + hasHatsEnabled())
-+ .toString();
-+ }
-+}
-diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 7daa310dd5d3eb1befb9983ce85e0354771af71d..8938f90c53de8aef71aa70522a66a69edb467e73 100644
---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
-+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -359,7 +359,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
- this.stats = server.getPlayerList().getPlayerStats(this);
- this.advancements = server.getPlayerList().getPlayerAdvancements(this);
- // this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); // Paper - Don't move existing players to world spawn
-- this.updateOptions(clientOptions);
-+ this.updateOptionsNoEvents(clientOptions); // Paper - don't call options events on login
- this.object = null;
-
- // CraftBukkit start
-@@ -2146,7 +2146,23 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
- }
- }
-
-+ // Paper start - Client option API
-+ private java.util.Map<com.destroystokyo.paper.ClientOption<?>, ?> getClientOptionMap(String locale, int viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility chatVisibility, boolean chatColors, com.destroystokyo.paper.PaperSkinParts skinParts, org.bukkit.inventory.MainHand mainHand, boolean allowsServerListing, boolean textFilteringEnabled) {
-+ java.util.Map<com.destroystokyo.paper.ClientOption<?>, Object> map = new java.util.HashMap<>();
-+ map.put(com.destroystokyo.paper.ClientOption.LOCALE, locale);
-+ map.put(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE, viewDistance);
-+ map.put(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY, chatVisibility);
-+ map.put(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED, chatColors);
-+ map.put(com.destroystokyo.paper.ClientOption.SKIN_PARTS, skinParts);
-+ map.put(com.destroystokyo.paper.ClientOption.MAIN_HAND, mainHand);
-+ map.put(com.destroystokyo.paper.ClientOption.ALLOW_SERVER_LISTINGS, allowsServerListing);
-+ map.put(com.destroystokyo.paper.ClientOption.TEXT_FILTERING_ENABLED, textFilteringEnabled);
-+ return map;
-+ }
-+ // Paper end
-+
- public void updateOptions(ClientInformation clientOptions) {
-+ new com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent(getBukkitEntity(), getClientOptionMap(clientOptions.language(), clientOptions.viewDistance(), com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(clientOptions.chatVisibility().name()), clientOptions.chatColors(), new com.destroystokyo.paper.PaperSkinParts(clientOptions.modelCustomisation()), clientOptions.mainHand() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT, clientOptions.allowsListing(), clientOptions.textFilteringEnabled())).callEvent(); // Paper - settings event
- // CraftBukkit start
- if (this.getMainArm() != clientOptions.mainHand()) {
- PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), this.getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
-@@ -2157,6 +2173,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
- this.server.server.getPluginManager().callEvent(event);
- }
- // CraftBukkit end
-+ // Paper start - don't call options events on login
-+ this.updateOptionsNoEvents(clientOptions);
-+ }
-+ public void updateOptionsNoEvents(ClientInformation clientOptions) {
-+ // Paper end
- this.language = clientOptions.language();
- this.adventure$locale = java.util.Objects.requireNonNullElse(net.kyori.adventure.translation.Translator.parseLocale(this.language), java.util.Locale.US); // Paper
- this.requestedViewDistance = clientOptions.viewDistance();
-diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 1959e2af13daa06293c10ea2a4f68e319fac26ad..068ff2c228308ec87fcc6d1352bd63b91bd34a93 100644
---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -653,6 +653,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
- connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message);
- }
- }
-+
-+ @Override
-+ public <T> T getClientOption(com.destroystokyo.paper.ClientOption<T> type) {
-+ if (com.destroystokyo.paper.ClientOption.SKIN_PARTS == type) {
-+ return type.getType().cast(new com.destroystokyo.paper.PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION)));
-+ } else if (com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED == type) {
-+ return type.getType().cast(getHandle().canChatInColor());
-+ } else if (com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY == type) {
-+ return type.getType().cast(getHandle().getChatVisibility() == null ? com.destroystokyo.paper.ClientOption.ChatVisibility.UNKNOWN : com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(getHandle().getChatVisibility().name()));
-+ } else if (com.destroystokyo.paper.ClientOption.LOCALE == type) {
-+ return type.getType().cast(getLocale());
-+ } else if (com.destroystokyo.paper.ClientOption.MAIN_HAND == type) {
-+ return type.getType().cast(getMainHand());
-+ } else if (com.destroystokyo.paper.ClientOption.VIEW_DISTANCE == type) {
-+ return type.getType().cast(getClientViewDistance());
-+ } else if (com.destroystokyo.paper.ClientOption.ALLOW_SERVER_LISTINGS == type) {
-+ return type.getType().cast(getHandle().allowsListing());
-+ } else if (com.destroystokyo.paper.ClientOption.TEXT_FILTERING_ENABLED == type) {
-+ return type.getType().cast(getHandle().isTextFilteringEnabled());
-+ }
-+ throw new RuntimeException("Unknown settings type");
-+ }
- // Paper end
-
- @Override
-diff --git a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..7f8b6462d2a1bbd39a870d2543bebc135f7eb45b
---- /dev/null
-+++ b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
-@@ -0,0 +1,18 @@
-+package io.papermc.paper.world;
-+
-+import com.destroystokyo.paper.ClientOption;
-+import net.minecraft.world.entity.player.ChatVisiblity;
-+import org.bukkit.Difficulty;
-+import org.junit.jupiter.api.Assertions;
-+import org.junit.jupiter.api.Test;
-+
-+public class TranslationKeyTest {
-+
-+ @Test
-+ public void testChatVisibilityKeys() {
-+ for (ClientOption.ChatVisibility chatVisibility : ClientOption.ChatVisibility.values()) {
-+ if (chatVisibility == ClientOption.ChatVisibility.UNKNOWN) continue;
-+ Assertions.assertEquals(ChatVisiblity.valueOf(chatVisibility.name()).getKey(), chatVisibility.translationKey(), chatVisibility + "'s translation key doesn't match");
-+ }
-+ }
-+}
diff --git a/patches/unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch
deleted file mode 100644
index 9d20799a09..0000000000
--- a/patches/unapplied/server/0341-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Sat, 18 Apr 2020 15:59:41 -0400
-Subject: [PATCH] Don't crash if player is attempted to be removed from
- untracked chunk.
-
-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 dfa0456f352ce25bc4edd1b0f04ca5a14434d7fa..1e7b440cc2c1bf53210069b38286f67a7b97041b 100644
---- a/src/main/java/net/minecraft/server/level/DistanceManager.java
-+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
-@@ -275,8 +275,8 @@ public abstract class DistanceManager {
- ObjectSet<ServerPlayer> objectset = (ObjectSet) this.playersPerChunk.get(i);
- if (objectset == null) return; // CraftBukkit - SPIGOT-6208
-
-- 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.isEmpty()) { // Paper
- this.playersPerChunk.remove(i);
- this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false);
- this.playerTicketManager.update(i, Integer.MAX_VALUE, false);
diff --git a/patches/unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch b/patches/unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch
deleted file mode 100644
index fda85df8ca..0000000000
--- a/patches/unapplied/server/0342-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Sun, 19 Apr 2020 00:05:46 -0400
-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.
-
-This all boiled down to 1 reason why: The event fired before the
-player was fully ready and joined to the world!
-
-Additionally, if that player logged out on a vehicle, the event
-fired before the vehicle was even loaded, so that plugins had no
-access to the vehicle during this event either.
-
-This change finally fixes this issue, fully preparing the player
-into the world as a fully ready entity, vehicle included.
-
-There should be no plugins that break because of this change, but might
-improve consistency with other plugins instead.
-
-For example, if 2 plugins listens to this event, and the first one
-teleported the player in the event, then the 2nd plugin actually
-would be getting a valid player!
-
-This was very non deterministic. This change will ensure every plugin
-receives a deterministic result, and should no longer require 1 tick
-delays anymore.
-
-== AT ==
-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 8206ec366b429858d9582e437781191e5aa0fa02..d91279f3bd009e1542e73354aadd6a16c80965e2 100644
---- a/src/main/java/net/minecraft/server/level/ChunkMap.java
-+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1248,6 +1248,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- return;
- }
- // 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 8938f90c53de8aef71aa70522a66a69edb467e73..e6e7dc17d1196a8211a565355f34b5dcfd478852 100644
---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
-+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -289,6 +289,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
- public double maxHealthCache;
- public boolean joining = true;
- public boolean sentListPacket = false;
-+ 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 2cbdcdf0349e7efa797802d0d339d158153690af..5390ce62ec8afd24d2e028ea04d2ef3029a125f9 100644
---- a/src/main/java/net/minecraft/server/players/PlayerList.java
-+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -297,6 +297,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 - 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);
-+ this.mountSavedVehicle(player, worldserver1, optional);
-+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
- // CraftBukkit start
- CraftPlayer bukkitPlayer = player.getBukkitEntity();
-
-@@ -335,6 +341,8 @@ public abstract class PlayerList {
- player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer1)));
- }
- player.sentListPacket = true;
-+ 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.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
-@@ -350,6 +358,11 @@ public abstract class PlayerList {
- worldserver1 = player.serverLevel(); // CraftBukkit - Update in case join event changed it
- // CraftBukkit end
- this.sendActivePlayerEffects(player);
-+ // Paper start - Fire PlayerJoinEvent when Player is actually ready; move vehicle into method so it can be called above - short circuit around that code
-+ this.onPlayerJoinFinish(player, worldserver1, s1);
-+ }
-+ private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, Optional<CompoundTag> optional) {
-+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
- if (optional.isPresent() && ((CompoundTag) optional.get()).contains("RootVehicle", 10)) {
- CompoundTag nbttagcompound = ((CompoundTag) optional.get()).getCompound("RootVehicle");
- ServerLevel finalWorldServer = worldserver1; // CraftBukkit - decompile error
-@@ -396,6 +409,10 @@ public abstract class PlayerList {
- }
- }
-
-+ // Paper start - Fire PlayerJoinEvent when Player is actually ready
-+ }
-+ public void onPlayerJoinFinish(ServerPlayer player, ServerLevel worldserver1, String s1) {
-+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
- player.initInventoryMenu();
- // CraftBukkit - Moved from above, added world
- // Paper start - Configurable player collision; Add to collideRule team if needed
diff --git a/patches/unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch
deleted file mode 100644
index b739652ade..0000000000
--- a/patches/unapplied/server/0343-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: 2277 <[email protected]>
-Date: Tue, 31 Mar 2020 10:33:55 +0100
-Subject: [PATCH] Move player to spawn point if spawn in unloaded world
-
-If the playerdata contains an invalid world (missing, unloaded, invalid,
-etc.), spawn the player at the spawn point of the main world.
-
-Co-authored-by: Wyatt Childers <[email protected]>
-Co-authored-by: Jake Potrebic <[email protected]>
-
-diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 5390ce62ec8afd24d2e028ea04d2ef3029a125f9..6f587c4bb4704d93552ba61335d87b1852fc169c 100644
---- a/src/main/java/net/minecraft/server/players/PlayerList.java
-+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -197,6 +197,7 @@ public abstract class PlayerList {
- }
-
- Optional<CompoundTag> optional = this.load(player); // CraftBukkit - decompile error
-+ ResourceKey<Level> resourcekey = null; // Paper
- // CraftBukkit start - Better rename detection
- if (optional.isPresent()) {
- CompoundTag nbttagcompound = optional.get();
-@@ -206,19 +207,47 @@ public abstract class PlayerList {
- }
- }
- // CraftBukkit end
-- ResourceKey<Level> resourcekey = (ResourceKey) optional.flatMap((nbttagcompound) -> {
-+ // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found
-+ boolean[] invalidPlayerWorld = {false};
-+ bukkitData: if (optional.isPresent()) {
-+ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds
-+ final org.bukkit.World bWorld;
-+ if (optional.get().contains("WorldUUIDMost") && optional.get().contains("WorldUUIDLeast")) {
-+ bWorld = org.bukkit.Bukkit.getServer().getWorld(new UUID(optional.get().getLong("WorldUUIDMost"), optional.get().getLong("WorldUUIDLeast")));
-+ } else if (optional.get().contains("world", net.minecraft.nbt.Tag.TAG_STRING)) { // Paper - legacy bukkit world name
-+ bWorld = org.bukkit.Bukkit.getServer().getWorld(optional.get().getString("world"));
-+ } else {
-+ break bukkitData; // if neither of the bukkit data points exist, proceed to the vanilla migration section
-+ }
-+ if (bWorld != null) {
-+ resourcekey = ((CraftWorld) bWorld).getHandle().dimension();
-+ } else {
-+ resourcekey = Level.OVERWORLD;
-+ invalidPlayerWorld[0] = true;
-+ }
-+ }
-+ if (resourcekey == null) { // only run the vanilla logic if we haven't found a world from the bukkit data
-+ // Below is the vanilla way of getting the dimension, this is for migration from vanilla servers
-+ resourcekey = optional.flatMap((nbttagcompound) -> {
-+ // Paper end
- DataResult<ResourceKey<Level>> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbttagcompound.get("Dimension"))); // CraftBukkit - decompile error
- Logger logger = PlayerList.LOGGER;
-
- Objects.requireNonNull(logger);
-- return dataresult.resultOrPartial(logger::error);
-- }).orElse(player.serverLevel().dimension()); // CraftBukkit - SPIGOT-7507: If no dimension, fall back to existing dimension loaded from "WorldUUID", which in turn defaults to World.OVERWORLD
-+ // Paper start - reset to main world spawn if no valid world is found
-+ final Optional<ResourceKey<Level>> result = dataresult.resultOrPartial(logger::error);
-+ invalidPlayerWorld[0] = result.isEmpty();
-+ return result;
-+ }).orElse(Level.OVERWORLD); // Paper - revert to vanilla default main world, this isn't an "invalid world" since no player data existed
-+ }
-+ // Paper end
- ServerLevel worldserver = this.server.getLevel(resourcekey);
- ServerLevel worldserver1;
-
- if (worldserver == null) {
- PlayerList.LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourcekey);
- worldserver1 = this.server.overworld();
-+ invalidPlayerWorld[0] = true; // Paper - reset to main world if no world with parsed value is found
- } else {
- worldserver1 = worldserver;
- }
-@@ -226,6 +255,10 @@ public abstract class PlayerList {
- // Paper start - Entity#getEntitySpawnReason
- if (optional.isEmpty()) {
- 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
-+ }
-+ if (optional.isEmpty() || invalidPlayerWorld[0]) {
-+ // Paper end - reset to main world spawn if first spawn or invalid world
- player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
- }
- // Paper end - Entity#getEntitySpawnReason
-diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 94242c19740ae6ab2c86e3949bab6cee631b938f..d80fd4e2f41583f83c9527ccf4ce80afe851276a 100644
---- a/src/main/java/net/minecraft/world/entity/Entity.java
-+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -2385,27 +2385,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
- }
- // CraftBukkit end
-
-- // CraftBukkit start - Reset world
-- if (this instanceof ServerPlayer) {
-- Server server = Bukkit.getServer();
-- org.bukkit.World bworld = null;
--
-- // TODO: Remove World related checks, replaced with WorldUID
-- String worldName = nbt.getString("world");
--
-- if (nbt.contains("WorldUUIDMost") && nbt.contains("WorldUUIDLeast")) {
-- UUID uid = new UUID(nbt.getLong("WorldUUIDMost"), nbt.getLong("WorldUUIDLeast"));
-- bworld = server.getWorld(uid);
-- } else {
-- bworld = server.getWorld(worldName);
-- }
--
-- if (bworld == null) {
-- bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getLevel(Level.OVERWORLD).getWorld();
-- }
--
-- ((ServerPlayer) this).setLevel(bworld == null ? null : ((CraftWorld) bworld).getHandle());
-- }
-+ // CraftBukkit start
-+ // Paper - move world parsing/loading to PlayerList#placeNewPlayer
- this.getBukkitEntity().readBukkitValues(nbt);
- if (nbt.contains("Bukkit.invisible")) {
- boolean bukkitInvisible = nbt.getBoolean("Bukkit.invisible");
diff --git a/patches/unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch
deleted file mode 100644
index 3348155d85..0000000000
--- a/patches/unapplied/server/0344-Add-PlayerAttackEntityCooldownResetEvent.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: nossr50 <[email protected]>
-Date: Thu, 26 Mar 2020 19:44:50 -0700
-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 cf18f17f181bc94a2b5f4ac6926c2388ec3178c8..42c4adabe451cd32aa362075395a9fcc384ea788 100644
---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
-+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-@@ -2277,7 +2277,17 @@ public abstract class LivingEntity extends Entity implements Attackable {
- }
-
- if (damagesource.getEntity() instanceof net.minecraft.world.entity.player.Player) {
-- ((net.minecraft.world.entity.player.Player) damagesource.getEntity()).resetAttackStrengthTicker(); // Moved from EntityHuman in order to make the cooldown reset get called after the damage event is fired
-+ // Paper start - PlayerAttackEntityCooldownResetEvent
-+ //((net.minecraft.world.entity.player.Player) damagesource.getEntity()).resetAttackStrengthTicker(); // Moved from EntityHuman in order to make the cooldown reset get called after the damage event is fired
-+ if (damagesource.getEntity() instanceof ServerPlayer) {
-+ ServerPlayer player = (ServerPlayer) damagesource.getEntity();
-+ if (new com.destroystokyo.paper.event.player.PlayerAttackEntityCooldownResetEvent(player.getBukkitEntity(), this.getBukkitEntity(), player.getAttackStrengthScale(0F)).callEvent()) {
-+ player.resetAttackStrengthTicker();
-+ }
-+ } else {
-+ ((net.minecraft.world.entity.player.Player) damagesource.getEntity()).resetAttackStrengthTicker();
-+ }
-+ // Paper end - PlayerAttackEntityCooldownResetEvent
- }
-
- // Resistance
diff --git a/patches/unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch b/patches/unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch
deleted file mode 100644
index a909ceca12..0000000000
--- a/patches/unapplied/server/0345-Don-t-fire-BlockFade-on-worldgen-threads.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Thu, 23 Apr 2020 01:36:39 -0400
-Subject: [PATCH] Don't fire BlockFade on worldgen threads
-
-
-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 c1111bd8065b53cb140e4289cb72985f03e6f549..9db6df5f28be559a324ead2fcfbe189eac076e2e 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 {
- @Override
- protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
- // CraftBukkit start
-+ if (!(world instanceof ServerLevel)) return this.canSurvive(state, world, pos) ? (BlockState) this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)) : Blocks.AIR.defaultBlockState(); // Paper - don't fire events in world generation
- if (!this.canSurvive(state, world, pos)) {
- // Suppress during worldgen
- if (!(world instanceof Level)) {
-@@ -123,7 +124,7 @@ public class FireBlock extends BaseFireBlock {
- return blockState.getHandle();
- }
- }
-- return this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE));
-+ 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/unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch b/patches/unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch
deleted file mode 100644
index 0eea572994..0000000000
--- a/patches/unapplied/server/0346-Add-phantom-creative-and-insomniac-controls.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath <[email protected]>
-Date: Sat, 25 Apr 2020 15:13:41 -0500
-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 f7014bf5faae03a04c31cbdaeb27188c47156c2d..eb425fac573881f3aad09ae75a32184fb0e325a6 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<Entity> CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith);
-+ public static Predicate<Player> 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 - Affects Spawning API
-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 3c3f70d05fb51b530b792adf84c324840bd03c14..4b3bec32921feb1dcf71abf5e8d34fcbbc59baf5 100644
---- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
-+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
-@@ -549,6 +549,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 - 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 bb7f2d3ff7fc6f5cadb4ab24efb5a3a2f5bdc33f..f74d41e57570a40cd5ce4da3076f3210b6594a63 100644
---- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
-+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
-@@ -48,7 +48,7 @@ public class PhantomSpawner implements CustomSpawner {
- while (iterator.hasNext()) {
- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
-
-- if (!entityplayer.isSpectator()) {
-+ 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/unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch b/patches/unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch
deleted file mode 100644
index 86f3c094a3..0000000000
--- a/patches/unapplied/server/0347-Fix-item-duplication-and-teleport-issues.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Sat, 25 Apr 2020 06:46:35 -0400
-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
-
-We also fix item duplication generically by anytime we clone an item
-to drop it on the ground, destroy the source item.
-
-This avoid an itemstack ever existing twice in the world state pre
-clean up stage.
-
-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 d80fd4e2f41583f83c9527ccf4ce80afe851276a..10015beb7a2de890fe27bffde8f55c1dd78ce344 100644
---- a/src/main/java/net/minecraft/world/entity/Entity.java
-+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -2515,11 +2515,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
- } else {
- // CraftBukkit start - Capture drops for death event
- if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) {
-- ((net.minecraft.world.entity.LivingEntity) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(stack));
-+ ((net.minecraft.world.entity.LivingEntity) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack)); // Paper - mirror so we can destroy it later
- return null;
- }
- // CraftBukkit end
-- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + (double) yOffset, this.getZ(), stack);
-+ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original
-+ stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe
-
- entityitem.setDefaultPickUpDelay();
- // CraftBukkit start
-@@ -3335,6 +3336,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
- public Entity changeDimension(DimensionTransition teleportTarget) {
- Level world = this.level();
-
-+ // Paper start - Fix item duplication and teleport issues
-+ if (!this.isAlive() || !this.valid) {
-+ LOGGER.warn("Illegal Entity Teleport " + this + " to " + teleportTarget.newLevel() + ":" + teleportTarget.pos(), new Throwable());
-+ return null;
-+ }
-+ // Paper end - Fix item duplication and teleport issues
- if (world instanceof ServerLevel worldserver) {
- if (!this.isRemoved()) {
- // CraftBukkit start
-@@ -3377,6 +3384,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
-
- if (entity2 != null) {
- if (this != entity2) {
-+ // Paper start - Fix item duplication and teleport issues
-+ if (this instanceof Leashable leashable) {
-+ leashable.dropLeash(true, true); // Paper drop lead
-+ }
-+ // Paper end - Fix item duplication and teleport issues
- entity2.restoreFrom(this);
- this.removeAfterChangingDimensions();
- // CraftBukkit start - Forward the CraftEntity to the new entity
-@@ -3452,7 +3464,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
- }
-
- public boolean canChangeDimensions(Level from, Level to) {
-- return true;
-+ return this.isAlive() && this.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 42c4adabe451cd32aa362075395a9fcc384ea788..8920099eb488c37b036b7bd97fbd4f7db505c77c 100644
---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
-+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-@@ -1728,9 +1728,9 @@ public abstract class LivingEntity extends Entity implements Attackable {
- // Paper start
- org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(worldserver, damageSource);
- if (deathEvent == null || !deathEvent.isCancelled()) {
-- if (this.deathScore >= 0 && entityliving != null) {
-- entityliving.awardKillScore(this, this.deathScore, damageSource);
-- }
-+ // 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
- if (this instanceof Mob) {
- for (EquipmentSlot slot : this.clearedEquipmentSlots) {
-@@ -1822,8 +1822,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
- this.dropCustomDeathLoot(world, damageSource, flag);
- this.clearEquipmentSlots = prev; // Paper
- }
-- // CraftBukkit start - Call death event
-- org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, damageSource, this.drops); // Paper
-+ // CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment
-+ org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, damageSource, this.drops, () -> {
-+ final LivingEntity entityliving = this.getKillCredit();
-+ if (this.deathScore >= 0 && entityliving != null) {
-+ entityliving.awardKillScore(this, this.deathScore, damageSource);
-+ }
-+ }); // Paper end
- this.postDeathDropItems(deathEvent); // Paper
- this.drops = new ArrayList<>();
- // CraftBukkit end
-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 92bb0c63330ad3a4cb13b2dc655020714e9b1ffd..cc1189c2d7dc57ba8f29aad4ba5d2a07362bcd5b 100644
---- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
-+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
-@@ -635,7 +635,7 @@ public class ArmorStand extends LivingEntity {
- for (i = 0; i < this.handItems.size(); ++i) {
- itemstack = (ItemStack) this.handItems.get(i);
- if (!itemstack.isEmpty()) {
-- this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
-+ this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
- this.handItems.set(i, ItemStack.EMPTY);
- }
- }
-@@ -643,7 +643,7 @@ public class ArmorStand extends LivingEntity {
- for (i = 0; i < this.armorItems.size(); ++i) {
- itemstack = (ItemStack) this.armorItems.get(i);
- if (!itemstack.isEmpty()) {
-- this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
-+ this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
- this.armorItems.set(i, ItemStack.EMPTY);
- }
- }
-diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-index 235ac5c12dab593da3a40e348a010ff626ce74a3..26f8a8cb18205bfb9fe9dc557097946987ddcb18 100644
---- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-@@ -905,6 +905,11 @@ public class CraftEventFactory {
- }
-
- public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops) {
-+ // Paper start
-+ return CraftEventFactory.callEntityDeathEvent(victim, damageSource, drops, com.google.common.util.concurrent.Runnables.doNothing());
-+ }
-+ public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, Runnable lootCheck) {
-+ // Paper end
- CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
- CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
- EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()));
-@@ -919,11 +924,13 @@ public class CraftEventFactory {
- playDeathSound(victim, event);
- // Paper end
- victim.expToDrop = event.getDroppedExp();
-+ lootCheck.run(); // Paper - advancement triggers before destroying items
-
- for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
- if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue;
-
-- world.dropItem(entity.getLocation(), stack);
-+ world.dropItem(entity.getLocation(), stack); // Paper - note: dropItem already clones due to this being bukkit -> NMS
-+ if (stack instanceof CraftItemStack) stack.setAmount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe, but don't nuke bukkit stacks of manually added items
- }
-
- return event;
diff --git a/patches/unapplied/server/0348-Villager-Restocks-API.patch b/patches/unapplied/server/0348-Villager-Restocks-API.patch
deleted file mode 100644
index 1f7c26de9d..0000000000
--- a/patches/unapplied/server/0348-Villager-Restocks-API.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: zbk <[email protected]>
-Date: Sun, 26 Apr 2020 23:49:01 -0400
-Subject: [PATCH] Villager Restocks API
-
-== AT ==
-public net.minecraft.world.entity.npc.Villager numberOfRestocksToday
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
-index 1b97755b42aaa6cc27b79f0b6369955e9a17c4d4..957c9ec21c7a9888b3038402b0111c68f816f968 100644
---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
-+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
-@@ -89,6 +89,18 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
- this.getHandle().setVillagerXp(experience);
- }
-
-+ // Paper start
-+ @Override
-+ public int getRestocksToday() {
-+ return getHandle().numberOfRestocksToday;
-+ }
-+
-+ @Override
-+ public void setRestocksToday(int restocksToday) {
-+ getHandle().numberOfRestocksToday = restocksToday;
-+ }
-+ // Paper end
-+
- @Override
- public boolean sleep(Location location) {
- Preconditions.checkArgument(location != null, "Location cannot be null");
diff --git a/patches/unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch
deleted file mode 100644
index 774f59a115..0000000000
--- a/patches/unapplied/server/0349-Validate-PickItem-Packet-and-kick-for-invalid.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Sat, 2 May 2020 03:09:46 -0400
-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 0ed2d0f5ec9d107e8049aa9e803479ffd341639f..119b9b2c45e3321b4197f3e6a34037e3fa99622d 100644
---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -895,7 +895,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- @Override
- public void handlePickItem(ServerboundPickItemPacket packet) {
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
-- this.player.getInventory().pickSlot(packet.getSlot());
-+ // Paper start - validate pick item position
-+ if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.getInventory().items.size())) {
-+ ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString());
-+ this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)"));
-+ return;
-+ }
-+ this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed
-+ // 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/unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch b/patches/unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch
deleted file mode 100644
index 46f51a9f45..0000000000
--- a/patches/unapplied/server/0350-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Mon, 4 May 2020 01:08:56 -0400
-Subject: [PATCH] Set cap on JDK per-thread native byte buffer cache
-
-See: https://www.evanjones.ca/java-bytebuffer-leak.html
-
-This is potentially a source of lots of native memory usage.
-
-We are clearly seeing native usage upwards to 1-4GB which doesn't make sense.
-
-Region File usage fixed in previous patch should of tecnically only been somewhat
-temporary until GC finally gets it some time later, but between all the various
-plugins doing IO on various threads, this hidden detail of the JDK could be
-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 ed167d0d399924d54d9ff99c10ab8ee093efc149..168cbb239ac5d632908f2b0aca82cbcfdc35651f 100644
---- a/src/main/java/org/bukkit/craftbukkit/Main.java
-+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
-@@ -27,6 +27,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; https://www.evanjones.ca/java-bytebuffer-leak.html
- OptionParser parser = new OptionParser() {
- {
- this.acceptsAll(Main.asList("?", "help"), "Show the help");
diff --git a/patches/unapplied/server/0351-misc-debugging-dumps.patch b/patches/unapplied/server/0351-misc-debugging-dumps.patch
deleted file mode 100644
index b339217a99..0000000000
--- a/patches/unapplied/server/0351-misc-debugging-dumps.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Shane Freeder <[email protected]>
-Date: Thu, 18 Feb 2021 20:23:28 +0000
-Subject: [PATCH] misc debugging dumps
-
-
-diff --git a/src/main/java/io/papermc/paper/util/TraceUtil.java b/src/main/java/io/papermc/paper/util/TraceUtil.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..479bb92d159f33c54c2d9c39d8a63aa9e74d95b9
---- /dev/null
-+++ b/src/main/java/io/papermc/paper/util/TraceUtil.java
-@@ -0,0 +1,25 @@
-+package io.papermc.paper.util;
-+
-+import org.bukkit.Bukkit;
-+
-+public final class TraceUtil {
-+
-+ public static void dumpTraceForThread(Thread thread, String reason) {
-+ Bukkit.getLogger().warning(thread.getName() + ": " + reason);
-+ StackTraceElement[] trace = StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(thread.getStackTrace());
-+ for (StackTraceElement traceElement : trace) {
-+ Bukkit.getLogger().warning("\tat " + traceElement);
-+ }
-+ }
-+
-+ public static void dumpTraceForThread(String reason) {
-+ final Throwable thr = new Throwable(reason);
-+ StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(thr);
-+ thr.printStackTrace();
-+ }
-+
-+ public static void printStackTrace(Throwable thr) {
-+ StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(thr);
-+ thr.printStackTrace();
-+ }
-+}
-diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
-index e25fc35716aff1d1805884b18f67b0eb33d8c05c..8ca9ac8eff9d605baa878ca24e165ac5642bf160 100644
---- a/src/main/java/net/minecraft/commands/Commands.java
-+++ b/src/main/java/net/minecraft/commands/Commands.java
-@@ -340,7 +340,7 @@ public class Commands {
- } catch (Exception exception) {
- MutableComponent ichatmutablecomponent = Component.literal(exception.getMessage() == null ? exception.getClass().getName() : exception.getMessage());
-
-- if (Commands.LOGGER.isDebugEnabled()) {
-+ 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 53bb62c1dcb487be915759d22e06aea80be54f36..8b17df3d18fe9acc1a7b10c6809886da0143f8c5 100644
---- a/src/main/java/net/minecraft/server/MinecraftServer.java
-+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -915,6 +915,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
-
- // CraftBukkit start
- private boolean hasStopped = false;
-+ private boolean hasLoggedStop = false; // Paper - Debugging
- private final Object stopLock = new Object();
- public final boolean hasStopped() {
- synchronized (this.stopLock) {
-@@ -929,6 +930,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- if (this.hasStopped) return;
- this.hasStopped = true;
- }
-+ if (!hasLoggedStop && isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
- // CraftBukkit end
- if (this.metricsRecorder.isRecording()) {
- this.cancelRecordingMetrics();
-@@ -1033,6 +1035,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- }
- public void safeShutdown(boolean waitForShutdown, boolean isRestarting) {
- this.isRestarting = isRestarting;
-+ this.hasLoggedStop = true; // Paper - Debugging
-+ if (isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
- // Paper end
- this.running = false;
- if (waitForShutdown) {
-diff --git a/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java
-index 5457358bc76889153036818fdfd70a043ec4e40f..880e5c52746e9e3a9a1f42ec6461be54e3ee136c 100644
---- a/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java
-+++ b/src/main/java/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java
-@@ -70,6 +70,10 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis
-
- @Override
- public void onDisconnect(DisconnectionDetails info) {
-+ // Paper start - Debugging
-+ if (net.minecraft.server.MinecraftServer.getServer().isDebugging()) {
-+ ServerConfigurationPacketListenerImpl.LOGGER.info("{} lost connection: {}, while in configuration phase {}", this.gameProfile, info.reason().getString(), currentTask != null ? currentTask.type().id() : "null");
-+ } else // Paper end
- ServerConfigurationPacketListenerImpl.LOGGER.info("{} lost connection: {}", this.gameProfile, info.reason().getString());
- super.onDisconnect(info);
- }
-@@ -169,6 +173,11 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis
- playerlist.placeNewPlayer(this.connection, entityplayer, this.createCookie(this.clientInformation));
- } catch (Exception exception) {
- ServerConfigurationPacketListenerImpl.LOGGER.error("Couldn't place player in world", exception);
-+ // Paper start - Debugging
-+ if (MinecraftServer.getServer().isDebugging()) {
-+ exception.printStackTrace();
-+ }
-+ // Paper end - Debugging
- this.connection.send(new ClientboundDisconnectPacket(ServerConfigurationPacketListenerImpl.DISCONNECT_REASON_INVALID_DATA));
- this.connection.disconnect(ServerConfigurationPacketListenerImpl.DISCONNECT_REASON_INVALID_DATA);
- }
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 7226c506c902fc94f27cc5d444e25882138759c2..75ea1d68c4be6f73ad05cd53b4e4c0182832395c 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -1049,6 +1049,7 @@ public final class CraftServer implements Server {
- plugin.getDescription().getFullName(),
- "This plugin is not properly shutting down its async tasks when it is being reloaded. This may cause conflicts with the newly loaded version of the plugin"
- ));
-+ if (console.isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread(worker.getThread(), "still running"); // Paper - Debugging
- }
- io.papermc.paper.plugin.PluginInitializerManager.reload(this.console); // Paper
- this.loadPlugins();
diff --git a/patches/unapplied/server/0352-Prevent-teleporting-dead-entities.patch b/patches/unapplied/server/0352-Prevent-teleporting-dead-entities.patch
deleted file mode 100644
index 361f87db56..0000000000
--- a/patches/unapplied/server/0352-Prevent-teleporting-dead-entities.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Shane Freeder <[email protected]>
-Date: Tue, 3 Mar 2020 05:26:40 +0000
-Subject: [PATCH] Prevent teleporting dead entities
-
-
-diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 119b9b2c45e3321b4197f3e6a34037e3fa99622d..c6bcde25b476ef2362f469bd7cba82ce97cb300c 100644
---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -1552,6 +1552,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- }
-
- public void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<RelativeMovement> set) { // Paper
-+ // 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 - Prevent teleporting dead entities
- // CraftBukkit start
- if (Float.isNaN(f)) {
- f = 0;