Skip to content

Commit f990b85

Browse files
committed
preserve update flag for block placement around API
1 parent 1a4367e commit f990b85

33 files changed

+189
-162
lines changed

build-data/paper.at

-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ public net.minecraft.server.level.ServerLevel getEntities()Lnet/minecraft/world/
9494
public net.minecraft.server.level.ServerLevel serverLevelData
9595
public net.minecraft.server.level.ServerPlayer completeUsingItem()V
9696
public net.minecraft.server.level.ServerPlayer containerSynchronizer
97-
public net.minecraft.server.level.ServerPlayer findRespawnAndUseSpawnBlock(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;FZZ)Ljava/util/Optional;
9897
public net.minecraft.server.level.ServerPlayer findRespawnAndUseSpawnBlock(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/server/level/ServerPlayer$RespawnConfig;Z)Ljava/util/Optional;
9998
public net.minecraft.server.level.ServerPlayer initMenu(Lnet/minecraft/world/inventory/AbstractContainerMenu;)V
10099
public net.minecraft.server.level.ServerPlayer isChangingDimension

paper-server/patches/sources/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch

+4-3
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@
273273
serverLevel.removeBlock(blockPos, false);
274274
} else {
275275
this.setSuccess(false);
276-
@@ -248,11 +_,62 @@
276+
@@ -248,11 +_,63 @@
277277
this.setSuccess(true);
278278
Level level = blockSource.level();
279279
BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING));
@@ -327,8 +327,9 @@
327327
+
328328
+ if (!fertilizeEvent.isCancelled()) {
329329
+ for (org.bukkit.block.BlockState blockstate : blocks) {
330-
+ blockstate.update(true);
331-
+ blockSource.level().checkCapturedTreeStateForObserverNotify(blockPos, (org.bukkit.craftbukkit.block.CraftBlockState) blockstate); // Paper - notify observers even if grow failed
330+
+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) blocks;
331+
+ craftBlockState.place(craftBlockState.getFlags());
332+
+ blockSource.level().checkCapturedTreeStateForObserverNotify(blockPos, craftBlockState); // Paper - notify observers even if grow failed
332333
+ }
333334
+ }
334335
+ }

paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch

+5-4
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@
345345
Biome biome = this.getBiome(heightmapPos).value();
346346
if (biome.shouldFreeze(this, blockPos1)) {
347347
- this.setBlockAndUpdate(blockPos1, Blocks.ICE.defaultBlockState());
348-
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockPos1, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
348+
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockPos1, Blocks.ICE.defaultBlockState(), 3, null); // CraftBukkit
349349
}
350350

351351
if (this.isRaining()) {
@@ -354,11 +354,11 @@
354354
BlockState blockState1 = blockState.setValue(SnowLayerBlock.LAYERS, layersValue + 1);
355355
Block.pushEntitiesUp(blockState, blockState1, this, heightmapPos);
356356
- this.setBlockAndUpdate(heightmapPos, blockState1);
357-
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, blockState1, null); // CraftBukkit
357+
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, blockState1, 3, null); // CraftBukkit
358358
}
359359
} else {
360360
- this.setBlockAndUpdate(heightmapPos, Blocks.SNOW.defaultBlockState());
361-
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, Blocks.SNOW.defaultBlockState(), null); // CraftBukkit
361+
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, Blocks.SNOW.defaultBlockState(), 3, null); // CraftBukkit
362362
}
363363
}
364364

@@ -1036,7 +1036,7 @@
10361036
return this.entityManager.getEntityGetter();
10371037
}
10381038

1039-
@@ -1699,6 +_,27 @@
1039+
@@ -1699,6 +_,28 @@
10401040
return this.serverLevelData.getGameRules();
10411041
}
10421042

@@ -1051,6 +1051,7 @@
10511051
+ }
10521052
+ // Paper end - respect global sound events gamerule
10531053
+ // Paper start - notify observers even if grow failed
1054+
+ @Deprecated // todo check if needed
10541055
+ public void checkCapturedTreeStateForObserverNotify(final BlockPos pos, final org.bukkit.craftbukkit.block.CraftBlockState craftBlockState) {
10551056
+ // notify observers if the block state is the same and the Y level equals the original y level (for mega trees)
10561057
+ // blocks at the same Y level with the same state can be assumed to be saplings which trigger observers regardless of if the

paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
BlockPos blockPos = new BlockPos(floor, floor1, floor2);
1515
if (this.level().getBlockState(blockPos).isAir() && blockState.canSurvive(this.level(), blockPos)) {
1616
- this.level().setBlockAndUpdate(blockPos, blockState);
17-
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this.level(), blockPos, blockState, this)) continue; // CraftBukkit
17+
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this.level(), blockPos, blockState, 3, this)) continue; // CraftBukkit
1818
this.level().gameEvent(GameEvent.BLOCK_PLACE, blockPos, GameEvent.Context.of(this, blockState));
1919
}
2020
}

paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
this.updateCustomBlockEntityTag(clickedPos, level, player, itemInHand, blockState);
3737
updateBlockEntityComponents(level, clickedPos, itemInHand);
3838
+ } catch (Exception ex) {
39-
+ oldBukkitState.update(true, false);
39+
+ ((org.bukkit.craftbukkit.block.CraftBlockState) oldBukkitState).revertPlace();
4040
+ if (player instanceof ServerPlayer serverPlayer) {
4141
+ org.apache.logging.log4j.LogManager.getLogger().error("Player {} tried placing invalid block", player.getScoreboardName(), ex);
4242
+ serverPlayer.getBukkitEntity().kickPlayer("Packet processing error");
@@ -50,7 +50,7 @@
5050
+ if (bukkitState != null) {
5151
+ org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent((net.minecraft.server.level.ServerLevel) level, player, blockPlaceContext.getHand(), bukkitState, clickedPos.getX(), clickedPos.getY(), clickedPos.getZ());
5252
+ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
53-
+ bukkitState.update(true, false);
53+
+ ((org.bukkit.craftbukkit.block.CraftBlockState) bukkitState).revertPlace();
5454
+
5555
+ // Paper - if the event is called here, the inventory should be updated
5656
+ player.containerMenu.sendAllDataToRemote(); // SPIGOT-4541

paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch

+4-4
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@
7474
+ this.restorePatch(newPatch);
7575
+ this.setCount(newCount);
7676
+ }
77-
+ for (org.bukkit.craftbukkit.block.CraftBlockState blockstate : blocks) {
77+
+ for (org.bukkit.craftbukkit.block.CraftBlockState snapshot : blocks) {
7878
+ // SPIGOT-7572 - Move fix for SPIGOT-7248 to CapturedBlockState, to allow bees in bee nest
79-
+ org.bukkit.craftbukkit.block.CapturedBlockState.setBlockState(blockstate);
80-
+ serverLevel.checkCapturedTreeStateForObserverNotify(clickedPos, blockstate); // Paper - notify observers even if grow failed
79+
+ snapshot.place(snapshot.getFlags());
80+
+ serverLevel.checkCapturedTreeStateForObserverNotify(clickedPos, snapshot); // Paper - notify observers even if grow failed
8181
+ }
8282
+ player.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat
8383
+ }
@@ -107,7 +107,7 @@
107107
+ serverLevel.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710
108108
+ serverLevel.isBlockPlaceCancelled = true; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
109109
+ for (org.bukkit.block.BlockState blockstate : blocks) {
110-
+ blockstate.update(true, false);
110+
+ ((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).revertPlace();
111111
+ }
112112
+ serverLevel.isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
113113
+ serverLevel.preventPoiUpdated = false;

paper-server/patches/sources/net/minecraft/world/item/enchantment/effects/ReplaceBlock.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
BlockPos blockPos = BlockPos.containing(origin).offset(this.offset);
66
if (this.predicate.map(blockPredicate -> blockPredicate.test(level, blockPos)).orElse(true)
77
- && level.setBlockAndUpdate(blockPos, this.blockState.getState(entity.getRandom(), blockPos))) {
8-
+ && org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, blockPos, this.blockState.getState(entity.getRandom(), blockPos), entity)) { // CraftBukkit - Call EntityBlockFormEvent
8+
+ && org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, blockPos, this.blockState.getState(entity.getRandom(), blockPos), 3, entity)) { // CraftBukkit - Call EntityBlockFormEvent
99
this.triggerGameEvent.ifPresent(holder -> level.gameEvent(entity, (Holder<GameEvent>)holder, blockPos));
1010
}
1111
}

paper-server/patches/sources/net/minecraft/world/item/enchantment/effects/ReplaceDisk.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
if (blockPos1.distToCenterSqr(origin.x(), blockPos1.getY() + 0.5, origin.z()) < Mth.square(i)
66
&& this.predicate.map(predicate -> predicate.test(level, blockPos1)).orElse(true)
77
- && level.setBlockAndUpdate(blockPos1, this.blockState.getState(random, blockPos1))) {
8-
+ && org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, blockPos1, this.blockState.getState(random, blockPos1), entity)) { // CraftBukkit - Call EntityBlockFormEvent for Frost Walker
8+
+ && org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, blockPos1, this.blockState.getState(random, blockPos1), 3, entity)) { // CraftBukkit - Call EntityBlockFormEvent for Frost Walker
99
this.triggerGameEvent.ifPresent(event -> level.gameEvent(entity, (Holder<GameEvent>)event, blockPos1));
1010
}
1111
}

paper-server/patches/sources/net/minecraft/world/level/Level.java.patch

+11-6
Original file line numberDiff line numberDiff line change
@@ -361,17 +361,22 @@
361361
if (this.isOutsideBuildHeight(pos)) {
362362
return false;
363363
} else if (!this.isClientSide && this.isDebug()) {
364-
@@ -219,11 +_,26 @@
364+
@@ -219,11 +_,31 @@
365365
} else {
366366
LevelChunk chunkAt = this.getChunkAt(pos);
367367
Block block = state.getBlock();
368368
+ // CraftBukkit start - capture blockstates
369369
+ boolean captured = false;
370-
+ if (this.captureBlockStates && !this.capturedBlockStates.containsKey(pos)) {
371-
+ CraftBlockState blockstate = (CraftBlockState) world.getBlockAt(pos.getX(), pos.getY(), pos.getZ()).getState(); // Paper - use CB getState to get a suitable snapshot
372-
+ blockstate.setFlags(flags); // Paper - set flag
373-
+ this.capturedBlockStates.put(pos.immutable(), blockstate);
374-
+ captured = true;
370+
+ if (this.captureBlockStates) {
371+
+ final CraftBlockState snapshot;
372+
+ if (!this.capturedBlockStates.containsKey(pos)) {
373+
+ snapshot = (CraftBlockState) world.getBlockAt(pos.getX(), pos.getY(), pos.getZ()).getState(); // Paper - use CB getState to get a suitable snapshot
374+
+ this.capturedBlockStates.put(pos.immutable(), snapshot);
375+
+ captured = true;
376+
+ } else {
377+
+ snapshot = this.capturedBlockStates.get(pos);
378+
+ }
379+
+ snapshot.setFlags(flags); // Paper - always set the flag of the most recent call to mitigate issues with multiple update at the same pos with different flags
375380
+ }
376381
BlockState blockState = chunkAt.setBlockState(pos, state, flags);
377382
+ // CraftBukkit end

paper-server/patches/sources/net/minecraft/world/level/block/BuddingAmethystBlock.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
+ if (block == Blocks.SMALL_AMETHYST_BUD) {
1010
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, blockState1, 3); // CraftBukkit
1111
+ } else {
12-
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, blockState1);
12+
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, blockState1, 3);
1313
+ }
1414
+ // Paper end - Have Amethyst throw both spread and grow events
1515
}

paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
double d = i >= 3 ? 0.25 : 0.1;
1515
if (random.nextDouble() <= d) {
1616
- level.setBlockAndUpdate(blockPos, Blocks.CACTUS_FLOWER.defaultBlockState());
17-
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, Blocks.CACTUS_FLOWER.defaultBlockState());
17+
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, Blocks.CACTUS_FLOWER.defaultBlockState(), 3);
1818
}
1919
- } else if (ageValue == 15 && i < 3) {
2020
- level.setBlockAndUpdate(blockPos, this.defaultBlockState());

paper-server/patches/sources/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch

+15-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
} else if (ageValue < 4) {
1212
int i = random.nextInt(4);
1313
if (flag1) {
14-
@@ -112,18 +_,28 @@
14+
@@ -112,30 +_,40 @@
1515
if (level.isEmptyBlock(blockPos1)
1616
&& level.isEmptyBlock(blockPos1.below())
1717
&& allNeighborsEmpty(level, blockPos1, randomDirection.getOpposite())) {
@@ -40,6 +40,20 @@
4040
}
4141
}
4242
}
43+
}
44+
45+
private void placeGrownFlower(Level level, BlockPos pos, int age) {
46+
- level.setBlock(pos, this.defaultBlockState().setValue(AGE, age), 2);
47+
+ // level.setBlock(pos, this.defaultBlockState().setValue(AGE, age), 2); // Paper - already done above in the event call
48+
level.levelEvent(1033, pos, 0);
49+
}
50+
51+
private void placeDeadFlower(Level level, BlockPos pos) {
52+
- level.setBlock(pos, this.defaultBlockState().setValue(AGE, 5), 2);
53+
+ // level.setBlock(pos, this.defaultBlockState().setValue(AGE, 5), 2); // Paper - already done above in the event call
54+
level.levelEvent(1034, pos, 0);
55+
}
56+
4357
@@ -261,6 +_,11 @@
4458
protected void onProjectileHit(Level level, BlockState state, BlockHitResult hit, Projectile projectile) {
4559
BlockPos blockPos = hit.getBlockPos();

paper-server/patches/sources/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
BlockPos blockPos = pos.relative(this.growthDirection);
2222
if (this.canGrowInto(level.getBlockState(blockPos))) {
2323
- level.setBlockAndUpdate(blockPos, this.getGrowIntoState(state, level.random));
24-
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, this.getGrowIntoState(state, level.random, level)); // CraftBukkit // Paper - Fix Spigot growth modifiers
24+
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, this.getGrowIntoState(state, level.random, level), 3); // CraftBukkit // Paper - Fix Spigot growth modifiers
2525
}
2626
}
2727
}

paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
+
5454
+ public static boolean changeLevel(Level level, BlockPos pos, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable
5555
+ // Paper end - Call CauldronLevelChangeEvent
56-
+ org.bukkit.craftbukkit.block.CraftBlockState newState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(level, pos, 3);
56+
+ org.bukkit.craftbukkit.block.CraftBlockState newState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(level, pos);
5757
+ newState.setData(newBlock);
5858
+
5959
+ org.bukkit.event.block.CauldronLevelChangeEvent event = new org.bukkit.event.block.CauldronLevelChangeEvent(
@@ -63,7 +63,7 @@
6363
+ if (!event.callEvent()) {
6464
+ return false;
6565
+ }
66-
+ newState.update(true);
66+
+ newState.place(3);
6767
+ if (sendGameEvent) level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(newBlock)); // Paper - Call CauldronLevelChangeEvent
6868
+ return true;
6969
+ }

paper-server/patches/sources/net/minecraft/world/level/block/RootedDirtBlock.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
@Override
66
public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) {
77
- level.setBlockAndUpdate(pos.below(), Blocks.HANGING_ROOTS.defaultBlockState());
8-
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, pos.below(), Blocks.HANGING_ROOTS.defaultBlockState()); // CraftBukkit
8+
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, pos.below(), Blocks.HANGING_ROOTS.defaultBlockState(), 3); // CraftBukkit
99
}
1010

1111
@Override

paper-server/patches/sources/net/minecraft/world/level/block/SaplingBlock.java.patch

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
this.advanceTree(level, pos, state, random);
1818
}
1919
}
20-
@@ -53,7 +_,33 @@
20+
@@ -53,7 +_,34 @@
2121
if (state.getValue(STAGE) == 0) {
2222
level.setBlock(pos, state.cycle(STAGE), 260);
2323
} else {
@@ -42,8 +42,9 @@
4242
+ }
4343
+ if (event == null || !event.isCancelled()) {
4444
+ for (org.bukkit.block.BlockState blockstate : blocks) {
45-
+ org.bukkit.craftbukkit.block.CapturedBlockState.setBlockState(blockstate);
46-
+ level.checkCapturedTreeStateForObserverNotify(pos, (org.bukkit.craftbukkit.block.CraftBlockState) blockstate); // Paper - notify observers even if grow failed
45+
+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) blockstate;
46+
+ craftBlockState.place(craftBlockState.getFlags());
47+
+ level.checkCapturedTreeStateForObserverNotify(pos, craftBlockState); // Paper - notify observers even if grow failed
4748
+ }
4849
+ }
4950
+ }

paper-server/patches/sources/net/minecraft/world/level/block/SpongeBlock.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
+ // Paper end - Fix SpongeAbsortEvent handling
8686
+ }
8787
+ }
88-
+ level.setBlock(blockPos, block.getHandle(), block.getFlags());
88+
+ block.place(block.getFlags());
8989
+ }
9090
+
9191
+ return true;

paper-server/patches/sources/net/minecraft/world/level/block/StemBlock.java.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
if (optional.isPresent() && optional1.isPresent()) {
2121
- level.setBlockAndUpdate(blockPos, optional.get().defaultBlockState());
2222
+ // CraftBukkit start
23-
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, optional.get().defaultBlockState())) {
23+
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, optional.get().defaultBlockState(), 3)) {
2424
+ return;
2525
+ }
2626
+ // CraftBukkit end

0 commit comments

Comments
 (0)