diff --git a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch index 1fd2cae77f..6608a2eae4 100644 --- a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -205,7 +205,7 @@ try { - this.getConnection().startTcpServerListener(inetAddress, this.getPort()); -+ this.getConnection().bind(bindAddress); // Paper - Unix domain socket support ++ this.getConnection().startTcpServerListener(bindAddress); // Paper - Unix domain socket support } catch (IOException var10) { LOGGER.warn("**** FAILED TO BIND TO PORT!"); LOGGER.warn("The exception was: {}", var10.toString()); diff --git a/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch index 559aabf756..6ce77e18f7 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch @@ -196,7 +196,7 @@ - return this.upgradeChunkTag(this.level.dimension(), this.overworldDataStorage, tag, this.generator().getTypeNameForDataFixer()); + // CraftBukkit start + private CompoundTag upgradeChunkTag(CompoundTag tag, ChunkPos pos) { -+ return this.upgradeChunkTag(this.level.dimension(), this.overworldDataStorage, tag, this.generator().getTypeNameForDataFixer(), pos, this.level); ++ return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, tag, this.generator().getTypeNameForDataFixer(), pos, this.level); + // CraftBukkit end } diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch index 5f558ccc4a..7d5ee65f78 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch @@ -172,7 +172,7 @@ this.distanceManager.purgeStaleTickets(); } -@@ -400,11 +_,19 @@ +@@ -400,12 +_,20 @@ ); this.lastSpawnState = spawnState; profiler.popPush("spawnAndTick"); @@ -182,6 +182,7 @@ List filteredSpawningCategories; if (_boolean && (this.spawnEnemies || this.spawnFriendlies)) { - boolean flag = this.level.getLevelData().getGameTime() % 400L == 0L; +- filteredSpawningCategories = NaturalSpawner.getFilteredSpawningCategories(spawnState, this.spawnFriendlies, this.spawnEnemies, flag); + // Paper start - PlayerNaturallySpawnCreaturesEvent + for (ServerPlayer entityPlayer : this.level.players()) { + int chunkRange = Math.min(level.spigotConfig.mobSpawnRange, entityPlayer.getBukkitEntity().getViewDistance()); @@ -191,9 +192,10 @@ + } + // Paper end - PlayerNaturallySpawnCreaturesEvent + boolean flag = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit - filteredSpawningCategories = NaturalSpawner.getFilteredSpawningCategories(spawnState, this.spawnFriendlies, this.spawnEnemies, flag); ++ filteredSpawningCategories = NaturalSpawner.getFilteredSpawningCategories(spawnState, this.spawnFriendlies, this.spawnEnemies, flag, this.level); // CraftBukkit } else { filteredSpawningCategories = List.of(); + } @@ -413,7 +_,7 @@ for (LevelChunk levelChunk : chunks) { ChunkPos pos = levelChunk.getPos(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch index 3670fec552..6e9bf95ddf 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch @@ -217,7 +217,7 @@ + this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { - Entity nearestPlayer = this.level().getNearestPlayer(this, -1.0); -+ Entity nearestPlayer = this.level().getNearestPlayer(this, -1.0, EntitySelector.PLAYER_AFFECTS_SPAWNING); // Paper - Affects Spawning API ++ Entity nearestPlayer = this.level().findNearbyPlayer(this, -1.0, EntitySelector.PLAYER_AFFECTS_SPAWNING); // Paper - Affects Spawning API if (nearestPlayer != null) { - double d = nearestPlayer.distanceToSqr(this); - int despawnDistance = this.getType().getCategory().getDespawnDistance(); @@ -320,7 +320,7 @@ this.setItemSlot(equipmentSlot, ItemStack.EMPTY); + // Paper start + } else { -+ this.clearedEquipmentSlots.add(enumitemslot); ++ this.clearedEquipmentSlots.add(equipmentSlot); + } + // Paper end } @@ -338,7 +338,7 @@ + EntityType entityType, ConversionParams conversionParams, EntitySpawnReason spawnReason, ConversionParams.AfterConversion afterConversion, EntityTransformEvent.TransformReason transformReason, CreatureSpawnEvent.SpawnReason creatureSpawnReason + ) { + // Paper start - entity zap event - allow cancellation of conversion post creation -+ return this.convertTo(entityType, conversionParams, spawnReason, e -> { afterConversion.finalizeConversion(e); return true; }, transformReason, spawnReason); ++ return this.convertTo(entityType, conversionParams, spawnReason, e -> { afterConversion.finalizeConversion(e); return true; }, transformReason, creatureSpawnReason); + } + @Nullable + public T convertTo( diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch index 01deda0a89..f475fefe0a 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch @@ -14,7 +14,7 @@ DyeColor dyeColor = dyeItem.getDyeColor(); if (dyeColor != this.getCollarColor()) { + // Paper start - Add EntityDyeEvent and CollarColorable interface -+ final io.papermc.paper.event.entity.EntityDyeEvent event = new io.papermc.paper.event.entity.EntityDyeEvent(this.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData((byte) enumcolor.getId()), ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity()); ++ final io.papermc.paper.event.entity.EntityDyeEvent event = new io.papermc.paper.event.entity.EntityDyeEvent(this.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData((byte) dyeColor.getId()), ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity()); + if (!event.callEvent()) return InteractionResult.FAIL; + dyeColor = DyeColor.byId(event.getColor().getWoolData()); + // Paper end - Add EntityDyeEvent and CollarColorable interface diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch index c8bd9cb88e..a5059e85d7 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cow.java.patch @@ -5,7 +5,7 @@ ItemStack itemInHand = player.getItemInHand(hand); if (itemInHand.is(Items.BUCKET) && !this.isBaby()) { + // CraftBukkit start - Got milk? -+ org.bukkit.event.player.PlayerBucketFillEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); ++ org.bukkit.event.player.PlayerBucketFillEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemInHand, Items.MILK_BUCKET, hand); + if (event.isCancelled()) { + player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + return InteractionResult.PASS; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch index 95199daa53..28a059aba2 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch @@ -13,19 +13,20 @@ this.scuteTime = this.pickNextScuteDropTime(); } -@@ -283,7 +_,11 @@ +@@ -283,8 +_,11 @@ } @Override - protected void actuallyHurt(ServerLevel level, DamageSource damageSource, float amount) { +- super.actuallyHurt(level, damageSource, amount); + // CraftBukkit start - void -> boolean + public boolean actuallyHurt(ServerLevel level, DamageSource damageSource, float amount, org.bukkit.event.entity.EntityDamageEvent event) { + boolean damageResult = super.actuallyHurt(level, damageSource, amount, event); + if (!damageResult) return false; + // CraftBukkit end - super.actuallyHurt(level, damageSource, amount); if (!this.isNoAi() && !this.isDeadOrDying()) { if (damageSource.getEntity() instanceof LivingEntity) { + this.getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, 80L); @@ -295,6 +_,7 @@ this.rollOut(); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/camel/Camel.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/camel/Camel.java.patch index 2ca2c4bbf8..2b76781cbe 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/camel/Camel.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/camel/Camel.java.patch @@ -11,7 +11,7 @@ boolean flag1 = this.isTamed() && this.getAge() == 0 && this.canFallInLove(); if (flag1) { - this.setInLove(player); -+ this.setInLove(player, item.copy()); // Paper - Fix EntityBreedEvent copying ++ this.setInLove(player, stack.copy()); // Paper - Fix EntityBreedEvent copying } boolean isBaby = this.isBaby(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Bogged.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Bogged.java.patch index a9624e7f90..2098a78455 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Bogged.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Bogged.java.patch @@ -43,7 +43,8 @@ + public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears, java.util.List drops) { + // Paper end - custom shear drops level.playSound(null, this, SoundEvents.BOGGED_SHEAR, soundSource, 1.0F, 1.0F); - this.spawnShearedMushrooms(level, shears); +- this.spawnShearedMushrooms(level, shears); ++ this.spawnShearedMushrooms(level, shears, drops); // Paper - custom shear drops this.setSheared(true); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Monster.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Monster.java.patch index 842c4f8588..68ded0ff66 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Monster.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Monster.java.patch @@ -5,7 +5,7 @@ } else { DimensionType dimensionType = level.dimensionType(); - int i = dimensionType.monsterSpawnBlockLightLimit(); -+ int i = world.getLevel().paperConfig().entities.spawning.monsterSpawnMaxLightLevel.or(dimensionType.monsterSpawnBlockLightLimit()); // Paper - Configurable max block light for monster spawning ++ int i = level.getLevel().paperConfig().entities.spawning.monsterSpawnMaxLightLevel.or(dimensionType.monsterSpawnBlockLightLimit()); // Paper - Configurable max block light for monster spawning if (i < 15 && level.getBrightness(LightLayer.BLOCK, pos) > i) { return false; } else { diff --git a/paper-server/patches/sources/net/minecraft/world/item/ArmorStandItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ArmorStandItem.java.patch new file mode 100644 index 0000000000..34157daf71 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/ArmorStandItem.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/world/item/ArmorStandItem.java ++++ b/net/minecraft/world/item/ArmorStandItem.java +@@ -45,6 +_,12 @@ + + float f = Mth.floor((Mth.wrapDegrees(context.getRotation() - 180.0F) + 22.5F) / 45.0F) * 45.0F; + armorStand.moveTo(armorStand.getX(), armorStand.getY(), armorStand.getZ(), f, 0.0F); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, armorStand).isCancelled()) { ++ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end + serverLevel.addFreshEntityWithPassengers(armorStand); + level.playSound( + null, armorStand.getX(), armorStand.getY(), armorStand.getZ(), SoundEvents.ARMOR_STAND_PLACE, SoundSource.BLOCKS, 0.75F, 0.8F diff --git a/paper-server/patches/sources/net/minecraft/world/item/AxeItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/AxeItem.java.patch new file mode 100644 index 0000000000..f39b785ebf --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/AxeItem.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/item/AxeItem.java ++++ b/net/minecraft/world/item/AxeItem.java +@@ -67,6 +_,11 @@ + return InteractionResult.PASS; + } else { + ItemStack itemInHand = context.getItemInHand(); ++ // Paper start - EntityChangeBlockEvent ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, clickedPos, optional.get())) { ++ return InteractionResult.PASS; ++ } ++ // Paper end + if (player instanceof ServerPlayer) { + CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, clickedPos, itemInHand); + } diff --git a/paper-server/patches/sources/net/minecraft/world/item/BoatItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/BoatItem.java.patch new file mode 100644 index 0000000000..44050142b3 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/BoatItem.java.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/world/item/BoatItem.java ++++ b/net/minecraft/world/item/BoatItem.java +@@ -30,7 +_,7 @@ + @Override + public InteractionResult use(Level level, Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); +- HitResult playerPovHitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.ANY); ++ net.minecraft.world.phys.BlockHitResult playerPovHitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.ANY); // Paper + if (playerPovHitResult.getType() == HitResult.Type.MISS) { + return InteractionResult.PASS; + } else { +@@ -51,6 +_,13 @@ + } + + if (playerPovHitResult.getType() == HitResult.Type.BLOCK) { ++ // CraftBukkit start - Boat placement ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(player, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, playerPovHitResult.getBlockPos(), playerPovHitResult.getDirection(), itemInHand, false, hand, playerPovHitResult.getLocation()); ++ ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end + AbstractBoat boat = this.getBoat(level, playerPovHitResult, itemInHand, player); + if (boat == null) { + return InteractionResult.FAIL; +@@ -60,7 +_,15 @@ + return InteractionResult.FAIL; + } else { + if (!level.isClientSide) { +- level.addFreshEntity(boat); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(level, playerPovHitResult.getBlockPos(), player.getDirection(), player, boat, hand).isCancelled()) { ++ return InteractionResult.FAIL; ++ } ++ ++ if (!level.addFreshEntity(boat)) { ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end + level.gameEvent(player, GameEvent.ENTITY_PLACE, playerPovHitResult.getLocation()); + itemInHand.consume(1, player); + } diff --git a/paper-server/patches/sources/net/minecraft/world/item/BoneMealItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/BoneMealItem.java.patch new file mode 100644 index 0000000000..a7ffb1e580 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/BoneMealItem.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/world/item/BoneMealItem.java ++++ b/net/minecraft/world/item/BoneMealItem.java +@@ -33,12 +_,17 @@ + + @Override + public InteractionResult useOn(UseOnContext context) { ++ // CraftBukkit start - extract bonemeal application logic to separate, static method ++ return BoneMealItem.applyBonemeal(context); ++ } ++ public static InteractionResult applyBonemeal(UseOnContext context) { ++ // CraftBukkit end + Level level = context.getLevel(); + BlockPos clickedPos = context.getClickedPos(); + BlockPos blockPos = clickedPos.relative(context.getClickedFace()); + if (growCrop(context.getItemInHand(), level, clickedPos)) { + if (!level.isClientSide) { +- context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); ++ if (context.getPlayer() != null) context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); // CraftBukkit - SPIGOT-7518 + level.levelEvent(1505, clickedPos, 15); + } + +@@ -48,7 +_,7 @@ + boolean isFaceSturdy = blockState.isFaceSturdy(level, clickedPos, context.getClickedFace()); + if (isFaceSturdy && growWaterPlant(context.getItemInHand(), level, blockPos, context.getClickedFace())) { + if (!level.isClientSide) { +- context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); ++ if (context.getPlayer() != null) context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); // CraftBukkit - SPIGOT-7518 + level.levelEvent(1505, blockPos, 15); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/item/BucketItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/BucketItem.java.patch new file mode 100644 index 0000000000..6a14409bf4 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/BucketItem.java.patch @@ -0,0 +1,92 @@ +--- a/net/minecraft/world/item/BucketItem.java ++++ b/net/minecraft/world/item/BucketItem.java +@@ -29,6 +_,7 @@ + import net.minecraft.world.phys.HitResult; + + public class BucketItem extends Item implements DispensibleContainerItem { ++ private static @Nullable ItemStack itemLeftInHandAfterPlayerBucketEmptyEvent = null; // Paper - Fix PlayerBucketEmptyEvent result itemstack + public final Fluid content; + + public BucketItem(Fluid content, Item.Properties properties) { +@@ -55,12 +_,23 @@ + } else if (this.content == Fluids.EMPTY) { + BlockState blockState = level.getBlockState(blockPos); + if (blockState.getBlock() instanceof BucketPickup bucketPickup) { ++ // CraftBukkit start ++ ItemStack dummyFluid = bucketPickup.pickupBlock(player, org.bukkit.craftbukkit.util.DummyGeneratorAccess.INSTANCE, blockPos, blockState); ++ if (dummyFluid.isEmpty()) return InteractionResult.FAIL; // Don't fire event if the bucket won't be filled. ++ org.bukkit.event.player.PlayerBucketFillEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((net.minecraft.server.level.ServerLevel) level, player, blockPos, blockPos, playerPovHitResult.getDirection(), itemInHand, dummyFluid.getItem(), hand); ++ ++ if (event.isCancelled()) { ++ // ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(level, blockPos)); // SPIGOT-5163 (see PlayerInteractManager) // Paper - Don't resend blocks ++ ((ServerPlayer) player).getBukkitEntity().updateInventory(); // SPIGOT-4541 ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end + ItemStack itemStack = bucketPickup.pickupBlock(player, level, blockPos, blockState); + if (!itemStack.isEmpty()) { + player.awardStat(Stats.ITEM_USED.get(this)); + bucketPickup.getPickupSound().ifPresent(soundEvent -> player.playSound(soundEvent, 1.0F, 1.0F)); + level.gameEvent(player, GameEvent.FLUID_PICKUP, blockPos); +- ItemStack itemStack1 = ItemUtils.createFilledResult(itemInHand, player, itemStack); ++ ItemStack itemStack1 = ItemUtils.createFilledResult(itemInHand, player, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit + if (!level.isClientSide) { + CriteriaTriggers.FILLED_BUCKET.trigger((ServerPlayer)player, itemStack); + } +@@ -73,7 +_,7 @@ + } else { + BlockState blockState = level.getBlockState(blockPos); + BlockPos blockPos2 = blockState.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockPos : blockPos1; +- if (this.emptyContents(player, level, blockPos2, playerPovHitResult)) { ++ if (this.emptyContents(player, level, blockPos2, playerPovHitResult, playerPovHitResult.getDirection(), blockPos, itemInHand, hand)) { // CraftBukkit + this.checkExtraContent(player, level, itemInHand, blockPos2); + if (player instanceof ServerPlayer) { + CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer)player, blockPos2, itemInHand); +@@ -90,6 +_,13 @@ + } + + public static ItemStack getEmptySuccessItem(ItemStack bucketStack, Player player) { ++ // Paper start - Fix PlayerBucketEmptyEvent result itemstack ++ if (itemLeftInHandAfterPlayerBucketEmptyEvent != null) { ++ ItemStack itemInHand = itemLeftInHandAfterPlayerBucketEmptyEvent; ++ itemLeftInHandAfterPlayerBucketEmptyEvent = null; ++ return itemInHand; ++ } ++ // Paper end - Fix PlayerBucketEmptyEvent result itemstack + return !player.hasInfiniteMaterials() ? new ItemStack(Items.BUCKET) : bucketStack; + } + +@@ -99,6 +_,12 @@ + + @Override + public boolean emptyContents(@Nullable Player player, Level level, BlockPos pos, @Nullable BlockHitResult result) { ++ // CraftBukkit start ++ return this.emptyContents(player, level, pos, result, null, null, null, InteractionHand.MAIN_HAND); ++ } ++ ++ public boolean emptyContents(@Nullable Player player, Level level, BlockPos pos, @Nullable BlockHitResult result, Direction enumdirection, BlockPos clicked, ItemStack itemstack, InteractionHand enumhand) { ++ // CraftBukkit end + if (!(this.content instanceof FlowingFluid flowingFluid)) { + return false; + } else { +@@ -109,8 +_,19 @@ + || canBeReplaced + || block instanceof LiquidBlockContainer liquidBlockContainer + && liquidBlockContainer.canPlaceLiquid(player, level, pos, blockState, this.content); ++ // CraftBukkit start ++ if (flag && player != null) { ++ org.bukkit.event.player.PlayerBucketEmptyEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketEmptyEvent((net.minecraft.server.level.ServerLevel) level, player, pos, clicked, enumdirection, itemstack, enumhand); ++ if (event.isCancelled()) { ++ // ((ServerPlayer) player).connection.send(new ClientboundBlockUpdatePacket(level, pos)); // SPIGOT-4238: needed when looking through entity // Paper - Don't resend blocks ++ ((ServerPlayer) player).getBukkitEntity().updateInventory(); // SPIGOT-4541 ++ return false; ++ } ++ itemLeftInHandAfterPlayerBucketEmptyEvent = event.getItemStack() != null ? event.getItemStack().equals(org.bukkit.craftbukkit.inventory.CraftItemStack.asNewCraftStack(net.minecraft.world.item.Items.BUCKET)) ? null : org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; // Paper - Fix PlayerBucketEmptyEvent result itemstack ++ } ++ // CraftBukkit end + if (!flag) { +- return result != null && this.emptyContents(player, level, result.getBlockPos().relative(result.getDirection()), null); ++ return result != null && this.emptyContents(player, level, result.getBlockPos().relative(result.getDirection()), null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit + } else if (level.dimensionType().ultraWarm() && this.content.is(FluidTags.WATER)) { + int x = pos.getX(); + int y = pos.getY(); diff --git a/paper-server/patches/sources/net/minecraft/world/item/CrossbowItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/CrossbowItem.java.patch new file mode 100644 index 0000000000..2f24e0047f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/CrossbowItem.java.patch @@ -0,0 +1,47 @@ +--- a/net/minecraft/world/item/CrossbowItem.java ++++ b/net/minecraft/world/item/CrossbowItem.java +@@ -90,7 +_,14 @@ + public boolean releaseUsing(ItemStack stack, Level level, LivingEntity entity, int timeLeft) { + int i = this.getUseDuration(stack, entity) - timeLeft; + float powerForTime = getPowerForTime(i, stack, entity); +- if (powerForTime >= 1.0F && !isCharged(stack) && tryLoadProjectiles(entity, stack)) { ++ // Paper start - Add EntityLoadCrossbowEvent ++ if (powerForTime >= 1.0F && !isCharged(stack)) { ++ final io.papermc.paper.event.entity.EntityLoadCrossbowEvent event = new io.papermc.paper.event.entity.EntityLoadCrossbowEvent(entity.getBukkitLivingEntity(), stack.asBukkitMirror(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(entity.getUsedItemHand())); ++ if (!event.callEvent() || !tryLoadProjectiles(entity, stack, event.shouldConsumeItem()) || !event.shouldConsumeItem()) { ++ if (entity instanceof ServerPlayer player) player.containerMenu.sendAllDataToRemote(); ++ return false; ++ } ++ // Paper end - Add EntityLoadCrossbowEvent + CrossbowItem.ChargingSounds chargingSounds = this.getChargingSounds(stack); + chargingSounds.end() + .ifPresent( +@@ -111,8 +_,14 @@ + } + } + ++ @io.papermc.paper.annotation.DoNotUse // Paper - Add EntityLoadCrossbowEvent + private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbowStack) { +- List list = draw(crossbowStack, shooter.getProjectile(crossbowStack), shooter); ++ // Paper start - Add EntityLoadCrossbowEvent ++ return CrossbowItem.tryLoadProjectiles(shooter, crossbowStack, true); ++ } ++ private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbowStack, boolean consume) { ++ List list = draw(crossbowStack, shooter.getProjectile(crossbowStack), shooter, consume); ++ // Paper end - Add EntityLoadCrossbowEvent + if (!list.isEmpty()) { + crossbowStack.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.of(list)); + return true; +@@ -164,7 +_,11 @@ + @Override + protected Projectile createProjectile(Level level, LivingEntity shooter, ItemStack weapon, ItemStack ammo, boolean isCrit) { + if (ammo.is(Items.FIREWORK_ROCKET)) { +- return new FireworkRocketEntity(level, ammo, shooter, shooter.getX(), shooter.getEyeY() - 0.15F, shooter.getZ(), true); ++ // Paper start ++ FireworkRocketEntity entity = new FireworkRocketEntity(level, ammo, shooter, shooter.getX(), shooter.getEyeY() - 0.15F, shooter.getZ(), true); ++ entity.spawningEntity = shooter.getUUID(); // Paper ++ return entity; ++ // Paper end + } else { + Projectile projectile = super.createProjectile(level, shooter, weapon, ammo, isCrit); + if (projectile instanceof AbstractArrow abstractArrow) { diff --git a/paper-server/patches/sources/net/minecraft/world/item/DyeItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/DyeItem.java.patch new file mode 100644 index 0000000000..b19c70d742 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/DyeItem.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/item/DyeItem.java ++++ b/net/minecraft/world/item/DyeItem.java +@@ -28,6 +_,17 @@ + sheep.level().playSound(player, sheep, SoundEvents.DYE_USE, SoundSource.PLAYERS, 1.0F, 1.0F); + if (!player.level().isClientSide) { + sheep.setColor(this.dyeColor); ++ // CraftBukkit start ++ byte bColor = (byte) this.dyeColor.getId(); ++ org.bukkit.event.entity.SheepDyeWoolEvent event = new org.bukkit.event.entity.SheepDyeWoolEvent((org.bukkit.entity.Sheep) sheep.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData(bColor), (org.bukkit.entity.Player) player.getBukkitEntity()); ++ sheep.level().getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ ++ sheep.setColor(DyeColor.byId((byte) event.getColor().getWoolData())); ++ // CraftBukkit end + stack.shrink(1); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/item/EggItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/EggItem.java.patch new file mode 100644 index 0000000000..59f5e151a8 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/EggItem.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/world/item/EggItem.java ++++ b/net/minecraft/world/item/EggItem.java +@@ -23,6 +_,28 @@ + @Override + public InteractionResult use(Level level, Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); ++ if (level instanceof ServerLevel serverLevel) { ++ // CraftBukkit start ++ // Paper start - PlayerLaunchProjectileEvent ++ final Projectile.Delayed thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, serverLevel, itemInHand, player, 0.0F, EggItem.PROJECTILE_SHOOT_POWER, 1.0F); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) thrownEgg.projectile().getBukkitEntity()); ++ if (event.callEvent() && thrownEgg.attemptSpawn()) { ++ if (event.shouldConsume()) { ++ itemInHand.consume(1, player); ++ } else if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } ++ level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)); ++ player.awardStat(Stats.ITEM_USED.get(this)); ++ } else { ++ // Paper end - PlayerLaunchProjectileEvent ++ if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end ++ } + level.playSound( + null, + player.getX(), +@@ -33,12 +_,7 @@ + 0.5F, + 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) + ); +- if (level instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectileFromRotation(ThrownEgg::new, serverLevel, itemInHand, player, 0.0F, PROJECTILE_SHOOT_POWER, 1.0F); +- } +- +- player.awardStat(Stats.ITEM_USED.get(this)); +- itemInHand.consume(1, player); ++ // Paper - PlayerLaunchProjectileEvent - moved up + return InteractionResult.SUCCESS; + } + diff --git a/paper-server/patches/sources/net/minecraft/world/item/EndCrystalItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/EndCrystalItem.java.patch new file mode 100644 index 0000000000..f6474104df --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/EndCrystalItem.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/world/item/EndCrystalItem.java ++++ b/net/minecraft/world/item/EndCrystalItem.java +@@ -27,7 +_,7 @@ + if (!blockState.is(Blocks.OBSIDIAN) && !blockState.is(Blocks.BEDROCK)) { + return InteractionResult.FAIL; + } else { +- BlockPos blockPos = clickedPos.above(); ++ BlockPos blockPos = clickedPos.above(); final BlockPos aboveBlockPosition = blockPos; // Paper - OBFHELPER + if (!level.isEmptyBlock(blockPos)) { + return InteractionResult.FAIL; + } else { +@@ -41,11 +_,17 @@ + if (level instanceof ServerLevel) { + EndCrystal endCrystal = new EndCrystal(level, d + 0.5, d1, d2 + 0.5); + endCrystal.setShowBottom(false); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, endCrystal).isCancelled()) { ++ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end + level.addFreshEntity(endCrystal); + level.gameEvent(context.getPlayer(), GameEvent.ENTITY_PLACE, blockPos); + EndDragonFight dragonFight = ((ServerLevel)level).getDragonFight(); + if (dragonFight != null) { +- dragonFight.tryRespawn(); ++ dragonFight.tryRespawn(aboveBlockPosition); // Paper - Perf: Do crystal-portal proximity check before entity lookup + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/item/EnderEyeItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/EnderEyeItem.java.patch new file mode 100644 index 0000000000..b2667052ad --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/EnderEyeItem.java.patch @@ -0,0 +1,56 @@ +--- a/net/minecraft/world/item/EnderEyeItem.java ++++ b/net/minecraft/world/item/EnderEyeItem.java +@@ -42,6 +_,11 @@ + return InteractionResult.SUCCESS; + } else { + BlockState blockState1 = blockState.setValue(EndPortalFrameBlock.HAS_EYE, Boolean.valueOf(true)); ++ // Paper start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(context.getPlayer(), clickedPos, blockState1)) { ++ return InteractionResult.PASS; ++ } ++ // Paper end + Block.pushEntitiesUp(blockState, blockState1, level, clickedPos); + level.setBlock(clickedPos, blockState1, 2); + level.updateNeighbourForOutputSignal(clickedPos, Blocks.END_PORTAL_FRAME); +@@ -57,7 +_,27 @@ + } + } + +- level.globalLevelEvent(1038, blockPos.offset(1, 0, 1), 0); ++ // CraftBukkit start - Use relative location for far away sounds ++ // level.globalLevelEvent(1038, blockPos.offset(1, 0, 1), 0); ++ int viewDistance = level.getCraftServer().getViewDistance() * 16; ++ BlockPos soundPos = blockPos.offset(1, 0, 1); ++ final net.minecraft.server.level.ServerLevel serverLevel = (net.minecraft.server.level.ServerLevel) level; // Paper - respect global sound events gamerule - ensured by isClientSide check above ++ for (ServerPlayer player : serverLevel.getPlayersForGlobalSoundGamerule()) { // Paper - respect global sound events gamerule ++ double deltaX = soundPos.getX() - player.getX(); ++ double deltaZ = soundPos.getZ() - player.getZ(); ++ double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; ++ final double soundRadiusSquared = serverLevel.getGlobalSoundRangeSquared(config -> config.endPortalSoundRadius); // Paper - respect global sound events gamerule ++ if (!serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_GLOBAL_SOUND_EVENTS) && distanceSquared > soundRadiusSquared) continue; // Spigot // Paper - respect global sound events gamerule ++ if (distanceSquared > viewDistance * viewDistance) { ++ double deltaLength = Math.sqrt(distanceSquared); ++ double relativeX = player.getX() + (deltaX / deltaLength) * viewDistance; ++ double relativeZ = player.getZ() + (deltaZ / deltaLength) * viewDistance; ++ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelEventPacket(1038, new BlockPos((int) relativeX, (int) soundPos.getY(), (int) relativeZ), 0, true)); ++ } else { ++ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelEventPacket(1038, soundPos, 0, true)); ++ } ++ } ++ // CraftBukkit end + } + + return InteractionResult.SUCCESS; +@@ -87,7 +_,11 @@ + eyeOfEnder.setItem(itemInHand); + eyeOfEnder.signalTo(blockPos); + level.gameEvent(GameEvent.PROJECTILE_SHOOT, eyeOfEnder.position(), GameEvent.Context.of(player)); +- level.addFreshEntity(eyeOfEnder); ++ // CraftBukkit start ++ if (!level.addFreshEntity(eyeOfEnder)) { ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end + if (player instanceof ServerPlayer serverPlayer) { + CriteriaTriggers.USED_ENDER_EYE.trigger(serverPlayer, blockPos); + } diff --git a/paper-server/patches/sources/net/minecraft/world/item/EnderpearlItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/EnderpearlItem.java.patch new file mode 100644 index 0000000000..5eccf6e90b --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/EnderpearlItem.java.patch @@ -0,0 +1,48 @@ +--- a/net/minecraft/world/item/EnderpearlItem.java ++++ b/net/minecraft/world/item/EnderpearlItem.java +@@ -21,22 +_,32 @@ + @Override + public InteractionResult use(Level level, Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.ENDER_PEARL_THROW, +- SoundSource.NEUTRAL, +- 0.5F, +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) +- ); + if (level instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectileFromRotation(ThrownEnderpearl::new, serverLevel, itemInHand, player, 0.0F, PROJECTILE_SHOOT_POWER, 1.0F); ++ // CraftBukkit start ++ // Paper start - PlayerLaunchProjectileEvent ++ final Projectile.Delayed thrownEnderpearl = Projectile.spawnProjectileFromRotationDelayed(ThrownEnderpearl::new, serverLevel, itemInHand, player, 0.0F, EnderpearlItem.PROJECTILE_SHOOT_POWER, 1.0F); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownEnderpearl.projectile().getBukkitEntity()); ++ if (event.callEvent() && thrownEnderpearl.attemptSpawn()) { ++ if (event.shouldConsume()) { ++ itemInHand.consume(1, player); ++ } else if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } ++ ++ serverLevel.playSound((Player) null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (serverLevel.getRandom().nextFloat() * 0.4F + 0.8F)); ++ player.awardStat(Stats.ITEM_USED.get(this)); ++ } else { ++ // Paper end - PlayerLaunchProjectileEvent ++ if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } ++ return InteractionResult.FAIL; ++ } + } ++ level.playSound((Player) null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)); ++ // CraftBukkit end + +- player.awardStat(Stats.ITEM_USED.get(this)); +- itemInHand.consume(1, player); ++ // Paper - PlayerLaunchProjectileEvent - moved up + return InteractionResult.SUCCESS; + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch index b806243653..78ae4f91d8 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/BaseSpawner.java +++ b/net/minecraft/world/level/BaseSpawner.java -@@ -44,9 +_,11 @@ +@@ -44,13 +_,15 @@ public int maxNearbyEntities = 6; public int requiredPlayerRange = 16; public int spawnRange = 4; @@ -12,6 +12,11 @@ } public boolean isNearPlayer(Level level, BlockPos pos) { +- return level.hasNearbyAlivePlayer(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, this.requiredPlayerRange); ++ return level.hasNearbyAlivePlayerThatAffectsSpawning(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, this.requiredPlayerRange); // Paper - Affects Spawning API + } + + public void clientTick(Level level, BlockPos pos) { @@ -73,13 +_,19 @@ } @@ -72,7 +77,7 @@ + if (mob.level().spigotConfig.nerfSpawnerMobs) { + mob.aware = false; + } -+ // Spigot End ++ // Spigot End } - if (!serverLevel.tryAddFreshEntityWithPassengers(entity)) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch index acc3c3c614..7fb16a71ce 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch @@ -1,28 +1,30 @@ --- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -@@ -106,6 +_,51 @@ +@@ -106,6 +_,53 @@ return 3; } }; + // CraftBukkit start - add fields and methods ++ @Nullable + public org.bukkit.potion.PotionEffect getPrimaryEffect() { + return (this.primaryPower != null) + ? org.bukkit.craftbukkit.potion.CraftPotionUtil.toBukkit(new MobEffectInstance( + this.primaryPower, -+ BeaconBlockEntity.getLevel(this.levels), -+ BeaconBlockEntity.getAmplification(this.levels, this.primaryPower, this.secondaryPower), ++ BeaconBlockEntity.computeEffectDuration(this.levels), ++ BeaconBlockEntity.computeEffectAmplifier(this.levels, this.primaryPower, this.secondaryPower), + true, + true + )) + : null; + } + ++ @Nullable + public org.bukkit.potion.PotionEffect getSecondaryEffect() { + return (BeaconBlockEntity.hasSecondaryEffect(this.levels, this.primaryPower, this.secondaryPower)) + ? org.bukkit.craftbukkit.potion.CraftPotionUtil.toBukkit(new MobEffectInstance( + this.secondaryPower, -+ BeaconBlockEntity.getLevel(this.levels), -+ BeaconBlockEntity.getAmplification(this.levels, this.primaryPower, this.secondaryPower), ++ BeaconBlockEntity.computeEffectDuration(this.levels), ++ BeaconBlockEntity.computeEffectAmplifier(this.levels, this.primaryPower, this.secondaryPower), + true, + true + )) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch index 0789c1b70b..3051c3b415 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch @@ -12,7 +12,7 @@ + + @Override + public java.util.List getContents() { -+ return Collections.singletonList(this.item); ++ return java.util.Collections.singletonList(this.item); + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch b/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch index 2fce5aff6c..0d57d512ea 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch @@ -34,7 +34,7 @@ + // I don't want to know why this is a generic type. + Entity entityCasted = (Entity)entity; + boolean wasRemoved = entityCasted.isRemoved(); -+ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, true); ++ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, worldGenSpawned, true); + if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { + // removed by callback + return false; @@ -107,7 +107,7 @@ this.requestChunkLoad(chunkPosValue); return false; } else { -+ if (callEvent) org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesUnloadEvent(((net.minecraft.world.level.chunk.storage.EntityStorage) this.permanentStorage).level, new ChunkPos(i), list.stream().map(entity -> (Entity) entity).collect(Collectors.toList())); // CraftBukkit ++ if (callEvent) org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesUnloadEvent(((net.minecraft.world.level.chunk.storage.EntityStorage) this.permanentStorage).level, new ChunkPos(chunkPosValue), list.stream().map(entity -> (Entity) entity).collect(Collectors.toList())); // CraftBukkit this.permanentStorage.storeEntities(new ChunkEntities<>(new ChunkPos(chunkPosValue), list)); list.forEach(entityAction); return true; @@ -149,7 +149,7 @@ this.chunkLoadStatuses.put(chunkEntities.getPos().toLong(), PersistentEntitySectionManager.ChunkLoadStatus.LOADED); + // CraftBukkit start - call entity load event + List entities = this.getEntities(chunkEntities.getPos()); -+ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesLoadEvent(((net.minecraft.world.level.chunk.storage.EntityStorage) this.permanentStorage).level, chunkentities.getPos(), entities); ++ org.bukkit.craftbukkit.event.CraftEventFactory.callEntitiesLoadEvent(((net.minecraft.world.level.chunk.storage.EntityStorage) this.permanentStorage).level, chunkEntities.getPos(), entities); + // CraftBukkit end } }