forked from mirror/Folia
6928284a56
The region shift is configurable under `grid-exponent`, which allows setting the region shift to any value in [0, 31]. Note that values above 6 affect the lock shift, as the lock shift currently is computed as max(ticket shift = 6, region shift). The shift is left configurable for now as the lower default shift of 2 may have negative performance impacts. The default region shift has been adjusted to 2 from 4, and the empty chunk buffer has been reduced to 8 from 16. These changes reduce, but do not eliminate, player spread requirements. The previous block range was around ~1500 blocks at VD = 10, but is now closer to ~900 blocks at VD = 10. This roughly reduces the area that each player uses in the regioniser by 2.5x.
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 48480686e8f1a554818e58890f9a8f3f4afd0a43..b924986c4e3b9e20a4100481c5d6534b040950af 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -1758,7 +1758,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;
|
|
}
|
|
}
|