Paper/patches/server/0848-Fire-EntityChangeBlockEvent-in-more-places.patch
Nassim Jahnke f6969b6374
Updated Upstream (Bukkit/CraftBukkit/Spigot)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
09b1c123 PR-916: Add more lightning API
c085f3de PR-859: Add Entity#getTrackedBy

CraftBukkit Changes:
1bf30a4e9 SPIGOT-7495: Spawning bee entity in asynchronous BlockPopulator causes IllegalStateException - Accessing LegacyRandomSource from multiple threads
476c5bccd PR-1267: Add more lightning API
40d5e6c02 PR-1190: Add Entity#getTrackedBy
40d41acc1 SPIGOT-7491: Downgrade bundled SQLite to be updated next release
44b31da38 PR-1264: Load Bukkit class before creating Registry item
dc45a6738 SPIGOT-7496: Failure to load datapacks with multiple identical predicates
f508657d6 Fix decompile error affecting javac
ef7a4743d PR-1265: Ensure UTF-8 used in new test resource

Spigot Changes:
224dad51 Rebuild patches
2023-10-03 22:00:24 +10:00

275 lines
17 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Mon, 9 Aug 2021 20:45:46 -0700
Subject: [PATCH] Fire EntityChangeBlockEvent in more places
Co-authored-by: ChristopheG <61288881+chrisgdt@users.noreply.github.com>
diff --git a/src/main/java/net/minecraft/world/entity/LightningBolt.java b/src/main/java/net/minecraft/world/entity/LightningBolt.java
index 21cdbd96ecbe2a6c8f7b2e3f20aed6c175f3732b..471275c5362b61ce8b5b9dd5c85b3e93cabd3f76 100644
--- a/src/main/java/net/minecraft/world/entity/LightningBolt.java
+++ b/src/main/java/net/minecraft/world/entity/LightningBolt.java
@@ -98,7 +98,7 @@ public class LightningBolt extends Entity {
}
this.powerLightningRod();
- LightningBolt.clearCopperOnLightningStrike(this.level(), this.getStrikePosition());
+ LightningBolt.clearCopperOnLightningStrike(this.level(), this.getStrikePosition(), this); // Paper - transmit LightningBolt instance to call EntityChangeBlockEvent
this.gameEvent(GameEvent.LIGHTNING_STRIKE);
}
}
@@ -192,7 +192,7 @@ public class LightningBolt extends Entity {
}
}
- private static void clearCopperOnLightningStrike(Level world, BlockPos pos) {
+ private static void clearCopperOnLightningStrike(Level world, BlockPos pos, Entity lightning) { // Paper - transmit LightningBolt instance to call EntityChangeBlockEvent
BlockState iblockdata = world.getBlockState(pos);
BlockPos blockposition1;
BlockState iblockdata1;
@@ -206,24 +206,29 @@ public class LightningBolt extends Entity {
}
if (iblockdata1.getBlock() instanceof WeatheringCopper) {
- world.setBlockAndUpdate(blockposition1, WeatheringCopper.getFirst(world.getBlockState(blockposition1)));
+ // Paper start - call EntityChangeBlockEvent
+ BlockState newBlock = WeatheringCopper.getFirst(world.getBlockState(blockposition1));
+ if (CraftEventFactory.callEntityChangeBlockEvent(lightning, blockposition1, newBlock)) {
+ world.setBlockAndUpdate(blockposition1, newBlock);
+ }
+ // Paper end
BlockPos.MutableBlockPos blockposition_mutableblockposition = pos.mutable();
int i = world.random.nextInt(3) + 3;
for (int j = 0; j < i; ++j) {
int k = world.random.nextInt(8) + 1;
- LightningBolt.randomWalkCleaningCopper(world, blockposition1, blockposition_mutableblockposition, k);
+ LightningBolt.randomWalkCleaningCopper(world, blockposition1, blockposition_mutableblockposition, k, lightning); // Paper - transmit LightningBolt instance to call EntityChangeBlockEvent
}
}
}
- private static void randomWalkCleaningCopper(Level world, BlockPos pos, BlockPos.MutableBlockPos mutablePos, int count) {
+ private static void randomWalkCleaningCopper(Level world, BlockPos pos, BlockPos.MutableBlockPos mutablePos, int count, Entity lightning) { // Paper - transmit LightningBolt instance to call EntityChangeBlockEvent
mutablePos.set(pos);
for (int j = 0; j < count; ++j) {
- Optional<BlockPos> optional = LightningBolt.randomStepCleaningCopper(world, mutablePos);
+ Optional<BlockPos> optional = LightningBolt.randomStepCleaningCopper(world, mutablePos, lightning); // Paper - transmit LightningBolt instance to call EntityChangeBlockEvent
if (optional.isEmpty()) {
break;
@@ -234,7 +239,7 @@ public class LightningBolt extends Entity {
}
- private static Optional<BlockPos> randomStepCleaningCopper(Level world, BlockPos pos) {
+ private static Optional<BlockPos> randomStepCleaningCopper(Level world, BlockPos pos, Entity lightning) { // Paper - transmit LightningBolt instance to call EntityChangeBlockEvent
Iterator iterator = BlockPos.randomInCube(world.random, 10, pos, 1).iterator();
BlockPos blockposition1;
@@ -251,6 +256,7 @@ public class LightningBolt extends Entity {
BlockPos blockposition1Final = blockposition1; // CraftBukkit - decompile error
WeatheringCopper.getPrevious(iblockdata).ifPresent((iblockdata1) -> {
+ if (CraftEventFactory.callEntityChangeBlockEvent(lightning, blockposition1Final, iblockdata1)) // Paper - call EntityChangeBlockEvent
world.setBlockAndUpdate(blockposition1Final, iblockdata1); // CraftBukkit - decompile error
});
world.levelEvent(3002, blockposition1, -1);
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java
index 2c443b421e342ebfbdf941a431ba20560521920b..91b68ee3605afdb845405e455c869e48a7fc9aab 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TryLaySpawnOnWaterNearLand.java
@@ -27,6 +27,12 @@ public class TryLaySpawnOnWaterNearLand {
BlockPos blockPos3 = blockPos2.above();
if (world.getBlockState(blockPos3).isAir()) {
BlockState blockState = frogSpawn.defaultBlockState();
+ // Paper start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, blockPos3, blockState)) {
+ isPregnant.erase(); // forgot pregnant memory
+ return true;
+ }
+ // Paper end
world.setBlock(blockPos3, blockState, 3);
world.gameEvent(GameEvent.BLOCK_PLACE, blockPos3, GameEvent.Context.of(entity, blockState));
world.playSound((Player)null, entity, SoundEvents.FROG_LAY_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F);
diff --git a/src/main/java/net/minecraft/world/item/AxeItem.java b/src/main/java/net/minecraft/world/item/AxeItem.java
index 2f8ae1786a4c4438515c59fa56acaefdff60703d..18898e16ec42f6b694b06e09d9174b60d62450d7 100644
--- a/src/main/java/net/minecraft/world/item/AxeItem.java
+++ b/src/main/java/net/minecraft/world/item/AxeItem.java
@@ -54,6 +54,11 @@ public class AxeItem extends DiggerItem {
}
if (optional4.isPresent()) {
+ // Paper start - EntityChangeBlockEvent
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional4.get())) {
+ return InteractionResult.PASS;
+ }
+ // Paper end
if (player instanceof ServerPlayer) {
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack);
}
diff --git a/src/main/java/net/minecraft/world/item/EnderEyeItem.java b/src/main/java/net/minecraft/world/item/EnderEyeItem.java
index 1fddc9025a9e5079f05dd6c86f6ca43c5d51d9c3..6d45e3ebea6721b9c168fea572e9bd610eb54431 100644
--- a/src/main/java/net/minecraft/world/item/EnderEyeItem.java
+++ b/src/main/java/net/minecraft/world/item/EnderEyeItem.java
@@ -43,6 +43,11 @@ public class EnderEyeItem extends Item {
return InteractionResult.SUCCESS;
} else {
BlockState iblockdata1 = (BlockState) iblockdata.setValue(EndPortalFrameBlock.HAS_EYE, true);
+ // Paper start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(context.getPlayer(), blockposition, iblockdata1)) {
+ return InteractionResult.PASS;
+ }
+ // Paper end
Block.pushEntitiesUp(iblockdata, iblockdata1, world, blockposition);
world.setBlock(blockposition, iblockdata1, 2);
diff --git a/src/main/java/net/minecraft/world/item/HoneycombItem.java b/src/main/java/net/minecraft/world/item/HoneycombItem.java
index 5ab115834cddb9ab3209c11bd0fe657b06a02eb2..eaa263db594d5cf8758c8205ea06bbd37d56cdd4 100644
--- a/src/main/java/net/minecraft/world/item/HoneycombItem.java
+++ b/src/main/java/net/minecraft/world/item/HoneycombItem.java
@@ -39,6 +39,14 @@ public class HoneycombItem extends Item implements SignApplicator {
return getWaxed(blockState).map((state) -> {
Player player = context.getPlayer();
ItemStack itemStack = context.getItemInHand();
+ // Paper start - EntityChangeBlockEvent
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, state)) {
+ if (!player.isCreative()) {
+ player.containerMenu.sendAllDataToRemote();
+ }
+ return InteractionResult.PASS;
+ }
+ // Paper end
if (player instanceof ServerPlayer) {
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack);
}
diff --git a/src/main/java/net/minecraft/world/item/PotionItem.java b/src/main/java/net/minecraft/world/item/PotionItem.java
index 8c79ca75089e739d4899421106833e42e4e57280..88df7093c47f2a90f79a55797a04d7e4f51ed549 100644
--- a/src/main/java/net/minecraft/world/item/PotionItem.java
+++ b/src/main/java/net/minecraft/world/item/PotionItem.java
@@ -107,6 +107,12 @@ public class PotionItem extends Item {
BlockState iblockdata = world.getBlockState(blockposition);
if (context.getClickedFace() != Direction.DOWN && iblockdata.is(BlockTags.CONVERTABLE_TO_MUD) && PotionUtils.getPotion(itemstack) == Potions.WATER) {
+ // Paper start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityhuman, blockposition, Blocks.MUD.defaultBlockState())) {
+ entityhuman.containerMenu.sendAllDataToRemote();
+ return InteractionResult.PASS;
+ }
+ // Paper end
world.playSound((Player) null, blockposition, SoundEvents.GENERIC_SPLASH, SoundSource.BLOCKS, 1.0F, 1.0F);
entityhuman.setItemInHand(context.getHand(), ItemUtils.createFilledResult(itemstack, entityhuman, new ItemStack(Items.GLASS_BOTTLE)));
entityhuman.awardStat(Stats.ITEM_USED.get(itemstack.getItem()));
diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java
index 32995cb5efdad0bc34ecacacb78cccd21220ba8d..21212462e6b415e96536a27b2c009d1562f18946 100644
--- a/src/main/java/net/minecraft/world/item/ShovelItem.java
+++ b/src/main/java/net/minecraft/world/item/ShovelItem.java
@@ -36,20 +36,29 @@ public class ShovelItem extends DiggerItem {
Player player = context.getPlayer();
BlockState blockState2 = FLATTENABLES.get(blockState.getBlock());
BlockState blockState3 = null;
+ Runnable afterAction = null; // Paper
if (blockState2 != null && level.getBlockState(blockPos.above()).isAir()) {
- level.playSound(player, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);
+ afterAction = () -> level.playSound(player, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper
blockState3 = blockState2;
} else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) {
+ afterAction = () -> { // Paper
if (!level.isClientSide()) {
level.levelEvent((Player)null, 1009, blockPos, 0);
}
CampfireBlock.dowse(context.getPlayer(), level, blockPos, blockState);
+ }; // Paper
blockState3 = blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false));
}
if (blockState3 != null) {
if (!level.isClientSide) {
+ // Paper start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(context.getPlayer(), blockPos, blockState3)) {
+ return InteractionResult.PASS;
+ }
+ afterAction.run();
+ // Paper end
level.setBlock(blockPos, blockState3, 11);
level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, blockState3));
if (player != null) {
diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
index 4f24d5453522c68c22f15beed87e5237163c701a..38cb52d185e543c4df9eebfcd856df6fa80ba0ed 100644
--- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
@@ -231,6 +231,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(itemstack.getItem())) {
if (i < 7 && !world.isClientSide) {
BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, itemstack);
+ // Paper start - handle cancelled events
+ if (iblockdata1 == null) {
+ return InteractionResult.PASS;
+ }
+ // Paper end
world.levelEvent(1500, pos, state != iblockdata1 ? 1 : 0);
player.awardStat(Stats.ITEM_USED.get(itemstack.getItem()));
@@ -254,11 +259,16 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
if (i < 7 && ComposterBlock.COMPOSTABLES.containsKey(stack.getItem())) {
// CraftBukkit start
double rand = world.getRandom().nextDouble();
- BlockState iblockdata1 = ComposterBlock.addItem(user, state, DummyGeneratorAccess.INSTANCE, pos, stack, rand);
- if (state == iblockdata1 || !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(user, pos, iblockdata1)) {
+ BlockState iblockdata1 = null; // Paper
+ if (false && (state == iblockdata1 || !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(user, pos, iblockdata1))) { // Paper - move event call into addItem
return state;
}
iblockdata1 = ComposterBlock.addItem(user, state, world, pos, stack, rand);
+ // Paper start - handle cancelled events
+ if (iblockdata1 == null) {
+ return state;
+ }
+ // Paper end
// CraftBukkit end
stack.shrink(1);
@@ -299,11 +309,13 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
return iblockdata1;
}
+ @Nullable // Paper
static BlockState addItem(@Nullable Entity user, BlockState state, LevelAccessor world, BlockPos pos, ItemStack stack) {
// CraftBukkit start
return ComposterBlock.addItem(user, state, world, pos, stack, world.getRandom().nextDouble());
}
+ @Nullable // Paper - make it nullable
static BlockState addItem(@Nullable Entity entity, BlockState iblockdata, LevelAccessor generatoraccess, BlockPos blockposition, ItemStack itemstack, double rand) {
// CraftBukkit end
int i = (Integer) iblockdata.getValue(ComposterBlock.LEVEL);
@@ -314,6 +326,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
} else {
int j = i + 1;
BlockState iblockdata1 = (BlockState) iblockdata.setValue(ComposterBlock.LEVEL, j);
+ // Paper start - move the EntityChangeBlockEvent here to avoid conflict later for the compost events
+ if (entity != null && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition, iblockdata1)) {
+ return null;
+ }
+ // Paper end
generatoraccess.setBlock(blockposition, iblockdata1, 3);
generatoraccess.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, iblockdata1));
diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
index 1233788274f1cbdaa564d3145214b4908ae1f573..23ee60e8843a6a05e7ae6512248a57ec2a08321b 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
@@ -120,7 +120,7 @@ public class DummyGeneratorAccess implements WorldGenLevel {
@Override
public void gameEvent(GameEvent event, Vec3 emitterPos, GameEvent.Context emitter) {
- // Used by BlockComposter
+ // Used by ComposterBlock
}
@Override