Folia/patches/server/0011-Prevent-block-updates-...

114 lines
8.5 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/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index f2597960643a37c79ad189254b7073e22d607347..833f65c7b66a9b87b34118ed12d4d701a54b8e61 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1763,7 +1763,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
Direction enumdirection = (Direction) iterator.next();
BlockPos blockposition1 = pos.relative(enumdirection);
- if (this.hasChunkAt(blockposition1)) {
+ if (io.papermc.paper.util.TickThread.isTickThreadFor((ServerLevel)this, blockposition1) && this.hasChunkAt(blockposition1)) { // Folia - block updates in unloaded chunks
BlockState iblockdata = this.getBlockState(blockposition1);
if (iblockdata.is(Blocks.COMPARATOR)) {
diff --git a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
index 034a3bc5b5e526e28088a9715a41ad8ab843860b..42877ed3c59141072a551d0f0d6db7e0eef919a0 100644
--- a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
@@ -134,9 +134,9 @@ public class DetectorRailBlock extends BaseRailBlock {
while (iterator.hasNext()) {
BlockPos blockposition1 = (BlockPos) iterator.next();
- BlockState iblockdata1 = world.getBlockState(blockposition1);
+ BlockState iblockdata1 = !io.papermc.paper.util.TickThread.isTickThreadFor((ServerLevel)world, blockposition1) ? null : world.getBlockStateIfLoaded(blockposition1); // Folia - block updates in unloaded chunks
- world.neighborChanged(iblockdata1, blockposition1, iblockdata1.getBlock(), pos, false);
+ if (iblockdata1 != null) world.neighborChanged(iblockdata1, blockposition1, iblockdata1.getBlock(), pos, false); // Folia - block updates in unloaded chunks
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
index b84c48902ef24fdae17578a304e6c93dc20c5dce..218c1954a7922c9e6bf6f34f9497f89ce1207eac 100644
--- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
@@ -104,9 +104,9 @@ public class PoweredRailBlock extends BaseRailBlock {
}
protected boolean isSameRailWithPower(Level world, BlockPos pos, boolean flag, int distance, RailShape shape) {
- BlockState iblockdata = world.getBlockState(pos);
+ BlockState iblockdata = !io.papermc.paper.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)world, pos) ? null : world.getBlockStateIfLoaded(pos); // Folia - block updates in unloaded chunks
- if (!iblockdata.is((Block) this)) {
+ if (iblockdata == null || !iblockdata.is((Block) this)) { // Folia - block updates in unloaded chunks
return false;
} else {
RailShape blockpropertytrackposition1 = (RailShape) iblockdata.getValue(PoweredRailBlock.SHAPE);
diff --git a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
index bf0e67921d96edde46a97543099f9c03634fca11..b64f0a30a0f7aee5ac9838a11756fdc5c93c36f6 100644
--- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
@@ -200,8 +200,9 @@ public class RedStoneWireBlock extends Block {
while (iterator.hasNext()) {
Direction enumdirection = (Direction) iterator.next();
RedstoneSide blockpropertyredstoneside = (RedstoneSide) state.getValue((Property) RedStoneWireBlock.PROPERTY_BY_DIRECTION.get(enumdirection));
+ BlockState currState; blockposition_mutableblockposition.setWithOffset(pos, enumdirection); // Folia - block updates in unloaded chunks
- if (blockpropertyredstoneside != RedstoneSide.NONE && !world.getBlockState(blockposition_mutableblockposition.setWithOffset(pos, enumdirection)).is((Block) this)) {
+ if (blockpropertyredstoneside != RedstoneSide.NONE && (currState = (world instanceof net.minecraft.server.level.ServerLevel serverLevel && !io.papermc.paper.util.TickThread.isTickThreadFor(serverLevel, pos) ? null : world.getBlockStateIfLoaded(blockposition_mutableblockposition))) != null && !currState.is((Block) this)) { // Folia - block updates in unloaded chunks
blockposition_mutableblockposition.move(Direction.DOWN);
BlockState iblockdata1 = world.getBlockState(blockposition_mutableblockposition);
diff --git a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
index 8a139bcfc9c3de5793b1b590be6cafaae01c86e1..a61672154c4f733cdadd9ac34ca5507355d06c68 100644
--- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
+++ b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
@@ -119,7 +119,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
@Override
public boolean runNext(Level world) {
BlockPos blockPos = this.sourcePos.relative(NeighborUpdater.UPDATE_ORDER[this.idx++]);
- BlockState blockState = world.getBlockState(blockPos);
+ BlockState blockState = !io.papermc.paper.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)world, blockPos) ? null : world.getBlockStateIfLoaded(blockPos); // Folia - block updates in unloaded chunks
+ if (blockState != null) { // Folia - block updates in unloaded chunks
// Paper start
try {
boolean cancelled = false;
@@ -141,6 +142,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
world.lastPhysicsProblem = new BlockPos(blockPos);
}
// Paper end
+ } // Folia - block updates in unloaded chunks
if (this.idx < NeighborUpdater.UPDATE_ORDER.length && NeighborUpdater.UPDATE_ORDER[this.idx] == this.skipDirection) {
++this.idx;
}
@@ -156,7 +158,9 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
static record ShapeUpdate(Direction direction, BlockState state, BlockPos pos, BlockPos neighborPos, int updateFlags, int updateLimit) implements CollectingNeighborUpdater.NeighborUpdates {
@Override
public boolean runNext(Level world) {
+ if (io.papermc.paper.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)world, this.pos) && world.getChunkIfLoaded(this.pos) != null) { // Folia - block updates in unloaded chunks
NeighborUpdater.executeShapeUpdate(world, this.direction, this.state, this.pos, this.neighborPos, this.updateFlags, this.updateLimit);
+ } // Folia - block updates in unloaded chunks
return false;
}
}
@@ -164,8 +168,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
static record SimpleNeighborUpdate(BlockPos pos, Block block, BlockPos neighborPos) implements CollectingNeighborUpdater.NeighborUpdates {
@Override
public boolean runNext(Level world) {
- BlockState blockState = world.getBlockState(this.pos);
- NeighborUpdater.executeUpdate(world, blockState, this.pos, this.block, this.neighborPos, false);
+ BlockState blockState = !io.papermc.paper.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)world, this.pos) ? null : world.getBlockStateIfLoaded(this.pos); // Folia - block updates in unloaded chunks
+ if (blockState != null) NeighborUpdater.executeUpdate(world, blockState, this.pos, this.block, this.neighborPos, false); // Folia - block updates in unloaded chunks
return false;
}
}