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

114 lines
8.6 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 7334a522956649fdf606b560d52e127c2f500b5d..394ec4f018b676a441e49d7ccbef3f8c56673603 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 9de6503f20396601a270e6eb0b66c40187fca690..f5fb81ebe2ca06cd8e4bf5b28494563f7beb4a7c 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 875a776d5aa1399808e5d5eab1c608dd35011c85..1b34a5beb7f17b25552375d3b8017e26da0239b8 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 a25c2983a7e0df3292f701fc46487e5e15ec7ac8..8185959e02a82590dcc3f5625494b6f0f38e31b1 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 - Call BlockPhysicsEvent
try {
boolean cancelled = false;
@@ -141,6 +142,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
world.lastPhysicsProblem = new BlockPos(blockPos);
}
// Paper end - Call BlockPhysicsEvent
+ } // 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;
}
}