From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 17 Apr 2023 19:47:57 -0700 Subject: [PATCH] Prevent block updates in non-loaded or non-owned chunks This is to prevent block physics from tripping thread checks by far exceeding the bounds of the current region. While this does add explicit block update suppression techniques, it's better than the server crashing. diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java index 402a90890b9754c9c1a1d209a13cda8c9498f05c..1976a443e7c59e1e18d8a411513df39c83ad1095 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -2045,7 +2045,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl public void updateNeighbourForOutputSignal(BlockPos pos, Block block) { for (Direction direction : Direction.Plane.HORIZONTAL) { BlockPos blockPos = pos.relative(direction); - if (this.hasChunkAt(blockPos)) { + if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this, blockPos, 16) && this.hasChunkAt(blockPos)) { // Folia - block updates in unloaded chunks BlockState blockState = this.getBlockState(blockPos); if (blockState.is(Blocks.COMPARATOR)) { this.neighborChanged(blockState, blockPos, block, null, false); diff --git a/net/minecraft/world/level/block/DetectorRailBlock.java b/net/minecraft/world/level/block/DetectorRailBlock.java index 73bc347616b40f55664dfcbc805dfac5d1e0452e..ec273a242c67d13906d543831e0cd5def2cae931 100644 --- a/net/minecraft/world/level/block/DetectorRailBlock.java +++ b/net/minecraft/world/level/block/DetectorRailBlock.java @@ -128,8 +128,8 @@ public class DetectorRailBlock extends BaseRailBlock { RailState railState = new RailState(level, pos, state); for (BlockPos blockPos : railState.getConnections()) { - BlockState blockState = level.getBlockState(blockPos); - level.neighborChanged(blockState, blockPos, blockState.getBlock(), null, false); + BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, blockPos, 16) ? null : level.getBlockState(blockPos); // Folia - block updates in unloaded chunks + if (blockState != null) level.neighborChanged(blockState, blockPos, blockState.getBlock(), null, false); // Folia - block updates in unloaded chunks } } diff --git a/net/minecraft/world/level/block/PoweredRailBlock.java b/net/minecraft/world/level/block/PoweredRailBlock.java index e4c4a6b4a6ea41b1fdb006cfc70dfb68dcd056c0..abc39a31b29ed4f68398851de7a1209fef895769 100644 --- a/net/minecraft/world/level/block/PoweredRailBlock.java +++ b/net/minecraft/world/level/block/PoweredRailBlock.java @@ -102,8 +102,8 @@ public class PoweredRailBlock extends BaseRailBlock { } protected boolean isSameRailWithPower(Level level, BlockPos state, boolean searchForward, int recursionCount, RailShape shape) { - BlockState blockState = level.getBlockState(state); - if (!blockState.is(this)) { + BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, state, 16) ? null : level.getBlockState(state); // Folia - block updates in unloaded chunks + if (blockState == null || !blockState.is(this)) { // Folia - block updates in unloaded chunks return false; } else { RailShape railShape = blockState.getValue(SHAPE); diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java index fde784fac9ee933d811d70701cb71684c816e966..4b37335e91a51b9a58ce0bce94b61ab5afbc6486 100644 --- a/net/minecraft/world/level/block/RedStoneWireBlock.java +++ b/net/minecraft/world/level/block/RedStoneWireBlock.java @@ -211,8 +211,9 @@ public class RedStoneWireBlock extends Block { BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); for (Direction direction : Direction.Plane.HORIZONTAL) { + BlockState currState; mutableBlockPos.setWithOffset(pos, direction); // Folia - block updates in unloaded chunks RedstoneSide redstoneSide = state.getValue(PROPERTY_BY_DIRECTION.get(direction)); - if (redstoneSide != RedstoneSide.NONE && !level.getBlockState(mutableBlockPos.setWithOffset(pos, direction)).is(this)) { + if (redstoneSide != RedstoneSide.NONE && (currState = (level instanceof net.minecraft.server.level.ServerLevel serverLevel && !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(serverLevel, pos, 16) ? null : level.getBlockStateIfLoaded(mutableBlockPos.setWithOffset(pos, direction)))) != null && !currState.is(this)) { // Folia - block updates in unloaded chunks mutableBlockPos.move(Direction.DOWN); BlockState blockState = level.getBlockState(mutableBlockPos); if (blockState.is(this)) { diff --git a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java index e7ea9df8f404a6176435204a91edeefab8070c89..285fa83ee583595274f228e5981a67f67012d410 100644 --- a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java +++ b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java @@ -122,7 +122,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater { public boolean runNext(Level level) { Direction direction = NeighborUpdater.UPDATE_ORDER[this.idx++]; BlockPos blockPos = this.sourcePos.relative(direction); - BlockState blockState = level.getBlockState(blockPos); + BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, blockPos, 16) ? null : level.getBlockState(blockPos); // Folia - block updates in unloaded chunks + if (blockState != null) { // Folia - block updates in unloaded chunks Orientation orientation = null; if (level.enabledFeatures().contains(FeatureFlags.REDSTONE_EXPERIMENTS)) { if (this.orientation == null) { @@ -135,6 +136,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater { } NeighborUpdater.executeUpdate(level, blockState, blockPos, this.sourceBlock, orientation, false, this.sourcePos); // Paper - Add source block to BlockPhysicsEvent + } // Folia - block updates in unloaded chunks if (this.idx < NeighborUpdater.UPDATE_ORDER.length && NeighborUpdater.UPDATE_ORDER[this.idx] == this.skipDirection) { this.idx++; } @@ -151,7 +153,9 @@ public class CollectingNeighborUpdater implements NeighborUpdater { implements CollectingNeighborUpdater.NeighborUpdates { @Override public boolean runNext(Level level) { + if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, this.pos, 16) && level.getChunkIfLoaded(this.pos) != null) { // Folia - block updates in unloaded chunks NeighborUpdater.executeShapeUpdate(level, this.direction, this.pos, this.neighborPos, this.neighborState, this.updateFlags, this.updateLimit); + } // Folia - block updates in unloaded chunks return false; } } @@ -159,8 +163,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater { record SimpleNeighborUpdate(BlockPos pos, Block block, @Nullable Orientation orientation) implements CollectingNeighborUpdater.NeighborUpdates { @Override public boolean runNext(Level level) { - BlockState blockState = level.getBlockState(this.pos); - NeighborUpdater.executeUpdate(level, blockState, this.pos, this.block, this.orientation, false); + BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, this.pos, 16) ? null : level.getBlockStateIfLoaded(this.pos); // Folia - block updates in unloaded chunks + if (blockState != null) NeighborUpdater.executeUpdate(level, blockState, this.pos, this.block, this.orientation, false); return false; } }