Luminol-Core/folia-server/minecraft-patches/features/0004-Prevent-block-updates-in-non-loaded-or-non-owned-chu.patch
2026-06-30 18:32:29 +08:00

112 lines
8.2 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
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<Entity>, 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;
}
}