net/minecraft/world/level/material

This commit is contained in:
Owen1212055 2024-12-14 16:49:54 -05:00
parent 9524c006d7
commit 4707f46b25
No known key found for this signature in database
GPG key ID: 2133292072886A30
5 changed files with 174 additions and 194 deletions

View file

@ -0,0 +1,137 @@
--- a/net/minecraft/world/level/material/FlowingFluid.java
+++ b/net/minecraft/world/level/material/FlowingFluid.java
@@ -118,6 +_,15 @@
FluidState newLiquid = this.getNewLiquid(level, blockPos, blockState1);
Fluid type = newLiquid.getType();
if (fluidState1.canBeReplacedWith(level, blockPos, type, Direction.DOWN) && canHoldSpecificFluid(level, blockPos, blockState1, type)) {
+ // CraftBukkit start
+ org.bukkit.block.Block source = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
+ org.bukkit.event.block.BlockFromToEvent event = new org.bukkit.event.block.BlockFromToEvent(source, org.bukkit.block.BlockFace.DOWN);
+ level.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
this.spreadTo(level, blockPos, blockState1, Direction.DOWN, newLiquid);
if (this.sourceNeighborCount(level, pos) >= 3) {
this.spreadToSides(level, pos, fluidState, blockState);
@@ -146,7 +_,18 @@
Direction direction = entry.getKey();
FluidState fluidState1 = entry.getValue();
BlockPos blockPos = pos.relative(direction);
- this.spreadTo(level, blockPos, level.getBlockState(blockPos), direction, fluidState1);
+ final BlockState blockStateIfLoaded = level.getBlockStateIfLoaded(blockPos); // Paper - Prevent chunk loading from fluid flowing
+ if (blockStateIfLoaded == null) continue; // Paper - Prevent chunk loading from fluid flowing
+ // CraftBukkit start
+ org.bukkit.block.Block source = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
+ org.bukkit.event.block.BlockFromToEvent event = new org.bukkit.event.block.BlockFromToEvent(source, org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(direction));
+ level.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ continue;
+ }
+ // CraftBukkit end
+ this.spreadTo(level, blockPos, blockStateIfLoaded, direction, fluidState1); // Paper - Prevent chunk loading from fluid flowing
}
}
}
@@ -158,7 +_,8 @@
for (Direction direction : Direction.Plane.HORIZONTAL) {
BlockPos blockPos = mutableBlockPos.setWithOffset(pos, direction);
- BlockState blockState = level.getBlockState(blockPos);
+ BlockState blockState = level.getBlockStateIfLoaded(mutableBlockPos); // Paper - Prevent chunk loading from fluid flowing
+ if (blockState == null) continue; // Paper - Prevent chunk loading from fluid flowing
FluidState fluidState = blockState.getFluidState();
if (fluidState.getType().isSame(this) && canPassThroughWall(direction, level, pos, state, blockPos, blockState)) {
if (fluidState.isSource()) {
@@ -252,13 +_,14 @@
liquidBlockContainer.placeLiquid(level, pos, blockState, fluidState);
} else {
if (!blockState.isAir()) {
- this.beforeDestroyingBlock(level, pos, blockState);
+ this.beforeDestroyingBlock(level, pos, blockState, pos.relative(direction.getOpposite())); // Paper - Add BlockBreakBlockEvent
}
level.setBlock(pos, fluidState.createLegacyBlock(), 3);
}
}
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - Add BlockBreakBlockEvent
protected abstract void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state);
protected int getSlopeDistance(LevelReader level, BlockPos pos, int depth, Direction direction, BlockState state, FlowingFluid.SpreadContext spreadContext) {
@@ -267,7 +_,8 @@
for (Direction direction1 : Direction.Plane.HORIZONTAL) {
if (direction1 != direction) {
BlockPos blockPos = pos.relative(direction1);
- BlockState blockState = spreadContext.getBlockState(blockPos);
+ BlockState blockState = spreadContext.getBlockStateIfLoaded(blockPos); // Paper - Prevent chunk loading from fluid flowing
+ if (blockState == null) continue; // Paper - Prevent chunk loading from fluid flowing
FluidState fluidState = blockState.getFluidState();
if (this.canPassThrough(level, this.getFlowing(), pos, state, direction1, blockPos, blockState, fluidState)) {
if (spreadContext.isHole(blockPos)) {
@@ -334,7 +_,8 @@
for (Direction direction : Direction.Plane.HORIZONTAL) {
BlockPos blockPos = pos.relative(direction);
- BlockState blockState = level.getBlockState(blockPos);
+ BlockState blockState = level.getBlockStateIfLoaded(blockPos); // Paper - Prevent chunk loading from fluid flowing
+ if (blockState == null) continue; // Paper - Prevent chunk loading from fluid flowing
FluidState fluidState = blockState.getFluidState();
if (this.canMaybePassThrough(level, pos, state, direction, blockPos, blockState, fluidState)) {
FluidState newLiquid = this.getNewLiquid(level, blockPos, blockState);
@@ -405,10 +_,24 @@
if (newLiquid.isEmpty()) {
fluidState = newLiquid;
blockState = Blocks.AIR.defaultBlockState();
+ // CraftBukkit start
+ org.bukkit.event.block.FluidLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFluidLevelChangeEvent(level, pos, blockState);
+ if (event.isCancelled()) {
+ return;
+ }
+ blockState = ((org.bukkit.craftbukkit.block.data.CraftBlockData) event.getNewData()).getState();
+ // CraftBukkit end
level.setBlock(pos, blockState, 3);
} else if (!newLiquid.equals(fluidState)) {
fluidState = newLiquid;
blockState = newLiquid.createLegacyBlock();
+ // CraftBukkit start
+ org.bukkit.event.block.FluidLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFluidLevelChangeEvent(level, pos, blockState);
+ if (event.isCancelled()) {
+ return;
+ }
+ blockState = ((org.bukkit.craftbukkit.block.data.CraftBlockData) event.getNewData()).getState();
+ // CraftBukkit end
level.setBlock(pos, blockState, 3);
level.scheduleTick(pos, newLiquid.getType(), spreadDelay);
}
@@ -476,9 +_,26 @@
public BlockState getBlockState(BlockPos pos) {
return this.getBlockState(pos, this.getCacheKey(pos));
}
+ // Paper start - Prevent chunk loading from fluid flowing
+ public @javax.annotation.Nullable BlockState getBlockStateIfLoaded(BlockPos pos) {
+ return this.getBlockState(pos, this.getCacheKey(pos), false);
+ }
+ // Paper end - Prevent chunk loading from fluid flowing
private BlockState getBlockState(BlockPos pos, short cacheKey) {
- return this.stateCache.computeIfAbsent(cacheKey, s -> this.level.getBlockState(pos));
+ // Paper start - Prevent chunk loading from fluid flowing
+ return getBlockState(pos, cacheKey, true);
+ }
+ private @javax.annotation.Nullable BlockState getBlockState(BlockPos pos, short packed, boolean load) {
+ BlockState blockState = this.stateCache.get(packed);
+ if (blockState == null) {
+ blockState = load ? level.getBlockState(pos) : level.getBlockStateIfLoaded(pos);
+ if (blockState != null) {
+ this.stateCache.put(packed, blockState);
+ }
+ }
+ return blockState;
+ // Paper end - Prevent chunk loading from fluid flowing
}
public boolean isHole(BlockPos pos) {

View file

@ -1,18 +1,18 @@
--- a/net/minecraft/world/level/material/FluidState.java
+++ b/net/minecraft/world/level/material/FluidState.java
@@ -26,9 +26,11 @@
@@ -26,9 +_,11 @@
public static final Codec<FluidState> CODEC = codec(BuiltInRegistries.FLUID.byNameCodec(), Fluid::defaultFluidState).stable();
public static final int AMOUNT_MAX = 9;
public static final int AMOUNT_FULL = 8;
+ protected final boolean isEmpty; // Paper - Perf: moved from isEmpty()
public FluidState(Fluid fluid, Reference2ObjectArrayMap<Property<?>, Comparable<?>> propertyMap, MapCodec<FluidState> codec) {
super(fluid, propertyMap, codec);
+ this.isEmpty = fluid.isEmpty(); // Paper - Perf: moved from isEmpty()
public FluidState(Fluid owner, Reference2ObjectArrayMap<Property<?>, Comparable<?>> values, MapCodec<FluidState> propertiesCodec) {
super(owner, values, propertiesCodec);
+ this.isEmpty = owner.isEmpty(); // Paper - Perf: moved from isEmpty()
}
public Fluid getType() {
@@ -44,7 +46,7 @@
@@ -44,7 +_,7 @@
}
public boolean isEmpty() {
@ -20,4 +20,4 @@
+ return this.isEmpty; // Paper - Perf: moved into constructor
}
public float getHeight(BlockGetter world, BlockPos pos) {
public float getHeight(BlockGetter level, BlockPos pos) {

View file

@ -1,48 +1,48 @@
--- a/net/minecraft/world/level/material/LavaFluid.java
+++ b/net/minecraft/world/level/material/LavaFluid.java
@@ -85,6 +85,13 @@
if (iblockdata.isAir()) {
if (this.hasFlammableNeighbours(world, blockposition1)) {
@@ -88,6 +_,13 @@
BlockState blockState = level.getBlockState(blockPos);
if (blockState.isAir()) {
if (this.hasFlammableNeighbours(level, blockPos)) {
+ // CraftBukkit start - Prevent lava putting something on fire
+ if (world.getBlockState(blockposition1).getBlock() != Blocks.FIRE) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition1, pos).isCancelled()) {
+ if (level.getBlockState(blockPos).getBlock() != Blocks.FIRE) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, blockPos, pos).isCancelled()) {
+ continue;
+ }
+ }
+ // CraftBukkit end
world.setBlockAndUpdate(blockposition1, BaseFireBlock.getState(world, blockposition1));
level.setBlockAndUpdate(blockPos, BaseFireBlock.getState(level, blockPos));
return;
}
@@ -101,6 +108,14 @@
@@ -103,6 +_,14 @@
}
if (world.isEmptyBlock(blockposition2.above()) && this.isFlammable(world, blockposition2)) {
if (level.isEmptyBlock(blockPos1.above()) && this.isFlammable(level, blockPos1)) {
+ // CraftBukkit start - Prevent lava putting something on fire
+ BlockPos up = blockposition2.above();
+ if (world.getBlockState(up).getBlock() != Blocks.FIRE) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, up, pos).isCancelled()) {
+ BlockPos up = blockPos1.above();
+ if (level.getBlockState(up).getBlock() != Blocks.FIRE) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, up, pos).isCancelled()) {
+ continue;
+ }
+ }
+ // CraftBukkit end
world.setBlockAndUpdate(blockposition2.above(), BaseFireBlock.getState(world, blockposition2));
level.setBlockAndUpdate(blockPos1.above(), BaseFireBlock.getState(level, blockPos1));
}
}
@@ -196,7 +211,11 @@
if (this.is(FluidTags.LAVA) && fluid1.is(FluidTags.WATER)) {
if (state.getBlock() instanceof LiquidBlock) {
- world.setBlock(pos, Blocks.STONE.defaultBlockState(), 3);
@@ -195,7 +_,11 @@
FluidState fluidState1 = level.getFluidState(pos);
if (this.is(FluidTags.LAVA) && fluidState1.is(FluidTags.WATER)) {
if (blockState.getBlock() instanceof LiquidBlock) {
- level.setBlock(pos, Blocks.STONE.defaultBlockState(), 3);
+ // CraftBukkit start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world.getMinecraftWorld(), pos, Blocks.STONE.defaultBlockState(), 3)) {
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level.getMinecraftWorld(), pos, Blocks.STONE.defaultBlockState(), 3)) {
+ return;
+ }
+ // CraftBukkit end
}
this.fizz(world, pos);
@@ -214,7 +233,7 @@
this.fizz(level, pos);
@@ -213,7 +_,7 @@
@Override
protected float getExplosionResistance() {

View file

@ -1,21 +1,21 @@
--- a/net/minecraft/world/level/material/WaterFluid.java
+++ b/net/minecraft/world/level/material/WaterFluid.java
@@ -81,7 +81,14 @@
return world.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION);
@@ -74,7 +_,13 @@
protected boolean canConvertToSource(ServerLevel level) {
return level.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION);
}
-
+ // Paper start - Add BlockBreakBlockEvent
@Override
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) {
+ @Override
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) {
+ BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
+ Block.dropResources(state, world, pos, tileentity, source);
+ }
+ // Paper end - Add BlockBreakBlockEvent
+ @Override
protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state) {
BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
Block.dropResources(state, world, pos, blockEntity);
@@ -119,7 +126,7 @@
@Override
protected void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state) {
BlockEntity blockEntity = state.hasBlockEntity() ? level.getBlockEntity(pos) : null;
@@ -113,7 +_,7 @@
@Override
protected float getExplosionResistance() {

View file

@ -1,157 +0,0 @@
--- a/net/minecraft/world/level/material/FlowingFluid.java
+++ b/net/minecraft/world/level/material/FlowingFluid.java
@@ -31,6 +31,14 @@
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
+// CraftBukkit start
+import org.bukkit.block.BlockFace;
+import org.bukkit.craftbukkit.block.CraftBlock;
+import org.bukkit.craftbukkit.block.data.CraftBlockData;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.block.BlockFromToEvent;
+import org.bukkit.event.block.FluidLevelChangeEvent;
+// CraftBukkit end
public abstract class FlowingFluid extends Fluid {
@@ -135,6 +143,15 @@
Fluid fluidtype = fluid2.getType();
if (fluid1.canBeReplacedWith(world, blockposition1, fluidtype, Direction.DOWN) && FlowingFluid.canHoldSpecificFluid(world, blockposition1, iblockdata1, fluidtype)) {
+ // CraftBukkit start
+ org.bukkit.block.Block source = CraftBlock.at(world, fluidPos);
+ BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN);
+ world.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
this.spreadTo(world, blockposition1, iblockdata1, Direction.DOWN, fluid2);
if (this.sourceNeighborCount(world, fluidPos) >= 3) {
this.spreadToSides(world, fluidPos, fluidState, blockState);
@@ -167,8 +184,19 @@
Direction enumdirection = (Direction) entry.getKey();
FluidState fluid1 = (FluidState) entry.getValue();
BlockPos blockposition1 = pos.relative(enumdirection);
+ final BlockState blockStateIfLoaded = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing
+ if (blockStateIfLoaded == null) continue; // Paper - Prevent chunk loading from fluid flowing
- this.spreadTo(world, blockposition1, world.getBlockState(blockposition1), enumdirection, fluid1);
+ // CraftBukkit start
+ org.bukkit.block.Block source = CraftBlock.at(world, pos);
+ BlockFromToEvent event = new BlockFromToEvent(source, org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(enumdirection));
+ world.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ continue;
+ }
+ // CraftBukkit end
+ this.spreadTo(world, blockposition1, blockStateIfLoaded, enumdirection, fluid1); // Paper - Prevent chunk loading from fluid flowing
}
}
@@ -183,7 +211,8 @@
while (iterator.hasNext()) {
Direction enumdirection = (Direction) iterator.next();
BlockPos.MutableBlockPos blockposition_mutableblockposition1 = blockposition_mutableblockposition.setWithOffset(pos, enumdirection);
- BlockState iblockdata1 = world.getBlockState(blockposition_mutableblockposition1);
+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition_mutableblockposition1); // Paper - Prevent chunk loading from fluid flowing
+ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing
FluidState fluid = iblockdata1.getFluidState();
if (fluid.getType().isSame(this) && FlowingFluid.canPassThroughWall(enumdirection, world, pos, state, blockposition_mutableblockposition1, iblockdata1)) {
@@ -287,7 +316,7 @@
ifluidcontainer.placeLiquid(world, pos, state, fluidState);
} else {
if (!state.isAir()) {
- this.beforeDestroyingBlock(world, pos, state);
+ this.beforeDestroyingBlock(world, pos, state, pos.relative(direction.getOpposite())); // Paper - Add BlockBreakBlockEvent
}
world.setBlock(pos, fluidState.createLegacyBlock(), 3);
@@ -295,6 +324,7 @@
}
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - Add BlockBreakBlockEvent
protected abstract void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state);
protected int getSlopeDistance(LevelReader world, BlockPos pos, int i, Direction direction, BlockState state, FlowingFluid.SpreadContext spreadCache) {
@@ -306,7 +336,8 @@
if (enumdirection1 != direction) {
BlockPos blockposition1 = pos.relative(enumdirection1);
- BlockState iblockdata1 = spreadCache.getBlockState(blockposition1);
+ BlockState iblockdata1 = spreadCache.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing
+ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing
FluidState fluid = iblockdata1.getFluidState();
if (this.canPassThrough(world, this.getFlowing(), pos, state, enumdirection1, blockposition1, iblockdata1, fluid)) {
@@ -372,7 +403,8 @@
while (iterator.hasNext()) {
Direction enumdirection = (Direction) iterator.next();
BlockPos blockposition1 = pos.relative(enumdirection);
- BlockState iblockdata1 = world.getBlockState(blockposition1);
+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing
+ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing
FluidState fluid = iblockdata1.getFluidState();
if (this.canMaybePassThrough(world, pos, state, enumdirection, blockposition1, iblockdata1, fluid)) {
@@ -444,10 +476,24 @@
if (fluid1.isEmpty()) {
fluidState = fluid1;
blockState = Blocks.AIR.defaultBlockState();
+ // CraftBukkit start
+ FluidLevelChangeEvent event = CraftEventFactory.callFluidLevelChangeEvent(world, pos, blockState);
+ if (event.isCancelled()) {
+ return;
+ }
+ blockState = ((CraftBlockData) event.getNewData()).getState();
+ // CraftBukkit end
world.setBlock(pos, blockState, 3);
} else if (!fluid1.equals(fluidState)) {
fluidState = fluid1;
blockState = fluid1.createLegacyBlock();
+ // CraftBukkit start
+ FluidLevelChangeEvent event = CraftEventFactory.callFluidLevelChangeEvent(world, pos, blockState);
+ if (event.isCancelled()) {
+ return;
+ }
+ blockState = ((CraftBlockData) event.getNewData()).getState();
+ // CraftBukkit end
world.setBlock(pos, blockState, 3);
world.scheduleTick(pos, fluid1.getType(), i);
}
@@ -524,12 +570,27 @@
public BlockState getBlockState(BlockPos pos) {
return this.getBlockState(pos, this.getCacheKey(pos));
}
+ // Paper start - Prevent chunk loading from fluid flowing
+ public @javax.annotation.Nullable BlockState getBlockStateIfLoaded(BlockPos pos) {
+ return this.getBlockState(pos, this.getCacheKey(pos), false);
+ }
+ // Paper end - Prevent chunk loading from fluid flowing
private BlockState getBlockState(BlockPos pos, short packed) {
- return (BlockState) this.stateCache.computeIfAbsent(packed, (short1) -> {
- return this.level.getBlockState(pos);
- });
+ // Paper start - Prevent chunk loading from fluid flowing
+ return getBlockState(pos, packed, true);
}
+ private @javax.annotation.Nullable BlockState getBlockState(BlockPos pos, short packed, boolean load) {
+ BlockState blockState = this.stateCache.get(packed);
+ if (blockState == null) {
+ blockState = load ? level.getBlockState(pos) : level.getBlockStateIfLoaded(pos);
+ if (blockState != null) {
+ this.stateCache.put(packed, blockState);
+ }
+ }
+ return blockState;
+ // Paper end - Prevent chunk loading from fluid flowing
+ }
public boolean isHole(BlockPos pos) {
return this.holeCache.computeIfAbsent(this.getCacheKey(pos), (short0) -> {