Patch me this, patch me that

This commit is contained in:
Bjarne Koll 2024-10-24 12:11:32 +02:00
parent 951043246e
commit 199ab95b0d
60 changed files with 336 additions and 360 deletions

View File

@ -35,7 +35,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
return org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion()); return org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion());
} }
// Paper end - WitchReadyPotionEvent // Paper end - WitchReadyPotionEvent

View File

@ -32,7 +32,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
io.papermc.paper.event.block.BlockFailedDispenseEvent event = new io.papermc.paper.event.block.BlockFailedDispenseEvent(block); io.papermc.paper.event.block.BlockFailedDispenseEvent event = new io.papermc.paper.event.block.BlockFailedDispenseEvent(block);
return event.callEvent(); return event.callEvent();
} }

View File

@ -72,7 +72,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
return event.callEvent(); return event.callEvent();
} }
// Paper end // Paper end

View File

@ -13,20 +13,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return; return;
} }
- this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed - this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed
// Paper end - validate pick item position
+ // Paper start - Add PlayerPickItemEvent + // Paper start - Add PlayerPickItemEvent
+ // this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed - moved down
+ Player bukkitPlayer = this.player.getBukkitEntity(); + Player bukkitPlayer = this.player.getBukkitEntity();
+ int targetSlot = this.player.getInventory().getSuitableHotbarSlot(); + int targetSlot = this.player.getInventory().getSuitableHotbarSlot();
+ int sourceSlot = packet.getSlot(); + int sourceSlot = packet.getSlot();
+ +
+ io.papermc.paper.event.player.PlayerPickItemEvent event = new io.papermc.paper.event.player.PlayerPickItemEvent(bukkitPlayer, targetSlot, sourceSlot); + io.papermc.paper.event.player.PlayerPickItemEvent event = new io.papermc.paper.event.player.PlayerPickItemEvent(bukkitPlayer, targetSlot, sourceSlot);
+ if (!event.callEvent()) return; + if (!event.callEvent()) return;
+
+ this.player.getInventory().pickSlot(event.getSourceSlot(), event.getTargetSlot());
+ // Paper end - Add PlayerPickItemEvent + // Paper end - Add PlayerPickItemEvent
this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, this.player.getInventory().selected, this.player.getInventory().getItem(this.player.getInventory().selected))); +
this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, packet.getSlot(), this.player.getInventory().getItem(packet.getSlot()))); + this.player.getInventory().pickSlot(event.getSourceSlot(), event.getTargetSlot()); // Paper - Add PlayerPickItemEvent
this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.getInventory().selected)); // Paper end - validate pick item position
int i = this.player.getInventory().selected;
diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/player/Inventory.java --- a/src/main/java/net/minecraft/world/entity/player/Inventory.java

View File

@ -97,7 +97,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
} }
public static PrepareAnvilEvent callPrepareAnvilEvent(AnvilView view, ItemStack item) { public static PrepareAnvilEvent callPrepareAnvilEvent(AnvilView view, ItemStack item) {
@ -110,7 +110,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
PrepareAnvilEvent event = new PrepareAnvilEvent(view, CraftItemStack.asCraftMirror(item).clone()); PrepareAnvilEvent event = new PrepareAnvilEvent(view, CraftItemStack.asCraftMirror(item).clone());
event.getView().getPlayer().getServer().getPluginManager().callEvent(event); event.getView().getPlayer().getServer().getPluginManager().callEvent(event);
event.getInventory().setItem(2, event.getResult()); event.getInventory().setItem(2, event.getResult());
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
} }
public static PrepareGrindstoneEvent callPrepareGrindstoneEvent(InventoryView view, ItemStack item) { public static PrepareGrindstoneEvent callPrepareGrindstoneEvent(InventoryView view, ItemStack item) {
@ -123,7 +123,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
PrepareGrindstoneEvent event = new PrepareGrindstoneEvent(view, CraftItemStack.asCraftMirror(item).clone()); PrepareGrindstoneEvent event = new PrepareGrindstoneEvent(view, CraftItemStack.asCraftMirror(item).clone());
event.getView().getPlayer().getServer().getPluginManager().callEvent(event); event.getView().getPlayer().getServer().getPluginManager().callEvent(event);
event.getInventory().setItem(2, event.getResult()); event.getInventory().setItem(2, event.getResult());
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
} }
public static PrepareSmithingEvent callPrepareSmithingEvent(InventoryView view, ItemStack item) { public static PrepareSmithingEvent callPrepareSmithingEvent(InventoryView view, ItemStack item) {

View File

@ -64,7 +64,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled); return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
} }
DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION; DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION;
@ -73,7 +73,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} else if (damager != null || source.getDirectEntity() != null) { } else if (damager != null || source.getDirectEntity() != null) {
DamageCause cause = (source.isSweep()) ? DamageCause.ENTITY_SWEEP_ATTACK : DamageCause.ENTITY_ATTACK; DamageCause cause = (source.isSweep()) ? DamageCause.ENTITY_SWEEP_ATTACK : DamageCause.ENTITY_ATTACK;
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
cause = DamageCause.MAGIC; cause = DamageCause.MAGIC;
} }
@ -82,7 +82,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} else if (source.is(DamageTypes.FELL_OUT_OF_WORLD)) { } else if (source.is(DamageTypes.FELL_OUT_OF_WORLD)) {
return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled); return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
} else if (source.is(DamageTypes.LAVA)) { } else if (source.is(DamageTypes.LAVA)) {
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
cause = DamageCause.CUSTOM; cause = DamageCause.CUSTOM;
} }

View File

@ -14,14 +14,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start // CraftBukkit start
- if (CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem).isCancelled()) { - if (CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem).isCancelled()) {
+ // Paper start - Add drops to shear events + // Paper start - Add drops to shear events
+ org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops()); + org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops(worldserver, itemstack));
+ if (event.isCancelled()) { + if (event.isCancelled()) {
+ // Paper end - Add drops to shear events + // Paper end - Add drops to shear events
continue; continue;
} }
// CraftBukkit end // CraftBukkit end
- ishearable.shear(SoundSource.BLOCKS); - ishearable.shear(worldserver, SoundSource.BLOCKS, itemstack);
+ ishearable.shear(SoundSource.BLOCKS, CraftItemStack.asNMSCopy(event.getDrops())); // Paper - Add drops to shear events + ishearable.shear(worldserver, SoundSource.BLOCKS, itemstack, CraftItemStack.asNMSCopy(event.getDrops())); // Paper - Add drops to shear events
worldserver.gameEvent((Entity) null, (Holder) GameEvent.SHEAR, blockposition); worldserver.gameEvent((Entity) null, (Holder) GameEvent.SHEAR, blockposition);
return true; return true;
} }
@ -29,16 +29,16 @@ diff --git a/src/main/java/net/minecraft/world/entity/Shearable.java b/src/main/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Shearable.java --- a/src/main/java/net/minecraft/world/entity/Shearable.java
+++ b/src/main/java/net/minecraft/world/entity/Shearable.java +++ b/src/main/java/net/minecraft/world/entity/Shearable.java
@@ -0,0 +0,0 @@ package net.minecraft.world.entity; @@ -0,0 +0,0 @@ import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundSource; import net.minecraft.world.item.ItemStack;
public interface Shearable { public interface Shearable {
+ default void shear(SoundSource soundCategory, java.util.List<net.minecraft.world.item.ItemStack> drops) { this.shear(soundCategory); } // Paper - Add drops to shear events + default void shear(ServerLevel world, SoundSource soundCategory, ItemStack shears, java.util.List<net.minecraft.world.item.ItemStack> drops) { this.shear(world, soundCategory, shears); } // Paper - Add drops to shear events
void shear(SoundSource shearedSoundCategory); void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears);
boolean readyForShearing(); boolean readyForShearing();
+ // Paper start - custom shear drops; ensure all implementing entities override this + // Paper start - custom shear drops; ensure all implementing entities override this
+ default java.util.List<net.minecraft.world.item.ItemStack> generateDefaultDrops() { + default java.util.List<net.minecraft.world.item.ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
+ return java.util.Collections.emptyList(); + return java.util.Collections.emptyList();
+ } + }
+ // Paper end - custom shear drops + // Paper end - custom shear drops
@ -47,275 +47,262 @@ diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java --- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
+++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java +++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.storage.loot.BuiltInLootTables;
// CraftBukkit start
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.event.entity.EntityDropItemEvent;
import org.bukkit.event.entity.EntityTransformEvent;
// CraftBukkit end
@@ -0,0 +0,0 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo @@ -0,0 +0,0 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
return InteractionResult.sidedSuccess(this.level().isClientSide); ServerLevel worldserver = (ServerLevel) world;
} else if (itemstack.is(Items.SHEARS) && this.readyForShearing()) {
// CraftBukkit start
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
- return InteractionResult.PASS;
+ // Paper start - custom shear drops
+ java.util.List<ItemStack> drops = this.generateDefaultDrops();
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
+ if (event != null) {
+ if (event.isCancelled()) {
+ return InteractionResult.PASS;
+ }
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
}
+ // Paper end - custom shear drops
// CraftBukkit end
- this.shear(SoundSource.PLAYERS);
+ this.shear(SoundSource.PLAYERS, drops); // Paper - custom shear drops
this.gameEvent(GameEvent.SHEAR, player);
if (!this.level().isClientSide) {
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
@@ -0,0 +0,0 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
@Override
public void shear(SoundSource shearedSoundCategory) {
+ // Paper start - custom shear drops
+ this.shear(shearedSoundCategory, this.generateDefaultDrops());
+ }
+
+ @Override
+ public java.util.List<ItemStack> generateDefaultDrops() {
+ java.util.List<ItemStack> dropEntities = new java.util.ArrayList<>(5);
+ for (int i = 0; i < 5; ++i) {
+ dropEntities.add(new ItemStack(this.getVariant().getBlockState().getBlock()));
+ }
+ return dropEntities;
+ }
+
+ @Override
+ public void shear(SoundSource shearedSoundCategory, java.util.List<ItemStack> drops) { // If drops is null, need to generate drops
+ // Paper end - custom shear drops
this.level().playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
if (!this.level().isClientSide()) {
Cow entitycow = (Cow) EntityType.COW.create(this.level());
@@ -0,0 +0,0 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - from above and add Bukkit remove cause
// CraftBukkit end
- for (int i = 0; i < 5; ++i) {
- // CraftBukkit start
- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), new ItemStack(this.getVariant().blockState.getBlock()));
- EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
- Bukkit.getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- continue;
- }
- this.level().addFreshEntity(entityitem);
- // CraftBukkit end
+ // Paper start - custom shear drops; moved drop generation to separate method
+ for (final ItemStack drop : drops) {
+ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop);
+ this.spawnAtLocation(entityitem);
}
+ // Paper end - custom shear drops
}
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
@@ -0,0 +0,0 @@ public class Sheep extends Animal implements Shearable {
if (itemstack.is(Items.SHEARS)) {
if (!this.level().isClientSide && this.readyForShearing()) {
// CraftBukkit start // CraftBukkit start
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) { - if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
- return InteractionResult.PASS; - return InteractionResult.PASS;
+ // Paper start - custom shear drops + // Paper start - custom shear drops
+ java.util.List<ItemStack> drops = this.generateDefaultDrops(); + java.util.List<ItemStack> drops = this.generateDefaultDrops(worldserver, itemstack);
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); + org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
+ if (event != null) { + if (event != null) {
+ if (event.isCancelled()) { + if (event.isCancelled()) {
+ return InteractionResult.PASS; + return InteractionResult.PASS;
+ } + }
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); + drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
}
+ // Paper end - custom shear drops + // Paper end - custom shear drops
}
// CraftBukkit end // CraftBukkit end
- this.shear(SoundSource.PLAYERS); - this.shear(worldserver, SoundSource.PLAYERS, itemstack);
+ this.shear(SoundSource.PLAYERS, drops); // Paper + this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops
this.gameEvent(GameEvent.SHEAR, player); this.gameEvent(GameEvent.SHEAR, player);
itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
return InteractionResult.SUCCESS; }
@@ -0,0 +0,0 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
@Override
public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) {
+ // Paper start - custom shear drops
+ this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears));
+ }
+
+ @Override
+ public java.util.List<ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
+ final java.util.List<ItemStack> drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
+ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (ignored, stack) -> {
+ for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1));
+ });
+ return drops;
+ }
+
+ @Override
+ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List<ItemStack> drops) {
+ // Paper end - custom shear drops
world.playSound((Player) null, (Entity) this, SoundEvents.MOOSHROOM_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
this.convertTo(EntityType.COW, ConversionParams.single(this, false, false), (entitycow) -> {
world.sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5D), this.getZ(), 1, 0.0D, 0.0D, 0.0D, 0.0D);
- this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_MOOSHROOM, shears, (worldserver1, itemstack1) -> {
- for (int i = 0; i < itemstack1.getCount(); ++i) {
- // CraftBukkit start
- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), itemstack1.copyWithCount(1));
- EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
- Bukkit.getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- continue;
- }
- worldserver1.addFreshEntity(entityitem);
- // CraftBukkit end
+ // Paper start - custom shear drops; moved drop generation to separate method
+ drops.forEach(itemstack1 -> {
+ for (final ItemStack drop : drops) {
+ ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop);
+ this.spawnAtLocation(entityitem);
}
-
+ // Paper end - custom shear drops; moved drop generation to separate method
});
}, EntityTransformEvent.TransformReason.SHEARED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); // CraftBukkit
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
@@ -0,0 +0,0 @@ public class Sheep extends Animal implements Shearable {
if (this.readyForShearing()) {
// CraftBukkit start
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
- return InteractionResult.PASS;
+ // Paper start - custom shear drops
+ java.util.List<ItemStack> drops = this.generateDefaultDrops(worldserver, itemstack);
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
+ if (event != null) {
+ if (event.isCancelled()) {
+ return InteractionResult.PASS;
+ }
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
+ // Paper end - custom shear drops
}
// CraftBukkit end
- this.shear(worldserver, SoundSource.PLAYERS, itemstack);
+ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops
this.gameEvent(GameEvent.SHEAR, player);
itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
return InteractionResult.SUCCESS_SERVER;
@@ -0,0 +0,0 @@ public class Sheep extends Animal implements Shearable { @@ -0,0 +0,0 @@ public class Sheep extends Animal implements Shearable {
@Override @Override
public void shear(SoundSource shearedSoundCategory) { public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) {
+ // Paper start - custom shear drops + // Paper start - custom shear drops
+ this.shear(shearedSoundCategory, this.generateDefaultDrops()); + this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears));
+ } + }
+ +
+ @Override + @Override
+ public java.util.List<ItemStack> generateDefaultDrops() { + public java.util.List<ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
+ int count = 1 + this.random.nextInt(3); + final java.util.List<ItemStack> drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
+ java.util.List<ItemStack> dropEntities = new java.util.ArrayList<>(count); + this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SHEEP, shears, (ignored, stack) -> {
+ for (int j = 0; j < count; ++j) { + for (int i = 0; i < stack.getCount(); ++i) drops.add(stack.copyWithCount(1));
+ dropEntities.add(new ItemStack(Sheep.ITEM_BY_DYE.get(this.getColor()))); + });
+ } + return drops;
+ return dropEntities;
+ } + }
+ +
+ @Override + @Override
+ public void shear(SoundSource shearedSoundCategory, java.util.List<ItemStack> drops) { + public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List<ItemStack> drops) {
+ final ServerLevel worldserver1 = world; // Named for lambda consumption
+ // Paper end - custom shear drops + // Paper end - custom shear drops
this.level().playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F); world.playSound((Player) null, (Entity) this, SoundEvents.SHEEP_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
this.setSheared(true); - this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_SHEEP, shears, (worldserver1, itemstack1) -> {
int i = 1 + this.random.nextInt(3); - for (int i = 0; i < itemstack1.getCount(); ++i) {
+ drops.forEach(itemstack1 -> { // Paper - custom drops - loop in generated default drops
- for (int j = 0; j < i; ++j) { + if (true) { // Paper - custom drops - loop in generated default drops
+ for (final ItemStack drop : drops) { // Paper - custom shear drops (moved drop generation to separate method) this.forceDrops = true; // CraftBukkit
this.forceDrops = true; // CraftBukkit ItemEntity entityitem = this.spawnAtLocation(worldserver1, itemstack1.copyWithCount(1), 1.0F);
- ItemEntity entityitem = this.spawnAtLocation((ItemLike) Sheep.ITEM_BY_DYE.get(this.getColor()), 1); this.forceDrops = false; // CraftBukkit
+ ItemEntity entityitem = this.spawnAtLocation(drop, 1); // Paper - custom shear drops
this.forceDrops = false; // CraftBukkit
if (entityitem != null) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java --- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java +++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
@@ -0,0 +0,0 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM @@ -0,0 +0,0 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
ServerLevel worldserver = (ServerLevel) world;
if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { // CraftBukkit start
// CraftBukkit start - if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
- if (!CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) { - return InteractionResult.PASS;
- return InteractionResult.PASS; + // Paper start - custom shear drops
+ // Paper start - custom shear drops + java.util.List<ItemStack> drops = this.generateDefaultDrops(worldserver, itemstack);
+ java.util.List<ItemStack> drops = this.generateDefaultDrops(); + org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
+ org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); + if (event != null) {
+ if (event != null) { + if (event.isCancelled()) {
+ if (event.isCancelled()) { + return InteractionResult.PASS;
+ return InteractionResult.PASS; + }
+ } + drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); + // Paper end - custom shear drops
} }
+ // Paper end - custom shear drops // CraftBukkit end
// CraftBukkit end - this.shear(worldserver, SoundSource.PLAYERS, itemstack);
- this.shear(SoundSource.PLAYERS); + this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops
+ this.shear(SoundSource.PLAYERS, drops); // Paper this.gameEvent(GameEvent.SHEAR, player);
this.gameEvent(GameEvent.SHEAR, player);
if (!this.level().isClientSide) {
itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
}
@@ -0,0 +0,0 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM @@ -0,0 +0,0 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
@Override @Override
public void shear(SoundSource shearedSoundCategory) { public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) {
+ // Paper start - custom shear drops + // Paper start - custom shear drops
+ this.shear(shearedSoundCategory, this.generateDefaultDrops()); + this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears));
+ } + }
+ +
+ @Override + @Override
+ public java.util.List<ItemStack> generateDefaultDrops() { + public java.util.List<ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
+ return java.util.Collections.singletonList(new ItemStack(Items.CARVED_PUMPKIN)); + final java.util.List<ItemStack> drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
+ this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (ignored, stack) -> {
+ drops.add(stack);
+ });
+ return drops;
+ } + }
+ +
+ @Override + @Override
+ public void shear(SoundSource shearedSoundCategory, java.util.List<ItemStack> drops) { + public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List<ItemStack> drops) {
+ // Paper end - custom shear drops + final ServerLevel worldserver1 = world; // Named for lambda consumption
this.level().playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + // Paper end - custom shear drops
if (!this.level().isClientSide()) { world.playSound((Player) null, (Entity) this, SoundEvents.SNOW_GOLEM_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
this.setPumpkin(false); this.setPumpkin(false);
- this.forceDrops = true; // CraftBukkit - this.dropFromShearingLootTable(world, BuiltInLootTables.SHEAR_SNOW_GOLEM, shears, (worldserver1, itemstack1) -> {
- this.spawnAtLocation(new ItemStack(Items.CARVED_PUMPKIN), this.getEyeHeight()); + drops.forEach(itemstack1 -> { // Paper - custom shear drops
- this.forceDrops = false; // CraftBukkit this.forceDrops = true; // CraftBukkit
+ // Paper start - custom shear drops (moved drop generation to separate method) this.spawnAtLocation(worldserver1, itemstack1, this.getEyeHeight());
+ for (final ItemStack drop : drops) { this.forceDrops = false; // CraftBukkit
+ this.forceDrops = true;
+ this.spawnAtLocation(drop, this.getEyeHeight());
+ this.forceDrops = false;
+ }
+ // Paper end - custom shear drops
}
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java diff --git a/src/main/java/net/minecraft/world/entity/monster/Bogged.java b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java --- a/src/main/java/net/minecraft/world/entity/monster/Bogged.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java +++ b/src/main/java/net/minecraft/world/entity/monster/Bogged.java
@@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable { @@ -0,0 +0,0 @@ import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { public class Bogged extends AbstractSkeleton implements Shearable {
// CraftBukkit start
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) { @@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable {
- this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients ServerLevel worldserver = (ServerLevel) world;
- return InteractionResult.PASS;
+ // Paper start - expose drops in event // CraftBukkit start
+ java.util.List<net.minecraft.world.item.ItemStack> drops = generateDefaultDrops(); - if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand)) {
+ final org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); - this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients
+ if (event != null) { - return InteractionResult.PASS;
+ if (event.isCancelled()) { + // Paper start - custom shear drops
+ if (player instanceof final net.minecraft.server.level.ServerPlayer serverPlayer) this.resendPossiblyDesyncedDataValues(java.util.List.of(Bogged.DATA_SHEARED), serverPlayer); + java.util.List<ItemStack> drops = this.generateDefaultDrops(worldserver, itemstack);
+ return InteractionResult.PASS; + org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops);
+ } + if (event != null) {
+ drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); + if (event.isCancelled()) {
+ // Paper end - expose drops in event + this.getEntityData().markDirty(Bogged.DATA_SHEARED); // CraftBukkit - mark dirty to restore sheared state to clients
} + return InteractionResult.PASS;
// CraftBukkit end + }
- this.shear(SoundSource.PLAYERS); + drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
+ this.shear(SoundSource.PLAYERS, drops); // Paper - expose drops in event + // Paper end - custom shear drops
this.gameEvent(GameEvent.SHEAR, player); }
if (!this.level().isClientSide) { // CraftBukkit end
- this.shear(worldserver, SoundSource.PLAYERS, itemstack);
+ this.shear(worldserver, SoundSource.PLAYERS, itemstack, drops); // Paper - custom shear drops
this.gameEvent(GameEvent.SHEAR, player);
itemstack.hurtAndBreak(1, player, getSlotForHand(hand)); itemstack.hurtAndBreak(1, player, getSlotForHand(hand));
}
@@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable { @@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable {
@Override @Override
public void shear(SoundSource shearedSoundCategory) { public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears) {
+ // Paper start - shear drop API + // Paper start - custom shear drops
+ this.shear(shearedSoundCategory, generateDefaultDrops()); + this.shear(world, shearedSoundCategory, shears, this.generateDefaultDrops(world, shears));
+ } + }
+ +
+ @Override + @Override
+ public void shear(SoundSource shearedSoundCategory, java.util.List<net.minecraft.world.item.ItemStack> drops) { + public java.util.List<ItemStack> generateDefaultDrops(final ServerLevel serverLevel, final ItemStack shears) {
+ // Paper end - shear drop API + final java.util.List<ItemStack> drops = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
this.level().playSound((Player) null, (Entity) this, SoundEvents.BOGGED_SHEAR, shearedSoundCategory, 1.0F, 1.0F); + this.dropFromShearingLootTable(serverLevel, BuiltInLootTables.BOGGED_SHEAR, shears, (ignored, stack) -> {
- this.spawnShearedMushrooms(); + drops.add(stack);
+ this.spawnDrops(drops); // Paper - shear drop API + });
+ return drops;
+ }
+
+ @Override
+ public void shear(ServerLevel world, SoundSource shearedSoundCategory, ItemStack shears, java.util.List<ItemStack> drops) {
+ // Paper end - custom shear drops
world.playSound((Player) null, (Entity) this, SoundEvents.BOGGED_SHEAR, shearedSoundCategory, 1.0F, 1.0F);
- this.spawnShearedMushrooms(world, shears);
+ this.spawnShearedMushrooms(world, shears, drops); // Paper - custom shear drops
this.setSheared(true); this.setSheared(true);
} }
private void spawnShearedMushrooms() { - private void spawnShearedMushrooms(ServerLevel world, ItemStack shears) {
+ // Paper start - shear drops API - this.dropFromShearingLootTable(world, BuiltInLootTables.BOGGED_SHEAR, shears, (worldserver1, itemstack1) -> {
+ this.spawnDrops(generateDefaultDrops()); // Only here for people calling spawnSheardMushrooms. Not used otherwise. + // Paper start - custom shear drops
+ } + private void spawnShearedMushrooms(ServerLevel world, ItemStack shears, java.util.List<ItemStack> drops) {
+ private void spawnDrops(java.util.List<net.minecraft.world.item.ItemStack> drops) { + final ServerLevel worldserver1 = world; // Named for lambda consumption
+ drops.forEach(stack -> { + drops.forEach(itemstack1 -> {
+ this.forceDrops = true; + // Paper end - custom shear drops
+ this.spawnAtLocation(stack, this.getBbHeight()); this.spawnAtLocation(worldserver1, itemstack1, this.getBbHeight());
+ this.forceDrops = false; });
+ });
+ }
+ private void generateShearedMushrooms(java.util.function.Consumer<ItemStack> stackConsumer) {
+ // Paper end - shear drops API
Level world = this.level();
if (world instanceof ServerLevel worldserver) {
@@ -0,0 +0,0 @@ public class Bogged extends AbstractSkeleton implements Shearable {
while (objectlistiterator.hasNext()) {
ItemStack itemstack = (ItemStack) objectlistiterator.next();
- this.spawnAtLocation(itemstack, this.getBbHeight());
+ stackConsumer.accept(itemstack); // Paper
}
}
} }
+ // Paper start - shear drops API
+ @Override
+ public java.util.List<ItemStack> generateDefaultDrops() {
+ final java.util.List<ItemStack> drops = new java.util.ArrayList<>();
+ this.generateShearedMushrooms(drops::add);
+ return drops;
+ }
+ // Paper end - shear drops API
+
@Override
public boolean readyForShearing() {
return !this.isSheared() && this.isAlive();
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java

View File

@ -180,28 +180,40 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
@@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { @@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
protected final ContainerLevelAccess access;
protected final Player player; protected final Player player;
protected final Container inputSlots; protected final Container inputSlots;
private final List<Integer> inputSlotIndexes; - protected final ResultContainer resultSlots = new ResultContainer() {
- protected final ResultContainer resultSlots = new ResultContainer(); - @Override
- public void setChanged() {
- ItemCombinerMenu.this.slotsChanged(this);
- }
- };
+ protected final ResultContainer resultSlots; // Paper - Add missing InventoryHolders; delay field init + protected final ResultContainer resultSlots; // Paper - Add missing InventoryHolders; delay field init
private final int resultSlotIndex; private final int resultSlotIndex;
protected abstract boolean mayPickup(Player player, boolean present); protected boolean mayPickup(Player player, boolean present) {
@@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { @@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
public ItemCombinerMenu(@Nullable MenuType<?> type, int syncId, Inventory playerInventory, ContainerLevelAccess context) { public ItemCombinerMenu(@Nullable MenuType<?> type, int syncId, Inventory playerInventory, ContainerLevelAccess context, ItemCombinerMenuSlotDefinition forgingSlotsManager) {
super(type, syncId); super(type, syncId);
this.access = context; this.access = context;
+ this.resultSlots = new ResultContainer(this.createBlockHolder(this.access)); // Paper - Add missing InventoryHolders; delay field init + // Paper start - Add missing InventoryHolders; delay field init
+ this.resultSlots = new ResultContainer(this.createBlockHolder(this.access)) {
+ @Override
+ public void setChanged() {
+ ItemCombinerMenu.this.slotsChanged(this);
+ }
+ };
+ // Paper end - Add missing InventoryHolders; delay field init
this.player = playerInventory.player; this.player = playerInventory.player;
ItemCombinerMenuSlotDefinition itemcombinermenuslotdefinition = this.createInputSlotDefinitions(); this.inputSlots = this.createContainer(forgingSlotsManager.getNumOfInputSlots());
this.resultSlotIndex = forgingSlotsManager.getResultSlotIndex();
@@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { @@ -0,0 +0,0 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
protected abstract ItemCombinerMenuSlotDefinition createInputSlotDefinitions(); public abstract void createResult();
private SimpleContainer createContainer(int size) { private SimpleContainer createContainer(int size) {
- return new SimpleContainer(size) { - return new SimpleContainer(size) {
+ return new SimpleContainer(this.createBlockHolder(this.access), size) { // Paper - Add missing InventoryHolders + return new SimpleContainer(this.createBlockHolder(this.access), size) {
@Override @Override
public void setChanged() { public void setChanged() {
super.setChanged(); super.setChanged();

View File

@ -53,7 +53,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
} }
// Paper end // Paper end

View File

@ -9,42 +9,35 @@ This can happen as a result of users moving regionfiles around,
which would cause a crash on Folia but would appear to function which would cause a crash on Folia but would appear to function
fine on Paper. fine on Paper.
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
@@ -0,0 +0,0 @@ public class ChunkSerializer { @@ -0,0 +0,0 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
for (int k1 = 0; k1 < nbttaglist3.size(); ++k1) {
CompoundTag nbttagcompound4 = nbttaglist3.getCompound(k1);
while (iterator2.hasNext()) {
nbttagcompound = (CompoundTag) iterator2.next();
+ // Paper start - do not read tile entities positioned outside the chunk + // Paper start - do not read tile entities positioned outside the chunk
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound4); + final BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound);
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) { + if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk"); + LOGGER.warn("Tile entity serialized in chunk {} in world '{}' positioned at {} is located outside of the chunk", chunkPos, world.getWorld().getName(), blockposition);
+ continue; + continue;
+ } + }
+ // Paper end - do not read tile entities positioned outside the chunk + // Paper end - do not read tile entities positioned outside the chunk
((ChunkAccess) object1).setBlockEntityNbt(nbttagcompound4); protochunk1.setBlockEntityNbt(nbttagcompound);
} }
@@ -0,0 +0,0 @@ public class ChunkSerializer { @@ -0,0 +0,0 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
CompoundTag nbttagcompound1 = nbttaglist1.getCompound(i); chunk.setBlockEntityNbt(nbttagcompound);
boolean flag = nbttagcompound1.getBoolean("keepPacked"); } else {
BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound);
+ // Paper start - do not read tile entities positioned outside the chunk + // Paper start - do not read tile entities positioned outside the chunk
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1); // moved up
+ ChunkPos chunkPos = chunk.getPos(); + ChunkPos chunkPos = chunk.getPos();
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) { + if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk"); + LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk");
+ continue; + continue;
+ } + }
+ // Paper end - do not read tile entities positioned outside the chunk + // Paper end - do not read tile entities positioned outside the chunk
+ BlockEntity tileentity = BlockEntity.loadStatic(blockposition, chunk.getBlockState(blockposition), nbttagcompound, world.registryAccess());
if (flag) {
chunk.setBlockEntityNbt(nbttagcompound1);
} else {
- BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1);
+ // Paper - do not read tile entities positioned outside the chunk; move up
BlockEntity tileentity = BlockEntity.loadStatic(blockposition, chunk.getBlockState(blockposition), nbttagcompound1, world.registryAccess());
if (tileentity != null) { if (tileentity != null) {

View File

@ -22,7 +22,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/mai
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// CraftBukkit start // CraftBukkit start
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
@ -54,14 +54,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT @@ -0,0 +0,0 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
} }
public static Optional<Entity> create(CompoundTag nbt, Level world) { public static Optional<Entity> create(CompoundTag nbt, Level world, EntitySpawnReason reason) {
+ // Paper start - Don't fire sync event during generation + // Paper start - Don't fire sync event during generation
+ return create(nbt, world, false); + return create(nbt, world, false);
+ } + }
+ public static Optional<Entity> create(CompoundTag nbt, Level world, boolean generation) { + public static Optional<Entity> create(CompoundTag nbt, Level world, EntitySpawnReason reason, boolean generation) {
+ // Paper end - Don't fire sync event during generation + // Paper end - Don't fire sync event during generation
return Util.ifElse(EntityType.by(nbt).map((entitytypes) -> { return Util.ifElse(EntityType.by(nbt).map((entitytypes) -> {
return entitytypes.create(world); return entitytypes.create(world, reason);
}), (entity) -> { }), (entity) -> {
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation + if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
entity.load(nbt); entity.load(nbt);
@ -127,8 +127,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private static Optional<Entity> createEntityIgnoreException(ServerLevelAccessor world, CompoundTag nbt) { private static Optional<Entity> createEntityIgnoreException(ServerLevelAccessor world, CompoundTag nbt) {
// CraftBukkit start // CraftBukkit start
// try { // try {
- return EntityType.create(nbt, world.getLevel()); - return EntityType.create(nbt, world.getLevel(), EntitySpawnReason.STRUCTURE);
+ return EntityType.create(nbt, world.getLevel(), true); // Paper - Don't fire sync event during generation + return EntityType.create(nbt, world.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation
// } catch (Exception exception) { // } catch (Exception exception) {
// return Optional.empty(); // return Optional.empty();
// } // }
@ -140,26 +140,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.handle.getLevel(); return this.handle.getLevel();
} }
- @Override
- public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) {
- this.handle.addFreshEntityWithPassengers(arg0, arg1);
- }
-
- @Override - @Override
- public void addFreshEntityWithPassengers(Entity entity) { - public void addFreshEntityWithPassengers(Entity entity) {
- this.handle.addFreshEntityWithPassengers(entity); - this.handle.addFreshEntityWithPassengers(entity);
- } - }
-
- @Override
- public void addFreshEntityWithPassengers(Entity entity, CreatureSpawnEvent.SpawnReason reason) {
- this.handle.addFreshEntityWithPassengers(entity, reason);
- }
+ // Paper start - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity + // Paper start - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity
+ // @Override + // @Override
+ // public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) {
+ // this.handle.addFreshEntityWithPassengers(arg0, arg1);
+ // }
+ //
+ // @Override
+ // public void addFreshEntityWithPassengers(Entity entity) { + // public void addFreshEntityWithPassengers(Entity entity) {
+ // this.handle.addFreshEntityWithPassengers(entity); + // this.handle.addFreshEntityWithPassengers(entity);
+ // } + // }
+ // Paper end - Don't fire sync event during generation; don't override these methods + //
+ // @Override
+ // public void addFreshEntityWithPassengers(Entity entity, CreatureSpawnEvent.SpawnReason reason) {
+ // this.handle.addFreshEntityWithPassengers(entity, reason);
+ // }
+ // Paper end - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity
@Override @Override
public ServerLevel getMinecraftWorld() { public ServerLevel getMinecraftWorld() {

View File

@ -137,7 +137,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) - ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager)
+ // ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) // Paper - Don't resend blocks + // ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) // Paper - Don't resend blocks
((ServerPlayer) user).getBukkitEntity().updateInventory(); // SPIGOT-4541 ((ServerPlayer) user).getBukkitEntity().updateInventory(); // SPIGOT-4541
return InteractionResultHolder.fail(itemstack); return InteractionResult.FAIL;
} }
@@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem { @@ -0,0 +0,0 @@ public class BucketItem extends Item implements DispensibleContainerItem {
if (flag2 && entityhuman != null) { if (flag2 && entityhuman != null) {
@ -153,19 +153,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/item/ItemStack.java --- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder { @@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
world.preventPoiUpdated = false; world.preventPoiUpdated = false;
// Brute force all possible updates // Brute force all possible updates
- BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); - BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition();
- for (Direction dir : Direction.values()) { - for (Direction dir : Direction.values()) {
- ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir))); - ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir)));
- } - }
+ // Paper start - Don't resync blocks + // Paper start - Don't resync blocks
+ // BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); + // BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition();
+ // for (Direction dir : Direction.values()) { + // for (Direction dir : Direction.values()) {
+ // ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir))); + // ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir)));
+ // } + // }
+ // Paper end - Don't resync blocks + // Paper end - Don't resync blocks
SignItem.openSign = null; // SPIGOT-6758 - Reset on early return SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
} else { } else {
// Change the stack to its new contents if it hasn't been tampered with. // Change the stack to its new contents if it hasn't been tampered with.

View File

@ -142,7 +142,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
Bukkit.getPluginManager().callEvent(new PlayerRecipeBookSettingsChangeEvent(player.getBukkitEntity(), bukkitType, open, filter)); Bukkit.getPluginManager().callEvent(new PlayerRecipeBookSettingsChangeEvent(player.getBukkitEntity(), bukkitType, open, filter));
} }

View File

@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.ja
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
@@ -0,0 +0,0 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie @@ -0,0 +0,0 @@ public class ThrownPotion extends ThrowableItemProjectile {
boolean noEffects = potioncontents.hasEffects(); // Paper - Fix potions splash events boolean noEffects = potioncontents.hasEffects(); // Paper - Fix potions splash events
// CraftBukkit start // CraftBukkit start
org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, position, entityareaeffectcloud); org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, position, entityareaeffectcloud);

View File

@ -52,7 +52,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
return event; return event;
} }

View File

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/commands/TeleportCommand.java --- a/src/main/java/net/minecraft/server/commands/TeleportCommand.java
+++ b/src/main/java/net/minecraft/server/commands/TeleportCommand.java +++ b/src/main/java/net/minecraft/server/commands/TeleportCommand.java
@@ -0,0 +0,0 @@ public class TeleportCommand { @@ -0,0 +0,0 @@ public class TeleportCommand {
Location to = new Location(world.getWorld(), x, y, z, f2, f3); Location to = new Location(world.getWorld(), d3, d4, d5, f4, f5);
EntityTeleportEvent event = new EntityTeleportEvent(target.getBukkitEntity(), target.getBukkitEntity().getLocation(), to); EntityTeleportEvent event = new EntityTeleportEvent(target.getBukkitEntity(), target.getBukkitEntity().getLocation(), to);
world.getCraftServer().getPluginManager().callEvent(event); world.getCraftServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) { - if (event.isCancelled()) {
@ -23,8 +23,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
+ to = event.getTo(); // Paper - actually track new location + to = event.getTo(); // Paper - actually track new location
x = to.getX(); d3 = to.getX();
y = to.getY(); d4 = to.getY();
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java

View File

@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues { @@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
ResourceLocation minecraftkey = CraftNamespacedKey.toMinecraft(key); ResourceLocation minecraftkey = CraftNamespacedKey.toMinecraft(key);
JsonElement jsonelement = ServerAdvancementManager.GSON.fromJson(advancement, JsonElement.class); JsonElement jsonelement = JsonParser.parseString(advancement);
- net.minecraft.advancements.Advancement nms = net.minecraft.advancements.Advancement.CODEC.parse(JsonOps.INSTANCE, jsonelement).getOrThrow(JsonParseException::new); - net.minecraft.advancements.Advancement nms = net.minecraft.advancements.Advancement.CODEC.parse(JsonOps.INSTANCE, jsonelement).getOrThrow(JsonParseException::new);
+ final net.minecraft.resources.RegistryOps<JsonElement> ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE); // Paper - use RegistryOps + final net.minecraft.resources.RegistryOps<JsonElement> ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE); // Paper - use RegistryOps
+ final net.minecraft.advancements.Advancement nms = net.minecraft.advancements.Advancement.CODEC.parse(ops, jsonelement).getOrThrow(JsonParseException::new); // Paper - use RegistryOps + final net.minecraft.advancements.Advancement nms = net.minecraft.advancements.Advancement.CODEC.parse(ops, jsonelement).getOrThrow(JsonParseException::new); // Paper - use RegistryOps

View File

@ -10,7 +10,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/mai
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@Nullable @Nullable
@Override @Override
public MapItemSavedData getMapData(MapId id) { public MapItemSavedData getMapData(MapId id) {

View File

@ -199,7 +199,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -0,0 +0,0 @@ populateFields(victim, event); // Paper - make cancellable @@ -0,0 +0,0 @@ public class CraftEventFactory {
return event; return event;
} }

View File

@ -22,9 +22,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.usePlayerItem(player, hand, itemstack); this.usePlayerItem(player, hand, itemstack);
- this.setInLove(player); - this.setInLove(player);
+ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying + this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying
return InteractionResult.SUCCESS; this.playEatingSound();
return InteractionResult.SUCCESS_SERVER;
} }
@@ -0,0 +0,0 @@ public abstract class Animal extends AgeableMob { @@ -0,0 +0,0 @@ public abstract class Animal extends AgeableMob {
return this.inLove <= 0; return this.inLove <= 0;
} }
@ -66,28 +66,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- this.setInLove(player); - this.setInLove(player);
+ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying + this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying
} else { } else {
if (this.level().isClientSide || this.isSitting() || this.isInWater()) { Level world = this.level();
return InteractionResult.PASS;
diff --git a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
+++ b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
@@ -0,0 +0,0 @@ public class Armadillo extends Animal {
}
@Override
- public void setInLove(@Nullable Player player) {
- super.setInLove(player);
+ public void setInLove(@Nullable Player player, @Nullable ItemStack breedItemCopy) { // Paper
+ super.setInLove(player, breedItemCopy); // Paper
this.makeSound(SoundEvents.ARMADILLO_EAT);
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java --- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
+++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
@@ -0,0 +0,0 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl @@ -0,0 +0,0 @@ public class Camel extends AbstractHorse {
boolean flag1 = this.isTamed() && this.getAge() == 0 && this.canFallInLove(); boolean flag1 = this.isTamed() && this.getAge() == 0 && this.canFallInLove();
if (flag1) { if (flag1) {

View File

@ -121,9 +121,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/net/minecraft/world/item/MinecartItem.java +++ b/src/main/java/net/minecraft/world/item/MinecartItem.java
@@ -0,0 +0,0 @@ public class MinecartItem extends Item { @@ -0,0 +0,0 @@ public class MinecartItem extends Item {
// CraftBukkit start // CraftBukkit start
if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityminecartabstract).isCancelled()) { if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityminecartabstract).isCancelled()) {
+ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync
return InteractionResult.FAIL; return InteractionResult.FAIL;
} }
// CraftBukkit end // CraftBukkit end

View File

@ -39,18 +39,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
private void spawnFire(int spreadAttempts) { private void spawnFire(int spreadAttempts) {
- if (!this.visualOnly && !this.level().isClientSide && this.level().getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { - if (!this.visualOnly) {
+ if (!this.visualOnly && !this.isEffect && !this.level().isClientSide && this.level().getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { // Paper - Properly handle lightning effects api + if (!this.visualOnly && !this.isEffect) { // Paper - Properly handle lightning effects api
BlockPos blockposition = this.blockPosition(); Level world = this.level();
BlockState iblockdata = BaseFireBlock.getState(this.level(), blockposition);
if (world instanceof ServerLevel) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
LightningBolt lightning = EntityType.LIGHTNING_BOLT.create(this.world); LightningBolt lightning = EntityType.LIGHTNING_BOLT.create(this.world, EntitySpawnReason.COMMAND);
lightning.moveTo(loc.getX(), loc.getY(), loc.getZ()); lightning.moveTo(loc.getX(), loc.getY(), loc.getZ());
- lightning.setVisualOnly(isVisual); - lightning.setVisualOnly(isVisual);
+ lightning.isEffect = isVisual; // Paper - Properly handle lightning effects api + lightning.isEffect = isVisual; // Paper - Properly handle lightning effects api

View File

@ -463,7 +463,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage); PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage);
event.setKeepInventory(keepInventory); event.setKeepInventory(keepInventory);
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
+populateFields(victim, event); // Paper - make cancellable + populateFields(victim, event); // Paper - make cancellable
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
+ // Paper start - make cancellable + // Paper start - make cancellable
+ if (event.isCancelled()) { + if (event.isCancelled()) {

View File

@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
- java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); - java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize());
+ List<DefaultDrop> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper - Restore vanilla drops behavior + List<DefaultDrop> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper - Restore vanilla drops behavior
boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator(); boolean keepInventory = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
if (!keepInventory) { if (!keepInventory) {
for (ItemStack item : this.getInventory().getContents()) { for (ItemStack item : this.getInventory().getContents()) {
@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false
// SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule) // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule)
this.dropFromLootTable(damageSource, this.lastHurtByPlayerTime > 0); this.dropFromLootTable(this.serverLevel(), damageSource, this.lastHurtByPlayerTime > 0);
- this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag); - this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag);
+ // Paper - Restore vanilla drops behaviour; custom death loot is a noop on server player, remove. + // Paper - Restore vanilla drops behaviour; custom death loot is a noop on server player, remove.
@ -43,9 +43,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@Nullable @Nullable
public ItemEntity spawnAtLocation(ItemStack stack, float yOffset) { public ItemEntity spawnAtLocation(ServerLevel world, ItemStack stack, float yOffset) {
+ // Paper start - Restore vanilla drops behavior + // Paper start - Restore vanilla drops behavior
+ return this.spawnAtLocation(stack, yOffset, null); + return this.spawnAtLocation(world, stack, yOffset, null);
+ } + }
+ public record DefaultDrop(Item item, org.bukkit.inventory.ItemStack stack, @Nullable java.util.function.Consumer<ItemStack> dropConsumer) { + public record DefaultDrop(Item item, org.bukkit.inventory.ItemStack stack, @Nullable java.util.function.Consumer<ItemStack> dropConsumer) {
+ public DefaultDrop(final ItemStack stack, final java.util.function.Consumer<ItemStack> dropConsumer) { + public DefaultDrop(final ItemStack stack, final java.util.function.Consumer<ItemStack> dropConsumer) {
@ -61,12 +61,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ @Nullable + @Nullable
+ public ItemEntity spawnAtLocation(ItemStack stack, float yOffset, @Nullable java.util.function.Consumer<? super ItemEntity> delayedAddConsumer) { + public ItemEntity spawnAtLocation(ServerLevel world, ItemStack stack, float yOffset, @Nullable java.util.function.Consumer<? super ItemEntity> delayedAddConsumer) {
+ // Paper end - Restore vanilla drops behavior + // Paper end - Restore vanilla drops behavior
if (stack.isEmpty()) { if (stack.isEmpty()) {
return null; return null;
} else if (this.level().isClientSide) {
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} else { } else {
// CraftBukkit start - Capture drops for death event // CraftBukkit start - Capture drops for death event
if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) { if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) {
@ -82,7 +80,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return null; return null;
} }
// CraftBukkit end // CraftBukkit end
ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack);
stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe
- entityitem.setDefaultPickUpDelay(); - entityitem.setDefaultPickUpDelay();
@ -107,13 +105,13 @@ diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java --- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -0,0 +0,0 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob @@ -0,0 +0,0 @@ public class WitherBoss extends Monster implements RangedAttackMob {
@Override @Override
protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) { protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) {
super.dropCustomDeathLoot(world, source, causedByPlayer); super.dropCustomDeathLoot(world, source, causedByPlayer);
- ItemEntity entityitem = this.spawnAtLocation((ItemLike) Items.NETHER_STAR); - ItemEntity entityitem = this.spawnAtLocation(world, (ItemLike) Items.NETHER_STAR);
- + ItemEntity entityitem = this.spawnAtLocation(world, new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer
+ ItemEntity entityitem = this.spawnAtLocation(new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer
if (entityitem != null) { if (entityitem != null) {
- entityitem.setExtendedLifetime(); - entityitem.setExtendedLifetime();
+ entityitem.setExtendedLifetime(); // Paper - diff on change + entityitem.setExtendedLifetime(); // Paper - diff on change
@ -175,15 +173,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return new Entity.DefaultDrop(CraftItemType.bukkitToMinecraft(stack.getType()), stack, null); + return new Entity.DefaultDrop(CraftItemType.bukkitToMinecraft(stack.getType()), stack, null);
+ }; + };
+ +
+ public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, Runnable lootCheck) { // Paper + public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, Runnable lootCheck) { // Paper - Restore vanilla drops behavior
// Paper end // Paper end
CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity(); CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
- EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()));
+ EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity())); // Paper - Restore vanilla drops behavior
populateFields(victim, event); // Paper - make cancellable
CraftWorld world = (CraftWorld) entity.getWorld(); CraftWorld world = (CraftWorld) entity.getWorld();
- EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(world.getHandle(), damageSource.getEntity()));
+ EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(world.getHandle(), damageSource.getEntity())); // Paper - Restore vanilla drops behavior, victim.getExpReward(world.getHandle(), damageSource.getEntity()));
populateFields(victim, event); // Paper - make cancellable
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
@@ -0,0 +0,0 @@ public class CraftEventFactory { @@ -0,0 +0,0 @@ public class CraftEventFactory {
victim.expToDrop = event.getDroppedExp(); victim.expToDrop = event.getDroppedExp();
lootCheck.run(); // Paper - advancement triggers before destroying items lootCheck.run(); // Paper - advancement triggers before destroying items
@ -193,7 +192,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (Entity.DefaultDrop drop : drops) { + for (Entity.DefaultDrop drop : drops) {
+ if (drop == null) continue; + if (drop == null) continue;
+ final org.bukkit.inventory.ItemStack stack = drop.stack(); + final org.bukkit.inventory.ItemStack stack = drop.stack();
+ // Paper end - Restore vanilla drops behavior + // Paper end - Restore vanilla drops behavior
if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue; if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue;
- world.dropItem(entity.getLocation(), stack); // Paper - note: dropItem already clones due to this being bukkit -> NMS - world.dropItem(entity.getLocation(), stack); // Paper - note: dropItem already clones due to this being bukkit -> NMS
@ -208,8 +207,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior + public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior
CraftPlayer entity = victim.getBukkitEntity(); CraftPlayer entity = victim.getBukkitEntity();
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
- PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(damageSource.getEntity()), 0, deathMessage); - PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage);
+ PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity()), 0, deathMessage); // Paper - Restore vanilla drops behavior + PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage); // Paper - Restore vanilla drops behavior
event.setKeepInventory(keepInventory); event.setKeepInventory(keepInventory);
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
populateFields(victim, event); // Paper - make cancellable populateFields(victim, event); // Paper - make cancellable
@ -222,14 +221,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (Entity.DefaultDrop drop : drops) { + for (Entity.DefaultDrop drop : drops) {
+ if (drop == null) continue; + if (drop == null) continue;
+ final org.bukkit.inventory.ItemStack stack = drop.stack(); + final org.bukkit.inventory.ItemStack stack = drop.stack();
+ // Paper end - Restore vanilla drops behavior + // Paper end - Restore vanilla drops behavior
if (stack == null || stack.getType() == Material.AIR) continue; if (stack == null || stack.getType() == Material.AIR) continue;
- if (stack instanceof CraftItemStack craftItemStack && craftItemStack.isForInventoryDrop()) { - if (stack instanceof CraftItemStack craftItemStack && craftItemStack.isForInventoryDrop()) {
- victim.drop(CraftItemStack.asNMSCopy(stack), true, false, false); // SPIGOT-7800, SPIGOT-7801: Vanilla Behaviour for Player Inventory dropped items - victim.drop(CraftItemStack.asNMSCopy(stack), true, false, false); // SPIGOT-7800, SPIGOT-7801: Vanilla Behaviour for Player Inventory dropped items
- } else { - } else {
- victim.forceDrops = true; - victim.forceDrops = true;
- victim.spawnAtLocation(CraftItemStack.asNMSCopy(stack)); // SPIGOT-7806: Vanilla Behaviour for items not related to Player Inventory dropped items - victim.spawnAtLocation(victim.serverLevel(), CraftItemStack.asNMSCopy(stack)); // SPIGOT-7806: Vanilla Behaviour for items not related to Player Inventory dropped items
- victim.forceDrops = false; - victim.forceDrops = false;
- } - }
+ drop.runConsumer(s -> victim.drop(CraftItemStack.unwrap(s), true, false, false)); // Paper - Restore vanilla drops behavior + drop.runConsumer(s -> victim.drop(CraftItemStack.unwrap(s), true, false, false)); // Paper - Restore vanilla drops behavior