forked from mirror/Folia
fd838ffbee
Fix two regionizer issues: In ThreadedRegionizer#addChunk, fix the incorrect handling of merging two regions where one of the regions had pending merges. If the first region had pending merges, and the second was marked as "ready" then the merge would cause a "ready" region to have pending merges. The fix is to simply downgrade the "ready" region to "transient," as was previously done if the merge was delayed in the case where the first region was "ticking." Additionally, prevent the creation of empty regions by checking if any new sections were created. This would happen when a section existed, but had no marked chunks in it AND all of the sections neighbours existed. In these cases, no region needs to be created as no sections were created.
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 c28e974ea43e69e1e7d608785299d74317c83920..8cf4428d8140fd03f0ad8fa1d148a04d8caefda8 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -1343,7 +1343,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 05dfb1790a292f9f85b641377c2ca3675726c127..971fcb61915f8b5f3fc4cbe3f3e4c8d639abdee6 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
|
|
@@ -127,9 +127,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 7fddb6fa8fd30ef88346a59f7867aae792f13772..b963f364b4763091c3b5d0f938eaa6798ffa4553 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
|
|
@@ -97,9 +97,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 858f81db707a73edeec2bb4ee62e69ad2f64200c..7b479d0c093732a5a8899b8f3d49a77139ef8826 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
|
|
@@ -193,8 +193,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 d50c7dd008af14fce9073666e0fd1b609f89559c..5ddd8108e077bc7c1a9524854ac591c6ab99c174 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;
|
|
}
|
|
}
|