Somehow a bunch of items were missed

This commit is contained in:
Jake Potrebic 2024-12-14 22:35:35 -08:00
parent 35afd218f5
commit 172a80cb66
No known key found for this signature in database
GPG key ID: 27CC63F7CBC866C7
25 changed files with 475 additions and 25 deletions

View file

@ -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());

View file

@ -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
}

View file

@ -172,7 +172,7 @@
this.distanceManager.purgeStaleTickets();
}
@@ -400,11 +_,19 @@
@@ -400,12 +_,20 @@
);
this.lastSpawnState = spawnState;
profiler.popPush("spawnAndTick");
@ -182,6 +182,7 @@
List<MobCategory> 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();

View file

@ -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<T> entityType, ConversionParams conversionParams, EntitySpawnReason spawnReason, ConversionParams.AfterConversion<T> 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 extends Mob> T convertTo(

View file

@ -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

View file

@ -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;

View file

@ -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();
}

View file

@ -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();

View file

@ -43,7 +43,8 @@
+ public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears, java.util.List<ItemStack> 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);
}

View file

@ -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 {

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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();

View file

@ -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<ItemStack> 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<ItemStack> 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) {

View file

@ -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);
}

View file

@ -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> 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;
}

View file

@ -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
}
}

View file

@ -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);
}

View file

@ -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> 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;
}
}

View file

@ -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 @@
}

View file

@ -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
+ ))

View file

@ -12,7 +12,7 @@
+
+ @Override
+ public java.util.List<net.minecraft.world.item.ItemStack> getContents() {
+ return Collections.singletonList(this.item);
+ return java.util.Collections.singletonList(this.item);
+ }
+
+ @Override

View file

@ -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<Entity> 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
}
}