diff --git a/patches/unapplied/server/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch b/patches/server/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch similarity index 100% rename from patches/unapplied/server/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch rename to patches/server/Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch diff --git a/patches/unapplied/server/Add-LivingEntity-getTargetEntity.patch b/patches/server/Add-LivingEntity-getTargetEntity.patch similarity index 99% rename from patches/unapplied/server/Add-LivingEntity-getTargetEntity.patch rename to patches/server/Add-LivingEntity-getTargetEntity.patch index 73940e29d..893dba641 100644 --- a/patches/unapplied/server/Add-LivingEntity-getTargetEntity.patch +++ b/patches/server/Add-LivingEntity-getTargetEntity.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.PlayerTeam; -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { return level.clip(raytrace); } diff --git a/patches/unapplied/server/Add-PlayerConnectionCloseEvent.patch b/patches/server/Add-PlayerConnectionCloseEvent.patch similarity index 100% rename from patches/unapplied/server/Add-PlayerConnectionCloseEvent.patch rename to patches/server/Add-PlayerConnectionCloseEvent.patch diff --git a/patches/server/Add-PlayerJumpEvent.patch b/patches/server/Add-PlayerJumpEvent.patch index 6ef3a584c..940607b19 100644 --- a/patches/server/Add-PlayerJumpEvent.patch +++ b/patches/server/Add-PlayerJumpEvent.patch @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.player.jumpFromGround(); + } else { + from = event.getFrom(); -+ this.internalTeleport(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet(), false); ++ this.internalTeleport(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet()); + return; + } + // Paper end diff --git a/patches/unapplied/server/Add-more-Witch-API.patch b/patches/server/Add-more-Witch-API.patch similarity index 100% rename from patches/unapplied/server/Add-more-Witch-API.patch rename to patches/server/Add-more-Witch-API.patch diff --git a/patches/unapplied/server/Add-more-Zombie-API.patch b/patches/server/Add-more-Zombie-API.patch similarity index 100% rename from patches/unapplied/server/Add-more-Zombie-API.patch rename to patches/server/Add-more-Zombie-API.patch diff --git a/patches/unapplied/server/Add-option-to-prevent-players-from-moving-into-unloa.patch b/patches/server/Add-option-to-prevent-players-from-moving-into-unloa.patch similarity index 98% rename from patches/unapplied/server/Add-option-to-prevent-players-from-moving-into-unloa.patch rename to patches/server/Add-option-to-prevent-players-from-moving-into-unloa.patch index 2fd504b2c..9e60e391f 100644 --- a/patches/unapplied/server/Add-option-to-prevent-players-from-moving-into-unloa.patch +++ b/patches/server/Add-option-to-prevent-players-from-moving-into-unloa.patch @@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + // Paper start - Prevent moving into unloaded chunks + if (player.level.paperConfig().chunks.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position())))) { -+ this.internalTeleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot(), Collections.emptySet(), true); ++ this.internalTeleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot(), Collections.emptySet()); + return; + } + // Paper end diff --git a/patches/unapplied/server/Add-ray-tracing-methods-to-LivingEntity.patch b/patches/server/Add-ray-tracing-methods-to-LivingEntity.patch similarity index 99% rename from patches/unapplied/server/Add-ray-tracing-methods-to-LivingEntity.patch rename to patches/server/Add-ray-tracing-methods-to-LivingEntity.patch index 6334cb29f..b3b54d369 100644 --- a/patches/unapplied/server/Add-ray-tracing-methods-to-LivingEntity.patch +++ b/patches/server/Add-ray-tracing-methods-to-LivingEntity.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { } // Paper start diff --git a/patches/unapplied/server/Add-sun-related-API.patch b/patches/server/Add-sun-related-API.patch similarity index 100% rename from patches/unapplied/server/Add-sun-related-API.patch rename to patches/server/Add-sun-related-API.patch diff --git a/patches/server/Adventure.patch b/patches/server/Adventure.patch index 6dcff7c5e..edf03c7b3 100644 --- a/patches/server/Adventure.patch +++ b/patches/server/Adventure.patch @@ -2190,6 +2190,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import com.mojang.datafixers.util.Pair; import java.util.Arrays; import java.util.concurrent.ExecutionException; +@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + private static final int NO_BLOCK_UPDATES_TO_ACK = -1; + private static final int TRACKED_MESSAGE_DISCONNECT_THRESHOLD = 4096; + private static final Component CHAT_VALIDATION_FAILED = Component.translatable("multiplayer.disconnect.chat_validation_failed"); +- private final Connection connection; ++ public final Connection connection; // Paper + private final MinecraftServer server; + public ServerPlayer player; + private int tickCount; @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic return this.server.isSingleplayerOwner(this.player.getGameProfile()); } diff --git a/patches/unapplied/server/Allow-chests-to-be-placed-with-NBT-data.patch b/patches/server/Allow-chests-to-be-placed-with-NBT-data.patch similarity index 100% rename from patches/unapplied/server/Allow-chests-to-be-placed-with-NBT-data.patch rename to patches/server/Allow-chests-to-be-placed-with-NBT-data.patch diff --git a/patches/unapplied/server/Async-command-map-building.patch b/patches/server/Async-command-map-building.patch similarity index 100% rename from patches/unapplied/server/Async-command-map-building.patch rename to patches/server/Async-command-map-building.patch diff --git a/patches/unapplied/server/Block-Entity-remove-from-being-called-on-Players.patch b/patches/server/Block-Entity-remove-from-being-called-on-Players.patch similarity index 100% rename from patches/unapplied/server/Block-Entity-remove-from-being-called-on-Players.patch rename to patches/server/Block-Entity-remove-from-being-called-on-Players.patch diff --git a/patches/unapplied/server/BlockDestroyEvent.patch b/patches/server/BlockDestroyEvent.patch similarity index 100% rename from patches/unapplied/server/BlockDestroyEvent.patch rename to patches/server/BlockDestroyEvent.patch diff --git a/patches/unapplied/server/Book-Size-Limits.patch b/patches/server/Book-Size-Limits.patch similarity index 100% rename from patches/unapplied/server/Book-Size-Limits.patch rename to patches/server/Book-Size-Limits.patch diff --git a/patches/unapplied/server/Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch b/patches/server/Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch similarity index 100% rename from patches/unapplied/server/Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch rename to patches/server/Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch diff --git a/patches/server/Call-player-spectator-target-events-and-improve-impl.patch b/patches/server/Call-player-spectator-target-events-and-improve-impl.patch new file mode 100644 index 000000000..893f229e0 --- /dev/null +++ b/patches/server/Call-player-spectator-target-events-and-improve-impl.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Caleb Bassham +Date: Fri, 28 Sep 2018 02:32:19 -0500 +Subject: [PATCH] Call player spectator target events and improve + implementation + +Use a proper teleport for teleporting to entities in different +worlds. + +Implementation improvements authored by Spottedleaf +Validate that the target entity is valid and deny spectate +requests from frozen players. + +Also, make sure the entity is spawned to the client before +sending the camera packet. If the entity isn't spawned clientside +when it receives the camera packet, then the client will not +spectate the target entity. + +Co-authored-by: Spottedleaf + +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { + + this.camera = (Entity) (entity == null ? this : entity); + if (entity1 != this.camera) { ++ // Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity Event ++ if (this.camera == this) { ++ com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent playerStopSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity()); ++ if (!playerStopSpectatingEntityEvent.callEvent()) { ++ return; ++ } ++ } else { ++ com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent playerStartSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity(), entity.getBukkitEntity()); ++ if (!playerStartSpectatingEntityEvent.callEvent()) { ++ return; ++ } ++ } ++ // Paper end + Level world = this.camera.getLevel(); + + if (world instanceof ServerLevel) { +@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { + this.connection.send(new ClientboundSetCameraPacket(this.camera)); + this.connection.resetPosition(); + } +- + } + + @Override diff --git a/patches/unapplied/server/Catch-JsonParseException-in-Entity-and-TE-names.patch b/patches/server/Catch-JsonParseException-in-Entity-and-TE-names.patch similarity index 100% rename from patches/unapplied/server/Catch-JsonParseException-in-Entity-and-TE-names.patch rename to patches/server/Catch-JsonParseException-in-Entity-and-TE-names.patch diff --git a/patches/unapplied/server/Check-Drowned-for-Villager-Aggression-Config.patch b/patches/server/Check-Drowned-for-Villager-Aggression-Config.patch similarity index 100% rename from patches/unapplied/server/Check-Drowned-for-Villager-Aggression-Config.patch rename to patches/server/Check-Drowned-for-Villager-Aggression-Config.patch diff --git a/patches/unapplied/server/Configurable-connection-throttle-kick-message.patch b/patches/server/Configurable-connection-throttle-kick-message.patch similarity index 100% rename from patches/unapplied/server/Configurable-connection-throttle-kick-message.patch rename to patches/server/Configurable-connection-throttle-kick-message.patch diff --git a/patches/unapplied/server/Don-t-allow-digging-into-unloaded-chunks.patch b/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch similarity index 100% rename from patches/unapplied/server/Don-t-allow-digging-into-unloaded-chunks.patch rename to patches/server/Don-t-allow-digging-into-unloaded-chunks.patch diff --git a/patches/unapplied/server/Don-t-check-ConvertSigns-boolean-every-sign-save.patch b/patches/server/Don-t-check-ConvertSigns-boolean-every-sign-save.patch similarity index 100% rename from patches/unapplied/server/Don-t-check-ConvertSigns-boolean-every-sign-save.patch rename to patches/server/Don-t-check-ConvertSigns-boolean-every-sign-save.patch diff --git a/patches/unapplied/server/Don-t-sleep-after-profile-lookups-if-not-needed.patch b/patches/server/Don-t-sleep-after-profile-lookups-if-not-needed.patch similarity index 100% rename from patches/unapplied/server/Don-t-sleep-after-profile-lookups-if-not-needed.patch rename to patches/server/Don-t-sleep-after-profile-lookups-if-not-needed.patch diff --git a/patches/unapplied/server/Entity-getEntitySpawnReason.patch b/patches/server/Entity-getEntitySpawnReason.patch similarity index 91% rename from patches/unapplied/server/Entity-getEntitySpawnReason.patch rename to patches/server/Entity-getEntitySpawnReason.patch index 870cb75fd..36d2f06af 100644 --- a/patches/unapplied/server/Entity-getEntitySpawnReason.patch +++ b/patches/server/Entity-getEntitySpawnReason.patch @@ -38,15 +38,6 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -0,0 +0,0 @@ import net.minecraft.world.InteractionHand; - import net.minecraft.world.InteractionResult; - import net.minecraft.world.Nameable; - import net.minecraft.world.damagesource.DamageSource; -+import net.minecraft.world.entity.animal.AbstractFish; -+import net.minecraft.world.entity.animal.Animal; - import net.minecraft.world.entity.item.ItemEntity; - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.entity.vehicle.Boat; @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } } @@ -80,7 +71,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (spawnReason == null) { + if (spawnedViaMobSpawner) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; -+ } else if (this instanceof Mob && (this instanceof Animal || this instanceof AbstractFish) && !((Mob) this).removeWhenFarAway(0.0)) { ++ } else if (this instanceof Mob && (this instanceof net.minecraft.world.entity.animal.Animal || this instanceof net.minecraft.world.entity.animal.AbstractFish) && !((Mob) this).removeWhenFarAway(0.0)) { + if (!nbt.getBoolean("PersistenceRequired")) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL; + } diff --git a/patches/unapplied/server/Expose-attack-cooldown-methods-for-Player.patch b/patches/server/Expose-attack-cooldown-methods-for-Player.patch similarity index 100% rename from patches/unapplied/server/Expose-attack-cooldown-methods-for-Player.patch rename to patches/server/Expose-attack-cooldown-methods-for-Player.patch diff --git a/patches/unapplied/server/Fire-event-on-GS4-query.patch b/patches/server/Fire-event-on-GS4-query.patch similarity index 100% rename from patches/unapplied/server/Fire-event-on-GS4-query.patch rename to patches/server/Fire-event-on-GS4-query.patch diff --git a/patches/unapplied/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch b/patches/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch similarity index 97% rename from patches/unapplied/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch rename to patches/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch index 65b71c50a..b7f4df810 100644 --- a/patches/unapplied/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch +++ b/patches/server/Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch @@ -65,4 +65,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end } - public ItemStack assemble(CraftingContainer inventory) { + public ItemStack assemble(CraftingContainer inventory, RegistryAccess registryManager) { diff --git a/patches/unapplied/server/Fix-SpongeAbsortEvent-handling.patch b/patches/server/Fix-SpongeAbsortEvent-handling.patch similarity index 100% rename from patches/unapplied/server/Fix-SpongeAbsortEvent-handling.patch rename to patches/server/Fix-SpongeAbsortEvent-handling.patch diff --git a/patches/unapplied/server/Handle-Large-Packets-disconnecting-client.patch b/patches/server/Handle-Large-Packets-disconnecting-client.patch similarity index 100% rename from patches/unapplied/server/Handle-Large-Packets-disconnecting-client.patch rename to patches/server/Handle-Large-Packets-disconnecting-client.patch diff --git a/patches/unapplied/server/Handle-Oversized-Tile-Entities-in-chunks.patch b/patches/server/Handle-Oversized-Tile-Entities-in-chunks.patch similarity index 100% rename from patches/unapplied/server/Handle-Oversized-Tile-Entities-in-chunks.patch rename to patches/server/Handle-Oversized-Tile-Entities-in-chunks.patch diff --git a/patches/unapplied/server/Honor-EntityAgeable.ageLock.patch b/patches/server/Honor-EntityAgeable.ageLock.patch similarity index 100% rename from patches/unapplied/server/Honor-EntityAgeable.ageLock.patch rename to patches/server/Honor-EntityAgeable.ageLock.patch diff --git a/patches/unapplied/server/Hook-into-CB-plugin-rewrites.patch b/patches/server/Hook-into-CB-plugin-rewrites.patch similarity index 100% rename from patches/unapplied/server/Hook-into-CB-plugin-rewrites.patch rename to patches/server/Hook-into-CB-plugin-rewrites.patch diff --git a/patches/unapplied/server/Implement-Brigadier-Mojang-API.patch b/patches/server/Implement-Brigadier-Mojang-API.patch similarity index 100% rename from patches/unapplied/server/Implement-Brigadier-Mojang-API.patch rename to patches/server/Implement-Brigadier-Mojang-API.patch diff --git a/patches/unapplied/server/Implement-PlayerPostRespawnEvent.patch b/patches/server/Implement-PlayerPostRespawnEvent.patch similarity index 100% rename from patches/unapplied/server/Implement-PlayerPostRespawnEvent.patch rename to patches/server/Implement-PlayerPostRespawnEvent.patch diff --git a/patches/unapplied/server/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch b/patches/server/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch similarity index 100% rename from patches/unapplied/server/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch rename to patches/server/Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch diff --git a/patches/unapplied/server/Implement-furnace-cook-speed-multiplier-API.patch b/patches/server/Implement-furnace-cook-speed-multiplier-API.patch similarity index 98% rename from patches/unapplied/server/Implement-furnace-cook-speed-multiplier-API.patch rename to patches/server/Implement-furnace-cook-speed-multiplier-API.patch index 1138accfb..5a38c1c3a 100644 --- a/patches/unapplied/server/Implement-furnace-cook-speed-multiplier-API.patch +++ b/patches/server/Implement-furnace-cook-speed-multiplier-API.patch @@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 blockEntity.cookingProgress = 0; - blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity); + blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity.recipeType, blockEntity, blockEntity.cookSpeedMultiplier); // Paper - if (AbstractFurnaceBlockEntity.burn(blockEntity.level, blockEntity.worldPosition, irecipe, blockEntity.items, i)) { // CraftBukkit + if (AbstractFurnaceBlockEntity.burn(blockEntity.level, blockEntity.worldPosition, world.registryAccess(), irecipe, blockEntity.items, i)) { // CraftBukkit blockEntity.setRecipeUsed(irecipe); } @@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit diff --git a/patches/unapplied/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch similarity index 95% rename from patches/unapplied/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch rename to patches/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch index b4ce6946b..831ac9123 100644 --- a/patches/unapplied/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch +++ b/patches/server/Improve-Server-Thread-Pool-and-Thread-Priorities.patch @@ -42,9 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private static final int DEFAULT_MAX_THREADS = 255; private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads"; private static final AtomicInteger WORKER_COUNT = new AtomicInteger(1); -- private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap"); - private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main"); -+ private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap", -2); // Paper - add -2 priority + private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - add -1 priority // Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() { diff --git a/patches/unapplied/server/Improve-death-events.patch b/patches/server/Improve-death-events.patch similarity index 94% rename from patches/unapplied/server/Improve-death-events.patch rename to patches/server/Improve-death-events.patch index 190a5a3a2..546f3fd86 100644 --- a/patches/unapplied/server/Improve-death-events.patch +++ b/patches/server/Improve-death-events.patch @@ -73,7 +73,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { public Set collidableExemptions = new HashSet<>(); public boolean bukkitPickUpLoot; public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper @@ -81,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public float getBukkitYaw() { -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { if (knockbackCancelled) this.level.broadcastEntityEvent(this, (byte) 2); // Paper - Disable explosion knockback if (this.isDeadOrDying()) { if (!this.checkTotemDeathProtection(source)) { @@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } else if (flag1) { this.playHurtSound(source); -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!this.isRemoved() && !this.dead) { Entity entity = damageSource.getEntity(); LivingEntity entityliving = this.getKillCredit(); @@ -108,7 +108,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.deathScore >= 0 && entityliving != null) { entityliving.awardKillScore(this, this.deathScore, damageSource); } -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!this.level.isClientSide && this.hasCustomName()) { if (org.spigotmc.SpigotConfig.logNamedDeaths) LivingEntity.LOGGER.info("Named entity {} died: {}", this, this.getCombatTracker().getDeathMessage().getString()); // Spigot } @@ -168,7 +168,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!this.level.isClientSide) { boolean flag = false; @@ -177,7 +177,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { BlockPos blockposition = this.blockPosition(); BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState(); -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { } } @@ -190,7 +190,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Entity entity = source.getEntity(); int i; -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { this.dropEquipment(); // CraftBukkit - from below if (this.shouldDropLoot() && this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { this.dropFromLootTable(source, flag); @@ -223,7 +223,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity { +@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements Targeting { } this.spawnAtLocation(itemstack); @@ -300,24 +300,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java @@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity { - this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity()); - this.lastHit = i; - } else { -- this.brokenByPlayer(source); -+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(source); // Paper - this.showBreakingParticles(); -- this.discard(); // CraftBukkit - SPIGOT-4890: remain as this.die() since above damagesource method will call death event -+ if (!event.isCancelled()) this.discard(); // CraftBukkit - SPIGOT-4890: remain as this.die() since above damagesource method will call death event // Paper - } + this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity()); + this.lastHit = i; + } else { +- this.brokenByPlayer(source); ++ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(source); // Paper + this.showBreakingParticles(); ++ if (!event.isCancelled()) // Paper + this.discard(); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event + } - return true; @@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity { } - private void brokenByPlayer(DamageSource damageSource) { -+ private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(DamageSource damageSource) { // Paper - drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(new ItemStack(Items.ARMOR_STAND))); // CraftBukkit - add to drops ++ private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(DamageSource damageSource) { // Paper + ItemStack itemstack = new ItemStack(Items.ARMOR_STAND); + + if (this.hasCustomName()) { +@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity { + } + + drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops - this.brokenByAnything(damageSource); + return this.brokenByAnything(damageSource); // Paper } diff --git a/patches/unapplied/server/Inventory-removeItemAnySlot.patch b/patches/server/Inventory-removeItemAnySlot.patch similarity index 100% rename from patches/unapplied/server/Inventory-removeItemAnySlot.patch rename to patches/server/Inventory-removeItemAnySlot.patch diff --git a/patches/unapplied/server/Limit-Client-Sign-length-more.patch b/patches/server/Limit-Client-Sign-length-more.patch similarity index 100% rename from patches/unapplied/server/Limit-Client-Sign-length-more.patch rename to patches/server/Limit-Client-Sign-length-more.patch diff --git a/patches/unapplied/server/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch b/patches/server/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch similarity index 98% rename from patches/unapplied/server/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch rename to patches/server/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch index 0807199d0..3ea74c320 100644 --- a/patches/unapplied/server/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch +++ b/patches/server/MC-50319-Check-other-worlds-for-shooter-of-projectil.patch @@ -14,7 +14,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -0,0 +0,0 @@ public abstract class Projectile extends Entity { +@@ -0,0 +0,0 @@ public abstract class Projectile extends Entity implements TraceableEntity { return this.cachedOwner; } else if (this.ownerUUID != null && this.level instanceof ServerLevel) { this.cachedOwner = ((ServerLevel) this.level).getEntity(this.ownerUUID); diff --git a/patches/unapplied/server/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch b/patches/server/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch similarity index 100% rename from patches/unapplied/server/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch rename to patches/server/Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch diff --git a/patches/unapplied/server/Make-the-default-permission-message-configurable.patch b/patches/server/Make-the-default-permission-message-configurable.patch similarity index 100% rename from patches/unapplied/server/Make-the-default-permission-message-configurable.patch rename to patches/server/Make-the-default-permission-message-configurable.patch diff --git a/patches/unapplied/server/Mob-Pathfinding-API.patch b/patches/server/Mob-Pathfinding-API.patch similarity index 100% rename from patches/unapplied/server/Mob-Pathfinding-API.patch rename to patches/server/Mob-Pathfinding-API.patch diff --git a/patches/unapplied/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch similarity index 96% rename from patches/unapplied/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch rename to patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch index 22a220595..9c6d5cc03 100644 --- a/patches/unapplied/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch +++ b/patches/server/Optimize-Network-Manager-and-add-advanced-packet-sup.patch @@ -48,8 +48,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void setProtocol(ConnectionProtocol state) { + protocol = state; // Paper this.channel.attr(Connection.ATTRIBUTE_PROTOCOL).set(state); + this.channel.attr(BundlerInfo.BUNDLER_PROVIDER).set(state); this.channel.config().setAutoRead(true); - Connection.LOGGER.debug("Enabled auto read"); @@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler> { Validate.notNull(listener, "packetListener", new Object[0]); this.packetListener = listener; @@ -354,6 +354,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } + if (!disableFlushConsolidation) channel.pipeline().addFirst(new io.netty.handler.flush.FlushConsolidationHandler()); // Paper - channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyQueryHandler(ServerConnectionListener.this)).addLast("splitter", new Varint21FrameDecoder()).addLast("decoder", new PacketDecoder(PacketFlow.SERVERBOUND)).addLast("prepender", new Varint21LengthFieldPrepender()).addLast("encoder", new PacketEncoder(PacketFlow.CLIENTBOUND)); - int j = ServerConnectionListener.this.server.getRateLimitPacketsPerSecond(); - Object object = j > 0 ? new RateKickingConnection(j) : new Connection(PacketFlow.SERVERBOUND); + ChannelPipeline channelpipeline = channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyQueryHandler(ServerConnectionListener.this)); + + Connection.configureSerialization(channelpipeline, PacketFlow.SERVERBOUND); diff --git a/patches/unapplied/server/Optimize-World-Time-Updates.patch b/patches/server/Optimize-World-Time-Updates.patch similarity index 100% rename from patches/unapplied/server/Optimize-World-Time-Updates.patch rename to patches/server/Optimize-World-Time-Updates.patch diff --git a/patches/unapplied/server/PreSpawnerSpawnEvent.patch b/patches/server/PreSpawnerSpawnEvent.patch similarity index 100% rename from patches/unapplied/server/PreSpawnerSpawnEvent.patch rename to patches/server/PreSpawnerSpawnEvent.patch diff --git a/patches/unapplied/server/Prevent-Enderman-from-loading-chunks.patch b/patches/server/Prevent-Enderman-from-loading-chunks.patch similarity index 100% rename from patches/unapplied/server/Prevent-Enderman-from-loading-chunks.patch rename to patches/server/Prevent-Enderman-from-loading-chunks.patch diff --git a/patches/unapplied/server/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch b/patches/server/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch similarity index 100% rename from patches/unapplied/server/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch rename to patches/server/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch diff --git a/patches/unapplied/server/Prevent-chunk-loading-from-Fluid-Flowing.patch b/patches/server/Prevent-chunk-loading-from-Fluid-Flowing.patch similarity index 100% rename from patches/unapplied/server/Prevent-chunk-loading-from-Fluid-Flowing.patch rename to patches/server/Prevent-chunk-loading-from-Fluid-Flowing.patch diff --git a/patches/unapplied/server/Prevent-mob-spawning-from-loading-generating-chunks.patch b/patches/server/Prevent-mob-spawning-from-loading-generating-chunks.patch similarity index 100% rename from patches/unapplied/server/Prevent-mob-spawning-from-loading-generating-chunks.patch rename to patches/server/Prevent-mob-spawning-from-loading-generating-chunks.patch diff --git a/patches/unapplied/server/Prevent-rayTrace-from-loading-chunks.patch b/patches/server/Prevent-rayTrace-from-loading-chunks.patch similarity index 100% rename from patches/unapplied/server/Prevent-rayTrace-from-loading-chunks.patch rename to patches/server/Prevent-rayTrace-from-loading-chunks.patch diff --git a/patches/unapplied/server/Reset-players-airTicks-on-respawn.patch b/patches/server/Reset-players-airTicks-on-respawn.patch similarity index 100% rename from patches/unapplied/server/Reset-players-airTicks-on-respawn.patch rename to patches/server/Reset-players-airTicks-on-respawn.patch diff --git a/patches/unapplied/server/Restore-custom-InventoryHolder-support.patch b/patches/server/Restore-custom-InventoryHolder-support.patch similarity index 100% rename from patches/unapplied/server/Restore-custom-InventoryHolder-support.patch rename to patches/server/Restore-custom-InventoryHolder-support.patch diff --git a/patches/unapplied/server/Turtle-API.patch b/patches/server/Turtle-API.patch similarity index 90% rename from patches/unapplied/server/Turtle-API.patch rename to patches/server/Turtle-API.patch index 4f7ad3ef2..1cd11d9d0 100644 --- a/patches/unapplied/server/Turtle-API.patch +++ b/patches/server/Turtle-API.patch @@ -44,11 +44,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + com.destroystokyo.paper.event.entity.TurtleLayEggEvent layEggEvent = new com.destroystokyo.paper.event.entity.TurtleLayEggEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(this.turtle.level, this.blockPos.above()), eggCount); + if (layEggEvent.callEvent() && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.turtle, this.blockPos.above(), Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount())).isCancelled()) { world.playSound((Player) null, blockposition, SoundEvents.TURTLE_LAY_EGG, SoundSource.BLOCKS, 0.3F, 0.9F + world.random.nextFloat() * 0.2F); -- world.setBlock(this.blockPos.above(), (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, this.turtle.random.nextInt(4) + 1), 3); -+ world.setBlock(this.blockPos.above(), (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount()), 3); - } - // CraftBukkit end - this.turtle.setHasEgg(false); + BlockPos blockposition1 = this.blockPos.above(); +- BlockState iblockdata = (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, this.turtle.random.nextInt(4) + 1); ++ BlockState iblockdata = (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount()); // Paper + + world.setBlock(blockposition1, iblockdata, 3); + world.gameEvent(GameEvent.BLOCK_PLACE, blockposition1, GameEvent.Context.of(this.turtle, iblockdata)); @@ -0,0 +0,0 @@ public class Turtle extends Animal { @Override diff --git a/patches/unapplied/server/Use-Vanilla-Minecart-Speeds.patch b/patches/server/Use-Vanilla-Minecart-Speeds.patch similarity index 100% rename from patches/unapplied/server/Use-Vanilla-Minecart-Speeds.patch rename to patches/server/Use-Vanilla-Minecart-Speeds.patch diff --git a/patches/unapplied/server/Workaround-for-vehicle-tracking-issue-on-disconnect.patch b/patches/server/Workaround-for-vehicle-tracking-issue-on-disconnect.patch similarity index 100% rename from patches/unapplied/server/Workaround-for-vehicle-tracking-issue-on-disconnect.patch rename to patches/server/Workaround-for-vehicle-tracking-issue-on-disconnect.patch diff --git a/patches/unapplied/server/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch b/patches/server/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch similarity index 90% rename from patches/unapplied/server/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch rename to patches/server/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch index 948779b89..a3dec08b3 100644 --- a/patches/unapplied/server/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch +++ b/patches/server/don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch @@ -9,7 +9,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -0,0 +0,0 @@ public class ItemEntity extends Entity { +@@ -0,0 +0,0 @@ public class ItemEntity extends Entity implements TraceableEntity { // CraftBukkit start - Use wall time for pickup and despawn timers int elapsedTicks = MinecraftServer.currentTick - this.lastTick; if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; @@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.age != -32768) this.age += elapsedTicks; this.lastTick = MinecraftServer.currentTick; // CraftBukkit end -@@ -0,0 +0,0 @@ public class ItemEntity extends Entity { +@@ -0,0 +0,0 @@ public class ItemEntity extends Entity implements TraceableEntity { // CraftBukkit start - Use wall time for pickup and despawn timers int elapsedTicks = MinecraftServer.currentTick - this.lastTick; if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; diff --git a/patches/unapplied/server/force-entity-dismount-during-teleportation.patch b/patches/server/force-entity-dismount-during-teleportation.patch similarity index 85% rename from patches/unapplied/server/force-entity-dismount-during-teleportation.patch rename to patches/server/force-entity-dismount-during-teleportation.patch index 90fa5cfee..f96495070 100644 --- a/patches/unapplied/server/force-entity-dismount-during-teleportation.patch +++ b/patches/server/force-entity-dismount-during-teleportation.patch @@ -19,27 +19,6 @@ this is going to be the best soultion all around. Improvements/suggestions welcome! -diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java -+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { - } - } - -- @Override -- public void stopRiding() { -+ // Paper start -+ @Override public void stopRiding() { stopRiding(false); } -+ @Override public void stopRiding(boolean suppressCancellation) { -+ // Paper end - Entity entity = this.getVehicle(); - -- super.stopRiding(); -+ super.stopRiding(suppressCancellation); // Paper - Entity entity1 = this.getVehicle(); - - if (entity1 != entity && this.connection != null) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java @@ -96,7 +75,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { @Override public void stopRiding() { diff --git a/patches/unapplied/server/Call-player-spectator-target-events-and-improve-impl.patch b/patches/unapplied/server/Call-player-spectator-target-events-and-improve-impl.patch deleted file mode 100644 index 5407982ee..000000000 --- a/patches/unapplied/server/Call-player-spectator-target-events-and-improve-impl.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Caleb Bassham -Date: Fri, 28 Sep 2018 02:32:19 -0500 -Subject: [PATCH] Call player spectator target events and improve - implementation - -Use a proper teleport for teleporting to entities in different -worlds. - -Implementation improvements authored by Spottedleaf -Validate that the target entity is valid and deny spectate -requests from frozen players. - -Also, make sure the entity is spawned to the client before -sending the camera packet. If the entity isn't spawned clientside -when it receives the camera packet, then the client will not -spectate the target entity. - -Co-authored-by: Spottedleaf - -diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java -+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { - } - - public void setCamera(@Nullable Entity entity) { -+ // Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity Event and improve implementation - Entity entity1 = this.getCamera(); - -- this.camera = (Entity) (entity == null ? this : entity); -- if (entity1 != this.camera) { -- this.connection.send(new ClientboundSetCameraPacket(this.camera)); -- this.connection.teleport(this.camera.getX(), this.camera.getY(), this.camera.getZ(), this.getYRot(), this.getXRot(), TeleportCause.SPECTATE); // CraftBukkit -- this.connection.resetPosition(); -+ if (entity == null) { -+ entity = this; - } - -+ if (entity1 == entity) return; // new spec target is the current spec target -+ -+ if (entity == this) { -+ com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent playerStopSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity()); -+ -+ if (!playerStopSpectatingEntityEvent.callEvent()) { -+ return; -+ } -+ } else { -+ com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent playerStartSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity(), entity.getBukkitEntity()); -+ -+ if (!playerStartSpectatingEntityEvent.callEvent()) { -+ return; -+ } -+ } -+ // Validate -+ if (entity != this) { -+ if (entity.isRemoved() || !entity.valid || entity.level == null) { -+ MinecraftServer.LOGGER.info("Blocking player " + this + " from spectating invalid entity " + entity); -+ return; -+ } -+ if (this.isImmobile()) { -+ // use debug: clients might maliciously spam this -+ MinecraftServer.LOGGER.debug("Blocking frozen player " + this + " from spectating entity " + entity); -+ return; -+ } -+ } -+ -+ this.camera = entity; // only set after validating state -+ -+ if (entity != this) { -+ // Make sure we're in the right place -+ this.ejectPassengers(); // teleport can fail if we have passengers... -+ this.getBukkitEntity().teleport(new Location(entity.getCommandSenderWorld().getWorld(), entity.getX(), entity.getY(), entity.getZ(), this.getYRot(), this.getXRot()), TeleportCause.SPECTATE); // Correctly handle cross-world entities from api calls by using CB teleport -+ -+ // Make sure we're tracking the entity before sending -+ ChunkMap.TrackedEntity tracker = ((ServerLevel)entity.level).getChunkSource().chunkMap.entityMap.get(entity.getId()); -+ if (tracker != null) { // dumb plugins... -+ tracker.updatePlayer(this); -+ } -+ } else { -+ this.connection.teleport(this.camera.getX(), this.camera.getY(), this.camera.getZ(), this.getYRot(), this.getXRot(), TeleportCause.SPECTATE); // CraftBukkit -+ } -+ this.connection.send(new ClientboundSetCameraPacket(entity)); -+ this.connection.resetPosition(); -+ // Paper end - } - - @Override