diff --git a/paper-server/patches/sources/net/minecraft/world/entity/item/FallingBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/item/FallingBlockEntity.java.patch new file mode 100644 index 0000000000..32fc663482 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/item/FallingBlockEntity.java.patch @@ -0,0 +1,165 @@ +--- a/net/minecraft/world/entity/item/FallingBlockEntity.java ++++ b/net/minecraft/world/entity/item/FallingBlockEntity.java +@@ -47,8 +_,14 @@ + import net.minecraft.world.phys.BlockHitResult; + import net.minecraft.world.phys.HitResult; + import net.minecraft.world.phys.Vec3; ++import org.bukkit.event.entity.CreatureSpawnEvent; + import org.slf4j.Logger; + ++// CraftBukkit start; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class FallingBlockEntity extends Entity { + private static final Logger LOGGER = LogUtils.getLogger(); + public BlockState blockState = Blocks.SAND.defaultBlockState(); +@@ -62,6 +_,7 @@ + public CompoundTag blockData; + public boolean forceTickAfterTeleportToDuplicate; + protected static final EntityDataAccessor DATA_START_POS = SynchedEntityData.defineId(FallingBlockEntity.class, EntityDataSerializers.BLOCK_POS); ++ public boolean autoExpire = true; // Paper - Expand FallingBlock API + + public FallingBlockEntity(EntityType entityType, Level level) { + super(entityType, level); +@@ -80,6 +_,10 @@ + } + + public static FallingBlockEntity fall(Level level, BlockPos pos, BlockState blockState) { ++ // CraftBukkit start ++ return FallingBlockEntity.fall(level, pos, blockState, CreatureSpawnEvent.SpawnReason.DEFAULT); ++ } ++ public static FallingBlockEntity fall(Level level, BlockPos pos, BlockState blockState, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { + FallingBlockEntity fallingBlockEntity = new FallingBlockEntity( + level, + pos.getX() + 0.5, +@@ -89,6 +_,7 @@ + ? blockState.setValue(BlockStateProperties.WATERLOGGED, Boolean.valueOf(false)) + : blockState + ); ++ if (!CraftEventFactory.callEntityChangeBlockEvent(fallingBlockEntity, pos, blockState.getFluidState().createLegacyBlock())) return fallingBlockEntity; // CraftBukkit + level.setBlock(pos, blockState.getFluidState().createLegacyBlock(), 3); + level.addFreshEntity(fallingBlockEntity); + return fallingBlockEntity; +@@ -139,13 +_,22 @@ + @Override + public void tick() { + if (this.blockState.isAir()) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else { + Block block = this.blockState.getBlock(); + this.time++; + this.applyGravity(); + this.move(MoverType.SELF, this.getDeltaMovement()); + this.applyEffectsFromBlocks(); ++ // Paper start - Configurable falling blocks height nerf ++ if (this.level().paperConfig().fixes.fallingBlockHeightNerf.test(v -> this.getY() > v)) { ++ if (this.dropItem && this.level() instanceof final ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { ++ this.spawnAtLocation(serverLevel, block); ++ } ++ this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD); ++ return; ++ } ++ // Paper end - Configurable falling blocks height nerf + this.handlePortal(); + if (this.level() instanceof ServerLevel serverLevel && (this.isAlive() || this.forceTickAfterTeleportToDuplicate)) { + BlockPos blockPos = this.blockPosition(); +@@ -166,12 +_,12 @@ + } + + if (!this.onGround() && !flag1) { +- if (this.time > 100 && (blockPos.getY() <= this.level().getMinY() || blockPos.getY() > this.level().getMaxY()) || this.time > 600) { ++ if ((this.time > 100 && autoExpire) && (blockPos.getY() <= this.level().getMinY() || blockPos.getY() > this.level().getMaxY()) || (this.time > 600 && autoExpire)) { // Paper - Expand FallingBlock API + if (this.dropItem && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { + this.spawnAtLocation(serverLevel, block); + } + +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause + } + } else { + BlockState blockState = this.level().getBlockState(blockPos); +@@ -189,12 +_,18 @@ + this.blockState = this.blockState.setValue(BlockStateProperties.WATERLOGGED, Boolean.valueOf(true)); + } + ++ // CraftBukkit start ++ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockPos, this.blockState)) { ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // SPIGOT-6586 called before the event in previous versions ++ return; ++ } ++ // CraftBukkit end + if (this.level().setBlock(blockPos, this.blockState, 3)) { + ((ServerLevel)this.level()) + .getChunkSource() + .chunkMap + .broadcast(this, new ClientboundBlockUpdatePacket(blockPos, this.level().getBlockState(blockPos))); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + if (block instanceof Fallable) { + ((Fallable)block).onLand(this.level(), blockPos, this.blockState, blockState, this); + } +@@ -218,19 +_,19 @@ + } + } + } else if (this.dropItem && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause + this.callOnBrokenAfterFall(block, blockPos); + this.spawnAtLocation(serverLevel, block); + } + } else { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause + if (this.dropItem && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { + this.callOnBrokenAfterFall(block, blockPos); + this.spawnAtLocation(serverLevel, block); + } + } + } else { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + this.callOnBrokenAfterFall(block, blockPos); + } + } +@@ -290,6 +_,7 @@ + } + + compound.putBoolean("CancelDrop", this.cancelDrop); ++ if (!autoExpire) {compound.putBoolean("Paper.AutoExpire", false);} // Paper - Expand FallingBlock API + } + + @Override +@@ -308,7 +_,7 @@ + this.dropItem = compound.getBoolean("DropItem"); + } + +- if (compound.contains("TileEntityData", 10)) { ++ if (compound.contains("TileEntityData", 10) && !(this.level().paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock)) { // Paper - Filter bad block entity nbt data from falling blocks + this.blockData = compound.getCompound("TileEntityData").copy(); + } + +@@ -316,6 +_,12 @@ + if (this.blockState.isAir()) { + this.blockState = Blocks.SAND.defaultBlockState(); + } ++ ++ // Paper start - Expand FallingBlock API ++ if (compound.contains("Paper.AutoExpire")) { ++ this.autoExpire = compound.getBoolean("Paper.AutoExpire"); ++ } ++ // Paper end - Expand FallingBlock API + } + + public void setHurtsEntities(float fallDamagePerDistance, int fallDamageMax) { +@@ -372,7 +_,7 @@ + ResourceKey resourceKey1 = this.level().dimension(); + boolean flag = (resourceKey1 == Level.END || resourceKey == Level.END) && resourceKey1 != resourceKey; + Entity entity = super.teleport(teleportTransition); +- this.forceTickAfterTeleportToDuplicate = entity != null && flag; ++ this.forceTickAfterTeleportToDuplicate = entity != null && flag && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation; // Paper + return entity; + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/item/ItemEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch similarity index 64% rename from paper-server/patches/unapplied/net/minecraft/world/entity/item/ItemEntity.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch index 0bc136847c..0eecee5ed4 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/item/ItemEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/item/ItemEntity.java +++ b/net/minecraft/world/entity/item/ItemEntity.java -@@ -5,18 +5,6 @@ +@@ -3,18 +_,6 @@ import java.util.Objects; import java.util.UUID; import javax.annotation.Nullable; @@ -19,7 +19,7 @@ import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -@@ -24,7 +12,6 @@ +@@ -22,7 +_,6 @@ import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.SlotAccess; import net.minecraft.world.entity.TraceableEntity; @@ -27,7 +27,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Explosion; -@@ -33,6 +20,27 @@ +@@ -31,6 +_,27 @@ import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.portal.TeleportTransition; import net.minecraft.world.phys.Vec3; @@ -54,33 +54,32 @@ +import org.bukkit.event.player.PlayerAttemptPickupItemEvent; // Paper public class ItemEntity extends Entity implements TraceableEntity { - -@@ -52,6 +60,10 @@ + private static final EntityDataAccessor DATA_ITEM = SynchedEntityData.defineId(ItemEntity.class, EntityDataSerializers.ITEM_STACK); +@@ -49,6 +_,9 @@ @Nullable public UUID target; public final float bobOffs; -+ // private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit // Paper - remove anti tick skipping measures / wall time + public boolean canMobPickup = true; // Paper - Item#canEntityPickup + private int despawnRate = -1; // Paper - Alternative item-despawn-rate + public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API - public ItemEntity(EntityType type, Level world) { - super(type, world); -@@ -61,7 +73,12 @@ + public ItemEntity(EntityType entityType, Level level) { + super(entityType, level); +@@ -57,7 +_,12 @@ } - public ItemEntity(Level world, double x, double y, double z, ItemStack stack) { -- this(world, x, y, z, stack, world.random.nextDouble() * 0.2D - 0.1D, 0.2D, world.random.nextDouble() * 0.2D - 0.1D); + public ItemEntity(Level level, double posX, double posY, double posZ, ItemStack itemStack) { +- this(level, posX, posY, posZ, itemStack, level.random.nextDouble() * 0.2 - 0.1, 0.2, level.random.nextDouble() * 0.2 - 0.1); + // Paper start - Don't use level random in entity constructors (to make them thread-safe) -+ this(EntityType.ITEM, world); -+ this.setPos(x, y, z); ++ this(EntityType.ITEM, level); ++ this.setPos(posX, posY, posZ); + this.setDeltaMovement(this.random.nextDouble() * 0.2D - 0.1D, 0.2D, this.random.nextDouble() * 0.2D - 0.1D); -+ this.setItem(stack); ++ this.setItem(itemStack); + // Paper end - Don't use level random in entity constructors } - public ItemEntity(Level world, double x, double y, double z, ItemStack stack, double velocityX, double velocityY, double velocityZ) { -@@ -133,12 +150,14 @@ + public ItemEntity(Level level, double posX, double posY, double posZ, ItemStack itemStack, double deltaX, double deltaY, double deltaZ) { +@@ -119,7 +_,7 @@ @Override public void tick() { if (this.getItem().isEmpty()) { @@ -88,24 +87,16 @@ + this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else { super.tick(); -+ // Paper start - remove anti tick skipping measures / wall time - revert to vanilla if (this.pickupDelay > 0 && this.pickupDelay != 32767) { - --this.pickupDelay; - } -+ // Paper end - remove anti tick skipping measures / wall time - revert to vanilla - - this.xo = this.getX(); - this.yo = this.getY(); -@@ -162,12 +181,16 @@ +@@ -147,11 +_,15 @@ } } -- if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { -+ if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { // Paper - Diff on change; ActivationRange immunity +- if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 1.0E-5F || (this.tickCount + this.getId()) % 4 == 0) { ++ if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 1.0E-5F || (this.tickCount + this.getId()) % 4 == 0) { // Paper - Diff on change; ActivationRange immunity this.move(MoverType.SELF, this.getDeltaMovement()); this.applyEffectsFromBlocks(); float f = 0.98F; - - if (this.onGround()) { + // Paper start - Friction API + if (frictionState == net.kyori.adventure.util.TriState.FALSE) { @@ -115,24 +106,15 @@ f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F; } -@@ -188,9 +211,11 @@ - this.mergeWithNeighbours(); - } - -+ // Paper - remove anti tick skipping measures / wall time - revert to vanilla /* CraftBukkit start - moved up - if (this.age != -32768) { - ++this.age; - } -+ // CraftBukkit end */ - - this.hasImpulse |= this.updateInWaterStateAndDoFluidPushing(); - if (!this.level().isClientSide) { -@@ -201,14 +226,44 @@ +@@ -184,11 +_,42 @@ } } - if (!this.level().isClientSide && this.age >= 6000) { - this.discard(); +- } +- } +- } + if (!this.level().isClientSide && this.age >= this.despawnRate) { // Spigot // Paper - Alternative item-despawn-rate + // CraftBukkit start - fire ItemDespawnEvent + if (CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { @@ -141,13 +123,12 @@ + } + // CraftBukkit end + this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause - } - - } - } - ++ } ++ } ++ } ++ + // Spigot start - copied from above - @Override ++ @Override + public void inactiveTick() { + // Paper start - remove anti tick skipping measures / wall time - copied from above + if (this.pickupDelay > 0 && this.pickupDelay != 32767) { @@ -170,85 +151,76 @@ + } + // Spigot end + -+ @Override + + @Override public BlockPos getBlockPosBelowThatAffectsMyMovement() { - return this.getOnPos(0.999999F); - } -@@ -229,7 +284,10 @@ +@@ -210,9 +_,18 @@ private void mergeWithNeighbours() { if (this.isMergable()) { -- List list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(0.5D, 0.0D, 0.5D), (entityitem) -> { -+ // Spigot start -+ double radius = this.level().spigotConfig.itemMerge; -+ List list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, this.level().paperConfig().entities.behavior.onlyMergeItemsHorizontally ? 0 : radius - 0.5D, radius), (entityitem) -> { // Paper - configuration to only merge items horizontally -+ // Spigot end - return entityitem != this && entityitem.isMergable(); - }); - Iterator iterator = list.iterator(); -@@ -238,6 +296,14 @@ - ItemEntity entityitem = (ItemEntity) iterator.next(); - - if (entityitem.isMergable()) { ++ double radius = this.level().spigotConfig.itemMerge; // Spigot + for (ItemEntity itemEntity : this.level() +- .getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(0.5, 0.0, 0.5), neighbour -> neighbour != this && neighbour.isMergable())) { ++ .getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, this.level().paperConfig().entities.behavior.onlyMergeItemsHorizontally ? 0 : radius - 0.5D, radius), neighbour -> neighbour != this && neighbour.isMergable())) { // Spigot // Paper - configuration to only merge items horizontally + if (itemEntity.isMergable()) { + // Paper start - Fix items merging through walls + if (this.level().paperConfig().fixes.fixItemsMergingThroughWalls) { -+ if (this.level().clipDirect(this.position(), entityitem.position(), ++ if (this.level().clipDirect(this.position(), itemEntity.position(), + net.minecraft.world.phys.shapes.CollisionContext.of(this)) == net.minecraft.world.phys.HitResult.Type.BLOCK) { + continue; + } + } + // Paper end - Fix items merging through walls - this.tryToMerge(entityitem); + this.tryToMerge(itemEntity); if (this.isRemoved()) { break; -@@ -251,7 +317,7 @@ +@@ -224,14 +_,14 @@ + private boolean isMergable() { - ItemStack itemstack = this.getItem(); - -- return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < 6000 && itemstack.getCount() < itemstack.getMaxStackSize(); -+ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && itemstack.getCount() < itemstack.getMaxStackSize(); // Paper - Alternative item-despawn-rate + ItemStack item = this.getItem(); +- return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < 6000 && item.getCount() < item.getMaxStackSize(); ++ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < item.getMaxStackSize(); // Paper - Alternative item-despawn-rate } - private void tryToMerge(ItemEntity other) { -@@ -259,7 +325,7 @@ - ItemStack itemstack1 = other.getItem(); - - if (Objects.equals(this.target, other.target) && ItemEntity.areMergable(itemstack, itemstack1)) { -- if (itemstack1.getCount() < itemstack.getCount()) { -+ if (true || itemstack1.getCount() < itemstack.getCount()) { // Spigot - ItemEntity.merge(this, itemstack, other, itemstack1); + private void tryToMerge(ItemEntity itemEntity) { + ItemStack item = this.getItem(); + ItemStack item1 = itemEntity.getItem(); + if (Objects.equals(this.target, itemEntity.target) && areMergable(item, item1)) { +- if (item1.getCount() < item.getCount()) { ++ if (true || item1.getCount() < item.getCount()) { // Spigot + merge(this, item, itemEntity, item1); } else { - ItemEntity.merge(other, itemstack1, this, itemstack); -@@ -287,11 +353,16 @@ + merge(itemEntity, item1, this, item); +@@ -257,11 +_,16 @@ } - private static void merge(ItemEntity targetEntity, ItemStack targetStack, ItemEntity sourceEntity, ItemStack sourceStack) { + private static void merge(ItemEntity destinationEntity, ItemStack destinationStack, ItemEntity originEntity, ItemStack originStack) { + // CraftBukkit start -+ if (!CraftEventFactory.callItemMergeEvent(sourceEntity, targetEntity)) { ++ if (!CraftEventFactory.callItemMergeEvent(originEntity, destinationEntity)) { + return; + } + // CraftBukkit end - ItemEntity.merge(targetEntity, targetStack, sourceStack); - targetEntity.pickupDelay = Math.max(targetEntity.pickupDelay, sourceEntity.pickupDelay); - targetEntity.age = Math.min(targetEntity.age, sourceEntity.age); - if (sourceStack.isEmpty()) { -- sourceEntity.discard(); -+ sourceEntity.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause); + merge(destinationEntity, destinationStack, originStack); + destinationEntity.pickupDelay = Math.max(destinationEntity.pickupDelay, originEntity.pickupDelay); + destinationEntity.age = Math.min(destinationEntity.age, originEntity.age); + if (originStack.isEmpty()) { +- originEntity.discard(); ++ originEntity.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause } - } -@@ -320,12 +391,17 @@ - } else if (!this.getItem().canBeHurtBy(source)) { + +@@ -289,12 +_,17 @@ + } else if (!this.getItem().canBeHurtBy(damageSource)) { return false; } else { + // CraftBukkit start -+ if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, source, amount)) { ++ if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, damageSource, amount)) { + return false; + } + // CraftBukkit end this.markHurt(); - this.health = (int) ((float) this.health - amount); - this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity()); + this.health = (int)(this.health - amount); + this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity()); if (this.health <= 0) { this.getItem().onDestroyed(this); - this.discard(); @@ -256,25 +228,25 @@ } return true; -@@ -339,6 +415,11 @@ +@@ -308,6 +_,11 @@ @Override - public void addAdditionalSaveData(CompoundTag nbt) { + public void addAdditionalSaveData(CompoundTag compound) { + // Paper start - Friction API + if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) { -+ nbt.putString("Paper.FrictionState", this.frictionState.toString()); ++ compound.putString("Paper.FrictionState", this.frictionState.toString()); + } + // Paper end - Friction API - nbt.putShort("Health", (short) this.health); - nbt.putShort("Age", (short) this.age); - nbt.putShort("PickupDelay", (short) this.pickupDelay); -@@ -381,23 +462,98 @@ + compound.putShort("Health", (short)this.health); + compound.putShort("Age", (short)this.age); + compound.putShort("PickupDelay", (short)this.pickupDelay); +@@ -347,22 +_,95 @@ + } else { this.setItem(ItemStack.EMPTY); } - + // Paper start - Friction API -+ if (nbt.contains("Paper.FrictionState")) { -+ String fs = nbt.getString("Paper.FrictionState"); ++ if (compound.contains("Paper.FrictionState")) { ++ String fs = compound.getString("Paper.FrictionState"); + try { + frictionState = net.kyori.adventure.util.TriState.valueOf(fs); + } catch (Exception ignored) { @@ -282,75 +254,72 @@ + } + } + // Paper end - Friction API -+ + if (this.getItem().isEmpty()) { - this.discard(); -+ this.discard(null); // CraftBukkit - add Bukkit remove cause ++ this.discard(null); // CraftBukkit - add Bukkit remove cause } - } @Override -- public void playerTouch(Player player) { -+ public void playerTouch(net.minecraft.world.entity.player.Player player) { +- public void playerTouch(Player entity) { ++ public void playerTouch(net.minecraft.world.entity.player.Player entity) { if (!this.level().isClientSide) { - ItemStack itemstack = this.getItem(); - Item item = itemstack.getItem(); - int i = itemstack.getCount(); -+ + ItemStack item = this.getItem(); + Item item1 = item.getItem(); + int count = item.getCount(); + // CraftBukkit start - fire PlayerPickupItemEvent -+ int canHold = player.getInventory().canHold(itemstack); -+ int remaining = i - canHold; ++ int canHold = entity.getInventory().canHold(item); ++ int remaining = count - canHold; + boolean flyAtPlayer = false; // Paper + + // Paper start - PlayerAttemptPickupItemEvent + if (this.pickupDelay <= 0) { -+ PlayerAttemptPickupItemEvent attemptEvent = new PlayerAttemptPickupItemEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); ++ PlayerAttemptPickupItemEvent attemptEvent = new PlayerAttemptPickupItemEvent((org.bukkit.entity.Player) entity.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); + this.level().getCraftServer().getPluginManager().callEvent(attemptEvent); + + flyAtPlayer = attemptEvent.getFlyAtPlayer(); + if (attemptEvent.isCancelled()) { + if (flyAtPlayer) { -+ player.take(this, i); ++ entity.take(this, count); + } + + return; + } + } -+ // Paper end - PlayerAttemptPickupItemEvent - ++ + if (this.pickupDelay <= 0 && canHold > 0) { -+ itemstack.setCount(canHold); ++ item.setCount(canHold); + // Call legacy event -+ PlayerPickupItemEvent playerEvent = new PlayerPickupItemEvent((Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); ++ PlayerPickupItemEvent playerEvent = new PlayerPickupItemEvent((Player) entity.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); + playerEvent.setCancelled(!playerEvent.getPlayer().getCanPickupItems()); + this.level().getCraftServer().getPluginManager().callEvent(playerEvent); + flyAtPlayer = playerEvent.getFlyAtPlayer(); // Paper + if (playerEvent.isCancelled()) { -+ itemstack.setCount(i); // SPIGOT-5294 - restore count ++ item.setCount(count); // SPIGOT-5294 - restore count + // Paper start + if (flyAtPlayer) { -+ player.take(this, i); ++ entity.take(this, count); + } + // Paper end + return; + } + + // Call newer event afterwards -+ EntityPickupItemEvent entityEvent = new EntityPickupItemEvent((Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); ++ EntityPickupItemEvent entityEvent = new EntityPickupItemEvent((Player) entity.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); + entityEvent.setCancelled(!entityEvent.getEntity().getCanPickupItems()); + this.level().getCraftServer().getPluginManager().callEvent(entityEvent); + if (entityEvent.isCancelled()) { -+ itemstack.setCount(i); // SPIGOT-5294 - restore count ++ item.setCount(count); // SPIGOT-5294 - restore count + return; + } + + // Update the ItemStack if it was changed in the event + ItemStack current = this.getItem(); -+ if (!itemstack.equals(current)) { -+ itemstack = current; ++ if (!item.equals(current)) { ++ item = current; + } else { -+ itemstack.setCount(canHold + remaining); // = i ++ item.setCount(canHold + remaining); // = i + } + + // Possibly < 0; fix here so we do not have to modify code below @@ -360,25 +329,25 @@ + this.pickupDelay = -1; + } + // CraftBukkit end -+ - if (this.pickupDelay == 0 && (this.target == null || this.target.equals(player.getUUID())) && player.getInventory().add(itemstack)) { ++ // Paper end - PlayerAttemptPickupItemEvent + if (this.pickupDelay == 0 && (this.target == null || this.target.equals(entity.getUUID())) && entity.getInventory().add(item)) { + if (flyAtPlayer) // Paper - PlayerPickupItemEvent - player.take(this, i); - if (itemstack.isEmpty()) { + entity.take(this, count); + if (item.isEmpty()) { - this.discard(); + this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause - itemstack.setCount(i); + item.setCount(count); } -@@ -438,6 +594,7 @@ +@@ -400,6 +_,7 @@ public void setItem(ItemStack stack) { - this.getEntityData().set(ItemEntity.DATA_ITEM, stack); + this.getEntityData().set(DATA_ITEM, stack); + this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate } @Override -@@ -492,7 +649,7 @@ +@@ -453,7 +_,7 @@ public void makeFakeItem() { this.setNeverPickUp(); @@ -386,4 +355,4 @@ + this.age = this.despawnRate - 1; // Spigot // Paper - Alternative item-despawn-rate } - public static float getSpin(float f, float f1) { + public static float getSpin(float age, float bobOffset) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/item/PrimedTnt.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/item/PrimedTnt.java.patch similarity index 73% rename from paper-server/patches/unapplied/net/minecraft/world/entity/item/PrimedTnt.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/item/PrimedTnt.java.patch index 1120fe2bdf..49714990c2 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/item/PrimedTnt.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/item/PrimedTnt.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/item/PrimedTnt.java +++ b/net/minecraft/world/entity/item/PrimedTnt.java -@@ -27,6 +27,12 @@ +@@ -27,6 +_,12 @@ import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.portal.TeleportTransition; @@ -11,26 +11,26 @@ +// CraftBukkit end + public class PrimedTnt extends Entity implements TraceableEntity { - private static final EntityDataAccessor DATA_FUSE_ID = SynchedEntityData.defineId(PrimedTnt.class, EntityDataSerializers.INT); -@@ -51,6 +57,7 @@ + private static final EntityDataAccessor DATA_BLOCK_STATE_ID = SynchedEntityData.defineId(PrimedTnt.class, EntityDataSerializers.BLOCK_STATE); +@@ -50,6 +_,7 @@ public LivingEntity owner; private boolean usedPortal; - public float explosionPower; + public float explosionPower = 4.0F; + public boolean isIncendiary = false; // CraftBukkit - add field - public PrimedTnt(EntityType type, Level world) { - super(type, world); -@@ -61,7 +68,7 @@ - public PrimedTnt(Level world, double x, double y, double z, @Nullable LivingEntity igniter) { - this(EntityType.TNT, world); + public PrimedTnt(EntityType entityType, Level level) { + super(entityType, level); +@@ -59,7 +_,7 @@ + public PrimedTnt(Level level, double x, double y, double z, @Nullable LivingEntity owner) { + this(EntityType.TNT, level); this.setPos(x, y, z); -- double d3 = world.random.nextDouble() * 6.2831854820251465D; -+ double d3 = this.random.nextDouble() * 6.2831854820251465D; // Paper - Don't use level random in entity constructors - - this.setDeltaMovement(-Math.sin(d3) * 0.02D, 0.20000000298023224D, -Math.cos(d3) * 0.02D); +- double d = level.random.nextDouble() * (float) (Math.PI * 2); ++ double d = this.random.nextDouble() * (float) (Math.PI * 2); // Paper - Don't use level random in entity constructors + this.setDeltaMovement(-Math.sin(d) * 0.02, 0.2F, -Math.cos(d) * 0.02); this.setFuse(80); -@@ -94,10 +101,17 @@ + this.xo = x; +@@ -91,10 +_,17 @@ @Override public void tick() { @@ -45,16 +45,16 @@ + return; + } + // Paper end - Configurable TNT height nerf - this.setDeltaMovement(this.getDeltaMovement().scale(0.98D)); + this.setDeltaMovement(this.getDeltaMovement().scale(0.98)); if (this.onGround()) { - this.setDeltaMovement(this.getDeltaMovement().multiply(0.7D, -0.5D, 0.7D)); -@@ -107,10 +121,13 @@ - + this.setDeltaMovement(this.getDeltaMovement().multiply(0.7, -0.5, 0.7)); +@@ -103,19 +_,49 @@ + int i = this.getFuse() - 1; this.setFuse(i); if (i <= 0) { - this.discard(); + // CraftBukkit start - Need to reverse the order of the explosion and the entity death so we have a location for the event -+ // this.discard(); ++ //this.discard(); if (!this.level().isClientSide) { this.explode(); } @@ -63,10 +63,9 @@ } else { this.updateInWaterStateAndDoFluidPushing(); if (this.level().isClientSide) { -@@ -118,10 +135,37 @@ + this.level().addParticle(ParticleTypes.SMOKE, this.getX(), this.getY() + 0.5, this.getZ(), 0.0, 0.0, 0.0); } } - + // Paper start - Option to prevent TNT from moving in water + if (!this.isRemoved() && this.wasTouchingWater && this.level().paperConfig().fixes.preventTntFromMovingInWater) { + /* @@ -91,19 +90,28 @@ } private void explode() { -- this.level().explode(this, Explosion.getDefaultDamageSource(this.level(), this), this.usedPortal ? PrimedTnt.USED_PORTAL_DAMAGE_CALCULATOR : null, this.getX(), this.getY(0.0625D), this.getZ(), this.explosionPower, false, Level.ExplosionInteraction.TNT); + // CraftBukkit start + ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity()); + if (event.isCancelled()) { + return; + } -+ this.level().explode(this, Explosion.getDefaultDamageSource(this.level(), this), this.usedPortal ? PrimedTnt.USED_PORTAL_DAMAGE_CALCULATOR : null, this.getX(), this.getY(0.0625D), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.TNT); -+ // CraftBukkit end ++ // Craftbukkit end + this.level() + .explode( + this, +@@ -124,8 +_,8 @@ + this.getX(), + this.getY(0.0625), + this.getZ(), +- this.explosionPower, +- false, ++ event.getRadius(), // CraftBukkit ++ event.getFire(), // CraftBukkit + Level.ExplosionInteraction.TNT + ); } - - @Override -@@ -198,4 +242,11 @@ - public final boolean hurtServer(ServerLevel world, DamageSource source, float amount) { +@@ -200,4 +_,11 @@ + public final boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) { return false; } + diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/item/FallingBlockEntity.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/item/FallingBlockEntity.java.patch deleted file mode 100644 index 8f36430b05..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/item/FallingBlockEntity.java.patch +++ /dev/null @@ -1,162 +0,0 @@ ---- a/net/minecraft/world/entity/item/FallingBlockEntity.java -+++ b/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -52,6 +52,11 @@ - import net.minecraft.world.phys.Vec3; - import org.slf4j.Logger; - -+// CraftBukkit start; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityRemoveEvent; -+// CraftBukkit end -+ - public class FallingBlockEntity extends Entity { - - private static final Logger LOGGER = LogUtils.getLogger(); -@@ -66,6 +71,7 @@ - public CompoundTag blockData; - public boolean forceTickAfterTeleportToDuplicate; - protected static final EntityDataAccessor DATA_START_POS = SynchedEntityData.defineId(FallingBlockEntity.class, EntityDataSerializers.BLOCK_POS); -+ public boolean autoExpire = true; // Paper - Expand FallingBlock API - - public FallingBlockEntity(EntityType type, Level world) { - super(type, world); -@@ -87,10 +93,17 @@ - } - - public static FallingBlockEntity fall(Level world, BlockPos pos, BlockState state) { -- FallingBlockEntity entityfallingblock = new FallingBlockEntity(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, state.hasProperty(BlockStateProperties.WATERLOGGED) ? (BlockState) state.setValue(BlockStateProperties.WATERLOGGED, false) : state); -+ // CraftBukkit start -+ return FallingBlockEntity.fall(world, pos, state, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); -+ } - -- world.setBlock(pos, state.getFluidState().createLegacyBlock(), 3); -- world.addFreshEntity(entityfallingblock); -+ public static FallingBlockEntity fall(Level world, BlockPos blockposition, BlockState iblockdata, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { -+ // CraftBukkit end -+ FallingBlockEntity entityfallingblock = new FallingBlockEntity(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, iblockdata.hasProperty(BlockStateProperties.WATERLOGGED) ? (BlockState) iblockdata.setValue(BlockStateProperties.WATERLOGGED, false) : iblockdata); -+ if (!CraftEventFactory.callEntityChangeBlockEvent(entityfallingblock, blockposition, iblockdata.getFluidState().createLegacyBlock())) return entityfallingblock; // CraftBukkit -+ -+ world.setBlock(blockposition, iblockdata.getFluidState().createLegacyBlock(), 3); -+ world.addFreshEntity(entityfallingblock, spawnReason); // CraftBukkit - return entityfallingblock; - } - -@@ -139,7 +152,7 @@ - @Override - public void tick() { - if (this.blockState.isAir()) { -- this.discard(); -+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause - } else { - Block block = this.blockState.getBlock(); - -@@ -147,6 +160,16 @@ - this.applyGravity(); - this.move(MoverType.SELF, this.getDeltaMovement()); - this.applyEffectsFromBlocks(); -+ // Paper start - Configurable falling blocks height nerf -+ if (this.level().paperConfig().fixes.fallingBlockHeightNerf.test(v -> this.getY() > v)) { -+ if (this.dropItem && this.level() instanceof final ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { -+ this.spawnAtLocation(serverLevel, block); -+ } -+ -+ this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD); -+ return; -+ } -+ // Paper end - Configurable falling blocks height nerf - this.handlePortal(); - Level world = this.level(); - -@@ -169,12 +192,12 @@ - } - - if (!this.onGround() && !flag1) { -- if (this.time > 100 && (blockposition.getY() <= this.level().getMinY() || blockposition.getY() > this.level().getMaxY()) || this.time > 600) { -+ if ((this.time > 100 && autoExpire) && (blockposition.getY() <= this.level().getMinY() || blockposition.getY() > this.level().getMaxY()) || (this.time > 600 && autoExpire)) { // Paper - Expand FallingBlock API - if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { - this.spawnAtLocation(worldserver, (ItemLike) block); - } - -- this.discard(); -+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause - } - } else { - BlockState iblockdata = this.level().getBlockState(blockposition); -@@ -191,9 +214,15 @@ - this.blockState = (BlockState) this.blockState.setValue(BlockStateProperties.WATERLOGGED, true); - } - -+ // CraftBukkit start -+ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, this.blockState)) { -+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // SPIGOT-6586 called before the event in previous versions -+ return; -+ } -+ // CraftBukkit end - if (this.level().setBlock(blockposition, this.blockState, 3)) { - ((ServerLevel) this.level()).getChunkSource().chunkMap.broadcast(this, new ClientboundBlockUpdatePacket(blockposition, this.level().getBlockState(blockposition))); -- this.discard(); -+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause - if (block instanceof Fallable) { - ((Fallable) block).onLand(this.level(), blockposition, this.blockState, iblockdata, this); - } -@@ -221,19 +250,19 @@ - } - } - } else if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { -- this.discard(); -+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause - this.callOnBrokenAfterFall(block, blockposition); - this.spawnAtLocation(worldserver, (ItemLike) block); - } - } else { -- this.discard(); -+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause - if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { - this.callOnBrokenAfterFall(block, blockposition); - this.spawnAtLocation(worldserver, (ItemLike) block); - } - } - } else { -- this.discard(); -+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause - this.callOnBrokenAfterFall(block, blockposition); - } - } -@@ -310,6 +339,7 @@ - } - - nbt.putBoolean("CancelDrop", this.cancelDrop); -+ if (!autoExpire) {nbt.putBoolean("Paper.AutoExpire", false);} // Paper - Expand FallingBlock API - } - - @Override -@@ -328,7 +358,7 @@ - this.dropItem = nbt.getBoolean("DropItem"); - } - -- if (nbt.contains("TileEntityData", 10)) { -+ if (nbt.contains("TileEntityData", 10) && !(this.level().paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock)) { // Paper - Filter bad block entity nbt data from falling blocks - this.blockData = nbt.getCompound("TileEntityData").copy(); - } - -@@ -337,6 +367,11 @@ - this.blockState = Blocks.SAND.defaultBlockState(); - } - -+ // Paper start - Expand FallingBlock API -+ if (nbt.contains("Paper.AutoExpire")) { -+ this.autoExpire = nbt.getBoolean("Paper.AutoExpire"); -+ } -+ // Paper end - Expand FallingBlock API - } - - public void setHurtsEntities(float fallHurtAmount, int fallHurtMax) { -@@ -395,7 +430,7 @@ - boolean flag = (resourcekey1 == Level.END || resourcekey == Level.END) && resourcekey1 != resourcekey; - Entity entity = super.teleport(teleportTarget); - -- this.forceTickAfterTeleportToDuplicate = entity != null && flag; -+ this.forceTickAfterTeleportToDuplicate = entity != null && flag && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation; // Paper - return entity; - } - }