forked from mirror/Folia
de6a87e338
- Compile needs to be checked. - Behaviors around the new tick manager need to be designed and implemented. Chk update.txt for anything specific.
114 lines
8.5 KiB
Diff
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 91f17ee2b6c9e1413b5bef62adcfe2a0d9537fef..474757fe16986d84f84302a22441c332d622d038 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -1764,7 +1764,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;
|
|
}
|
|
}
|