diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch index 61a4fc8a78..54f850ca56 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/LayeredCauldronBlock.java +++ b/net/minecraft/world/level/block/LayeredCauldronBlock.java -@@ -79,39 +_,67 @@ +@@ -79,39 +_,71 @@ @Override protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) { @@ -11,13 +11,17 @@ - if (entity1.isOnFire() && entity1.mayInteract(serverLevel, blockPos)) { - this.handleEntityOnFireInside(state, level, blockPos); + if (entity1.isOnFire() && (entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity1.mayInteract(serverLevel, blockPos)) { // Paper - Fixes MC-248588 -+ this.handleEntityOnFireInside(state, level, blockPos, entity); // Paper - Track entity ++ // Paper start - cauldron level change event ++ if (this.handleEntityOnFireInside(state, level, blockPos, entity1)) { // Paper - track entity ++ InsideBlockEffectType.EXTINGUISH.effect().affect(entity1, blockPos); // apply extinguishing if event was not cancelled. ++ } ++ // Paper end - cauldron level change event } }); } - effectApplier.apply(InsideBlockEffectType.EXTINGUISH); -+ effectApplier.apply(InsideBlockEffectType.EXTINGUISH); // TODO: THE EVENT ??????????????????????????????????? ++ // effectApplier.apply(InsideBlockEffectType.EXTINGUISH); // Paper - manually applied above - cauldron level change event - delay to not extinguish when event is cancelled } - private void handleEntityOnFireInside(BlockState state, Level level, BlockPos pos) { diff --git a/paper-server/src/test/java/io/papermc/paper/contract/StepBasedCollectorRunBeforeTest.java b/paper-server/src/test/java/io/papermc/paper/contract/StepBasedCollectorRunBeforeTest.java new file mode 100644 index 0000000000..8c6292ea17 --- /dev/null +++ b/paper-server/src/test/java/io/papermc/paper/contract/StepBasedCollectorRunBeforeTest.java @@ -0,0 +1,38 @@ +package io.papermc.paper.contract; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.InsideBlockEffectApplier.StepBasedCollector; +import net.minecraft.world.entity.InsideBlockEffectType; +import net.minecraft.world.entity.animal.Pig; +import org.bukkit.support.environment.AllFeatures; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +/** + * Simple test ensuring that the {@link StepBasedCollector} executes calls to {@link StepBasedCollector#runBefore(InsideBlockEffectType, Consumer)} + * even if the effect is never registered. + *
+ * Paper relies on this implementation detail to perform some events, specifically + * - net.minecraft.world.level.block.LayeredCauldronBlock#entityInside + */ +@AllFeatures +public class StepBasedCollectorRunBeforeTest { + + @Test + public void testExecuteRunBeforeWithoutEffect() { + final StepBasedCollector stepBasedCollector = new StepBasedCollector(); + final AtomicBoolean triggered = new AtomicBoolean(false); + final Entity entity = Mockito.mock(Entity.class); + Mockito.when(entity.isAlive()).thenReturn(true); + + stepBasedCollector.runBefore(InsideBlockEffectType.EXTINGUISH, e -> triggered.set(true)); + stepBasedCollector.applyAndClear(entity); + + Assertions.assertTrue(triggered.get()); + } + +}