aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0739-Fire-EntityChangeBlockEvent-in-more-places.patch
blob: bafa064971a4ad4bd5dc1b5f870f1b271f6a054e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
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>
Co-authored-by: maxcom1 <46265094+maxcom1@users.noreply.github.com>

diff --git a/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java b/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java
index 6a84eaeddd0d7f050053c8aa0659d6811192aad4..1b2d41a6c6f149701c8a78f3d345f45069f1f857 100644
--- a/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/WeavingMobEffect.java
@@ -25,11 +25,11 @@ class WeavingMobEffect extends MobEffect {
     @Override
     public void onMobRemoved(LivingEntity entity, int amplifier, Entity.RemovalReason reason) {
         if (reason == Entity.RemovalReason.KILLED && (entity instanceof Player || entity.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) {
-            this.spawnCobwebsRandomlyAround(entity.level(), entity.getRandom(), entity.getOnPos());
+            this.spawnCobwebsRandomlyAround(entity, entity.level(), entity.getRandom(), entity.getOnPos()); // Paper - Fire EntityChangeBlockEvent in more places
         }
     }
 
-    private void spawnCobwebsRandomlyAround(Level world, RandomSource random, BlockPos pos) {
+    private void spawnCobwebsRandomlyAround(LivingEntity entity, Level world, RandomSource random, BlockPos pos) { // Paper - Fire EntityChangeBlockEvent in more places
         Set<BlockPos> set = Sets.newHashSet();
         int i = this.maxCobwebs.applyAsInt(random);
 
@@ -46,6 +46,7 @@ class WeavingMobEffect extends MobEffect {
         }
 
         for (BlockPos blockPos3 : set) {
+            if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, blockPos3, Blocks.COBWEB.defaultBlockState())) continue; // Paper - Fire EntityChangeBlockEvent in more places
             world.setBlock(blockPos3, Blocks.COBWEB.defaultBlockState(), 3);
             world.levelEvent(3018, blockPos3, 0);
         }
diff --git a/src/main/java/net/minecraft/world/entity/LightningBolt.java b/src/main/java/net/minecraft/world/entity/LightningBolt.java
index bf5015c4bb68e5c46313bab1e59c0a4d45053b73..0471d9c85af02133f99cca4e181b83b58a3f1abc 100644
--- a/src/main/java/net/minecraft/world/entity/LightningBolt.java
+++ b/src/main/java/net/minecraft/world/entity/LightningBolt.java
@@ -99,7 +99,7 @@ public class LightningBolt extends Entity {
                 }
 
                 this.powerLightningRod();
-                LightningBolt.clearCopperOnLightningStrike(this.level(), this.getStrikePosition());
+                LightningBolt.clearCopperOnLightningStrike(this.level(), this.getStrikePosition(), this); // Paper - Call EntityChangeBlockEvent
                 this.gameEvent(GameEvent.LIGHTNING_STRIKE);
             }
         }
@@ -193,7 +193,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 - Call EntityChangeBlockEvent
         BlockState iblockdata = world.getBlockState(pos);
         BlockPos blockposition1;
         BlockState iblockdata1;
@@ -207,24 +207,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 - Call EntityChangeBlockEvent
             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;
@@ -235,7 +240,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;
@@ -252,6 +257,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/item/AxeItem.java b/src/main/java/net/minecraft/world/item/AxeItem.java
index c227784544e52ee2c75ab1a2181e0b0ba7246f4b..f005ea92449cf5e249ff64f4791c3bc6b8635528 100644
--- a/src/main/java/net/minecraft/world/item/AxeItem.java
+++ b/src/main/java/net/minecraft/world/item/AxeItem.java
@@ -65,6 +65,11 @@ public class AxeItem extends DiggerItem {
                 return InteractionResult.PASS;
             } else {
                 ItemStack itemStack = context.getItemInHand();
+                // Paper start - EntityChangeBlockEvent
+                if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional.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 391579b515c5a07066f82b33c4f9ef8ee1d05530..d8ce44a180f848f4c9c04967470c4359af979b2f 100644
--- a/src/main/java/net/minecraft/world/item/EnderEyeItem.java
+++ b/src/main/java/net/minecraft/world/item/EnderEyeItem.java
@@ -46,6 +46,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 decabf6fccaca3d1bfeba679ac71677d33315f5e..14d37bf64af719eae3ea154ea7f952cc27712b57 100644
--- a/src/main/java/net/minecraft/world/item/HoneycombItem.java
+++ b/src/main/java/net/minecraft/world/item/HoneycombItem.java
@@ -74,6 +74,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 92fa6523f2bba105a74fff228e36e58666ed56ae..d147b24bb57b322d3f5f4a9eb8cfef2acdd9e0f5 100644
--- a/src/main/java/net/minecraft/world/item/PotionItem.java
+++ b/src/main/java/net/minecraft/world/item/PotionItem.java
@@ -109,6 +109,12 @@ public class PotionItem extends Item {
         BlockState iblockdata = world.getBlockState(blockposition);
 
         if (context.getClickedFace() != Direction.DOWN && iblockdata.is(BlockTags.CONVERTABLE_TO_MUD) && potioncontents.is(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 c0e96284bb470353c0e54ad4e0c2205017913e61..24f6a158e4759aac3be8da4cf5e0d40bd295355b 100644
--- a/src/main/java/net/minecraft/world/item/ShovelItem.java
+++ b/src/main/java/net/minecraft/world/item/ShovelItem.java
@@ -46,20 +46,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(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/CakeBlock.java b/src/main/java/net/minecraft/world/level/block/CakeBlock.java
index d72f4a01ca07df8a9678b3ca4707e5363e482283..43e306b5ef00b39923c1597f212b4a07fb95f1ca 100644
--- a/src/main/java/net/minecraft/world/level/block/CakeBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CakeBlock.java
@@ -65,6 +65,12 @@ public class CakeBlock extends Block {
             if (block instanceof CandleBlock) {
                 CandleBlock candleblock = (CandleBlock) block;
 
+                // Paper start - call change block event
+                if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, CandleCakeBlock.byCandle(candleblock))) {
+                    player.containerMenu.sendAllDataToRemote(); // update inv because candle could decrease
+                    return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
+                }
+                // Paper end - call change block event
                 stack.consume(1, player);
                 world.playSound((Player) null, pos, SoundEvents.CAKE_ADD_CANDLE, SoundSource.BLOCKS, 1.0F, 1.0F);
                 world.setBlockAndUpdate(pos, CandleCakeBlock.byCandle(candleblock));
@@ -96,6 +102,14 @@ public class CakeBlock extends Block {
         if (!player.canEat(false)) {
             return InteractionResult.PASS;
         } else {
+            // Paper start - call change block event
+            int i = state.getValue(CakeBlock.BITES);
+            final BlockState newState = i < MAX_BITES ? state.setValue(CakeBlock.BITES, i + 1) : world.getFluidState(pos).createLegacyBlock();
+            if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, newState)) {
+                ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().sendHealthUpdate();
+                return InteractionResult.PASS; // return a non-consume result to cake blocks don't drop their candles
+            }
+            // Paper end - call change block event
             player.awardStat(Stats.EAT_CAKE_SLICE);
             // CraftBukkit start
             // entityhuman.getFoodData().eat(2, 0.1F);
@@ -109,7 +123,7 @@ public class CakeBlock extends Block {
 
             ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().sendHealthUpdate();
             // CraftBukkit end
-            int i = (Integer) state.getValue(CakeBlock.BITES);
+            // Paper - move up
 
             world.gameEvent((Entity) player, (Holder) GameEvent.EAT, pos);
             if (i < 6) {
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 804adb5ed92dfcf4c29c756dd95d7164150a9666..19fa8a9f935e9063497f8c0bd7909036fa0af2b7 100644
--- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
@@ -239,6 +239,11 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
         if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(stack.getItem())) {
             if (i < 7 && !world.isClientSide) {
                 BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, stack);
+                // Paper start - handle cancelled events
+                if (iblockdata1 == null) {
+                    return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION;
+                }
+                // Paper end
 
                 world.levelEvent(1500, pos, state != iblockdata1 ? 1 : 0);
                 player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
@@ -269,11 +274,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);
@@ -314,11 +324,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);
@@ -329,6 +341,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((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, iblockdata1));
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
index ef8a0236ab4fb648c4bb2a8cfc90e3cefe8f9f1d..1a3d8755c8f6a7cfe06069e2082d8147aaaff097 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
@@ -259,7 +259,13 @@ public class BeehiveBlockEntity extends BlockEntity {
                                         --j;
                                     }
 
-                                    world.setBlockAndUpdate(blockposition, (BlockState) iblockdata.setValue(BeehiveBlock.HONEY_LEVEL, i + j));
+                                    // Paper start - Fire EntityChangeBlockEvent in more places
+                                    BlockState newBlockState = iblockdata.setValue(BeehiveBlock.HONEY_LEVEL, i + j);
+
+                                    if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entitybee, blockposition, newBlockState)) {
+                                        world.setBlockAndUpdate(blockposition, newBlockState);
+                                    }
+                                    // Paper end - Fire EntityChangeBlockEvent in more places
                                 }
                             }
                         }
diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
index daf3c26fce7569761951bfd5594c6726d854a9ff..e8a73d34dbb372581b03018aade170a31c266099 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(Holder<GameEvent> event, Vec3 emitterPos, GameEvent.Context emitter) {
-        // Used by BlockComposter
+        // Used by ComposterBlock
     }
 
     @Override