9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-19 14:59:25 +00:00

[ci-skip] reformat patches

This commit is contained in:
NONPLAYT
2025-10-31 19:49:24 +03:00
parent 75d44c6035
commit 14c80ea6eb
28 changed files with 708 additions and 686 deletions

View File

@@ -4,19 +4,6 @@ Date: Sun, 23 Feb 2025 01:14:54 +0300
Subject: [PATCH] Catch update suppressors
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
index 35b6f8365f4568da7bc0f4e47c39cb3690292aaf..e28d859b457ca0e24bc6dc9d6cd4a97f12ae0671 100644
--- a/net/minecraft/network/Connection.java
+++ b/net/minecraft/network/Connection.java
@@ -327,7 +327,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
private static void syncAfterConfigurationChange(ChannelFuture future) {
try {
- future.syncUninterruptibly();
+ future.awaitUninterruptibly(5000L); // DivineMC - In rare cases this can get stuck, so we time out instead in worst case 5s of lag
} catch (Exception var2) {
if (var2 instanceof ClosedChannelException) {
LOGGER.info("Connection closed during protocol change");
diff --git a/net/minecraft/network/PacketProcessor.java b/net/minecraft/network/PacketProcessor.java
index 3e4241976fdfe65bc0aae90a9097770745c0ddf1..98b101fde04fbf5507f021bb8d8e6bed334de5b6 100644
--- a/net/minecraft/network/PacketProcessor.java
@@ -47,350 +34,6 @@ index e3c7065cd4832e0c533f70d444c0a7beff53e423..d73546a9f086f67bafb3ce3a2a8ed5c2
} catch (Throwable levelTickingException) {
CrashReport crashReport = CrashReport.forThrowable(levelTickingException, "Exception ticking world");
serverLevel.fillReportDetails(crashReport);
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 04dd1bec1aff470e67a21fb0b25932685992ec82..72a0a80f1fffa43e143c80c689db5302f462114e 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -737,7 +737,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start - optimise chunk tick iteration
final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.world.level.chunk.LevelChunk> tickingChunks = ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel)this.level).moonrise$getPlayerTickingChunks();
- final LevelChunk[] raw = tickingChunks.getRawDataUnchecked();
+ final LevelChunk[] raw = tickingChunks.toArray(new LevelChunk[0]); // DivineMC - Regionized Chunk Ticking - sync fix
final int size = tickingChunks.size();
Objects.checkFromToIndex(0, size, raw.length);
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 6ea62fbffda38e477ef8e119608fc93793db95c3..74f63e549f8cadc80de26fcad11923151e0c40eb 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -57,7 +57,7 @@ import org.slf4j.Logger;
public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache { // Paper - rewrite chunk system
private static final Logger LOGGER = LogUtils.getLogger();
private final DistanceManager distanceManager;
- private final ServerLevel level;
+ protected final ServerLevel level; // DivineMC - Regionized Chunk Ticking - private -> protected
public final Thread mainThread;
final ThreadedLevelLightEngine lightEngine;
public final ServerChunkCache.MainThreadExecutor mainThreadProcessor;
@@ -71,8 +71,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
private final long[] lastChunkPos = new long[4];
private final ChunkStatus[] lastChunkStatus = new ChunkStatus[4];
private final ChunkAccess[] lastChunk = new ChunkAccess[4];
- private final List<LevelChunk> spawningChunks = new ObjectArrayList<>();
- private final Set<ChunkHolder> chunkHoldersToBroadcast = new ReferenceOpenHashSet<>();
+ // DivineMC start - Regionized Chunk Ticking
+ private final ObjectArrayList<LevelChunk> spawningChunks = new ObjectArrayList<>();
+ private final Set<ChunkHolder> chunkHoldersToBroadcast = java.util.Collections.synchronizedSet(new ReferenceOpenHashSet<>());
+ // DivineMC end - Regionized Chunk Ticking
@Nullable
@VisibleForDebug
private NaturalSpawner.SpawnState lastSpawnState;
@@ -156,34 +158,47 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
// Paper end - rewrite chunk system
// Paper start - chunk tick iteration optimisations
private final ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom shuffleRandom = new ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom(0L);
- private void iterateTickingChunksFaster() {
+ private void iterateTickingChunksFaster(final CompletableFuture<Void> spawns) { // DivineMC - Regionized Chunk Ticking
final ServerLevel world = this.level;
final int randomTickSpeed = world.getGameRules().getInt(GameRules.RULE_RANDOMTICKING);
// TODO check on update: impl of forEachBlockTickingChunk will only iterate ENTITY ticking chunks!
// TODO check on update: consumer just runs tickChunk
- final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.world.level.chunk.LevelChunk> entityTickingChunks = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$getEntityTickingChunks();
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<LevelChunk> entityTickingChunks = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$getEntityTickingChunks(); // DivineMC - Regionized Chunk Ticking
// note: we can use the backing array here because:
// 1. we do not care about new additions
// 2. _removes_ are impossible at this stage in the tick
- final LevelChunk[] raw = entityTickingChunks.getRawDataUnchecked();
+ final LevelChunk[] raw = entityTickingChunks.toArray(new LevelChunk[0]); // DivineMC - use toArray instead of getRawDataUnchecked this way is safe and doesn't have performance impact
final int size = entityTickingChunks.size();
- java.util.Objects.checkFromToIndex(0, size, raw.length);
- for (int i = 0; i < size; ++i) {
- world.tickChunk(raw[i], randomTickSpeed);
-
- // call mid-tick tasks for chunk system
- if ((i & 7) == 0) {
- // DivineMC start - Parallel world ticking
- if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) {
- ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer) this.level.getServer()).moonrise$executeMidTickTasks();
- continue;
- }
+ // DivineMC start - Regionized Chunk Ticking
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableRegionizedChunkTicking) {
+ if (this instanceof org.bxteam.divinemc.async.rct.RegionizedChunkTicking rct) {
+ rct.execute(spawns, raw);
+ }
+ } else {
+ java.util.Objects.checkFromToIndex(0, size, raw.length);
+ for (int i = 0; i < size; ++i) {
+ world.tickChunk(raw[i], randomTickSpeed);
+
+ // call mid-tick tasks for chunk system
+ if ((i & 7) == 0) {
+ // DivineMC start - Parallel world ticking
+ if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) {
+ ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer) this.level.getServer()).moonrise$executeMidTickTasks();
+ continue;
+ }
+ // DivineMC end - Parallel world ticking
+ }
// DivineMC end - Parallel world ticking
}
- }
+
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncNaturalSpawn) {
+ spawns.join();
+ }
+ }
+ // DivineMC end - Regionized Chunk Ticking
}
// Paper end - chunk tick iteration optimisations
@@ -502,14 +517,21 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
long gameTime = this.level.getGameTime();
long l = gameTime - this.lastInhabitedUpdate;
this.lastInhabitedUpdate = gameTime;
- if (!this.level.isDebug()) {
- if (this.level.tickRateManager().runsNormally()) {
- this.tickChunks(l);
- }
+ // DivineMC start - Regionized Chunk Ticking
+ if (this.level.isDebug()) {
+ return;
+ }
+
+ if (!this.level.tickRateManager().runsNormally()) { // DivineMC - when frozen only broadcast changed chunks and don't run async mob spawning
this.broadcastChangedChunks();
+ return;
}
+ this.tickChunks(l);
+ this.broadcastChangedChunks();
+ // DivineMC end - Regionized Chunk Ticking
+
// DivineMC start - Pufferfish: Optimize mob spawning
if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableAsyncSpawning) {
for (ServerPlayer player : this.level.players) {
@@ -553,14 +575,18 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
}
private void broadcastChangedChunks() {
- for (ChunkHolder chunkHolder : this.chunkHoldersToBroadcast) {
- LevelChunk tickingChunk = chunkHolder.getChunkToSend(); // Paper - rewrite chunk system
- if (tickingChunk != null) {
- chunkHolder.broadcastChanges(tickingChunk);
+ // DivineMC start - Regionized Chunk Ticking
+ synchronized (chunkHoldersToBroadcast) {
+ for (ChunkHolder chunkHolder : this.chunkHoldersToBroadcast) {
+ LevelChunk tickingChunk = chunkHolder.getChunkToSend(); // Paper - rewrite chunk system
+ if (tickingChunk != null) {
+ chunkHolder.broadcastChanges(tickingChunk);
+ }
}
- }
- this.chunkHoldersToBroadcast.clear();
+ this.chunkHoldersToBroadcast.clear();
+ }
+ // DivineMC end - Regionized Chunk Ticking
}
private void tickChunks(long timeInhabited) {
@@ -610,6 +636,24 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
filteredSpawningCategories = List.of();
}
+ // DivineMC start - Regionized Chunk Ticking
+ final CompletableFuture<Void> spawns;
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncNaturalSpawn) {
+ spawns = CompletableFuture.runAsync(() -> naturalSpawn(filteredSpawningCategories, timeInhabited), org.bxteam.divinemc.async.rct.RegionizedChunkTicking.REGION_EXECUTOR);
+ } else {
+ naturalSpawn(filteredSpawningCategories, timeInhabited);
+ spawns = new CompletableFuture<>();
+ }
+ // DivineMC end - Regionized Chunk Ticking
+
+ this.iterateTickingChunksFaster(spawns); // Paper - chunk tick iteration optimisations // DivineMC - Regionized Chunk Ticking
+ if (_boolean) {
+ this.level.tickCustomSpawners(this.spawnEnemies);
+ }
+ }
+
+ // DivineMC start - Regionized Chunk Ticking
+ private void naturalSpawn(List<MobCategory> filteredSpawningCategories, long timeInhabited) {
List<LevelChunk> list = this.spawningChunks;
try {
@@ -627,12 +671,12 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
} finally {
list.clear();
}
+ }
- this.iterateTickingChunksFaster(); // Paper - chunk tick iteration optimisations
- if (_boolean) {
- this.level.tickCustomSpawners(this.spawnEnemies);
- }
+ protected net.minecraft.world.level.entity.EntityTickList getEntityTickList() {
+ return level.entityTickList;
}
+ // DivineMC end - Regionized Chunk Ticking
private void tickSpawningChunk(LevelChunk chunk, long timeInhabited, List<MobCategory> spawnCategories, NaturalSpawner.SpawnState spawnState) {
ChunkPos pos = chunk.getPos();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index ca9883277c0f036c94e861f7917ca42facd3c47b..8c98c2593eec14a8a378041e94cf52b8fbfedc30 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -197,7 +197,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
private final LevelTicks<Block> blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded);
private final LevelTicks<Fluid> fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded);
private final PathTypeCache pathTypesByPosCache = new PathTypeCache();
- final Set<Mob> navigatingMobs = new ObjectOpenHashSet<>();
+ final Set<Mob> navigatingMobs = java.util.Collections.synchronizedSet(new ObjectOpenHashSet<>()); // DivineMC - Regionized Chunk Ticking
volatile boolean isUpdatingNavigations;
protected final Raids raids;
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>();
@@ -666,19 +666,37 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
boolean flag = server.forceSynchronousWrites();
DataFixer fixerUpper = server.getFixerUpper();
// Paper - rewrite chunk system
- this.chunkSource = new ServerChunkCache(
- this,
- levelStorageAccess,
- fixerUpper,
- server.getStructureManager(),
- dispatcher,
- chunkGenerator,
- this.spigotConfig.viewDistance, // Spigot
- this.spigotConfig.simulationDistance, // Spigot
- flag,
- null, // Paper - rewrite chunk system
- () -> server.overworld().getDataStorage()
- );
+ // DivineMC start - Regionized Chunk Ticking
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableRegionizedChunkTicking) {
+ this.chunkSource = new org.bxteam.divinemc.async.rct.RegionizedChunkTicking(
+ this,
+ levelStorageAccess,
+ fixerUpper,
+ server.getStructureManager(),
+ dispatcher,
+ chunkGenerator,
+ this.spigotConfig.viewDistance, // Spigot
+ this.spigotConfig.simulationDistance, // Spigot
+ flag,
+ null, // Paper - rewrite chunk system
+ () -> server.overworld().getDataStorage()
+ );
+ } else {
+ this.chunkSource = new ServerChunkCache(
+ this,
+ levelStorageAccess,
+ fixerUpper,
+ server.getStructureManager(),
+ dispatcher,
+ chunkGenerator,
+ this.spigotConfig.viewDistance, // Spigot
+ this.spigotConfig.simulationDistance, // Spigot
+ flag,
+ null, // Paper - rewrite chunk system
+ () -> server.overworld().getDataStorage()
+ );
+ }
+ // DivineMC end - Regionized Chunk Ticking
this.chunkSource.getGeneratorState().ensureStructuresGenerated();
this.portalForcer = new PortalForcer(this);
this.updateSkyBrightness();
@@ -846,6 +864,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.dragonFight.tick();
}
+ // DivineMC start - Regionized Chunk Ticking
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableRegionizedChunkTicking) {
+ this.tickBlockEntities();
+ return;
+ }
+ // DivineMC end - Regionized Chunk Ticking
+
io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR
this.entityTickList
.forEach(
@@ -1874,22 +1899,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
if (Shapes.joinIsNotEmpty(collisionShape, collisionShape1, BooleanOp.NOT_SAME)) {
List<PathNavigation> list = new ObjectArrayList<>();
- try { // Paper - catch CME see below why
- for (Mob mob : this.navigatingMobs) {
- PathNavigation navigation = mob.getNavigation();
- if (navigation.shouldRecomputePath(pos)) {
- list.add(navigation);
+ // DivineMC start - Regionized Chunk Ticking
+ synchronized (this.navigatingMobs) {
+ for (Mob mob : this.navigatingMobs) {
+ PathNavigation navigation = mob.getNavigation();
+ if (navigation.shouldRecomputePath(pos)) {
+ list.add(navigation);
+ }
}
}
- // Paper start - catch CME see below why
- } catch (final java.util.ConcurrentModificationException concurrentModificationException) {
- // This can happen because the pathfinder update below may trigger a chunk load, which in turn may cause more navigators to register
- // In this case we just run the update again across all the iterators as the chunk will then be loaded
- // As this is a relative edge case it is much faster than copying navigators (on either read or write)
- this.sendBlockUpdated(pos, oldState, newState, flags);
- return;
- }
- // Paper end - catch CME see below why
+ // DivineMC end - Regionized Chunk Ticking
try {
this.isUpdatingNavigations = true;
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 7fe5cb2ea1c81b12baf302999a2794f20018707c..738cbde3595165e0f05c0a6fde21499e98dc850b 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -113,7 +113,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
.build();
public final org.bxteam.divinemc.util.BlockEntityTickersList blockEntityTickers = new org.bxteam.divinemc.util.BlockEntityTickersList(); // DivineMC - optimize block entity removals - Fix MC-117075
protected final CollectingNeighborUpdater neighborUpdater;
- private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
+ private final List<TickingBlockEntity> pendingBlockEntityTickers = java.util.Collections.synchronizedList(Lists.newArrayList()); // DivineMC - Regionized Chunk Ticking
private boolean tickingBlockEntities;
public final Thread thread;
private final boolean isDebug;
@@ -145,7 +145,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public boolean captureBlockStates = false;
public boolean captureTreeGeneration = false;
- public Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
+ public Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlockStates = java.util.Collections.synchronizedMap(new java.util.LinkedHashMap<>()); // Paper // DivineMC - Regionized Chunk Ticking
public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
@Nullable
public List<net.minecraft.world.entity.item.ItemEntity> captureDrops;
@@ -1459,10 +1459,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public void tickBlockEntities() {
this.tickingBlockEntities = true;
- if (!this.pendingBlockEntityTickers.isEmpty()) {
- this.blockEntityTickers.addAll(this.pendingBlockEntityTickers);
- this.pendingBlockEntityTickers.clear();
+ // DivineMC start - Regionized Chunk Ticking - synchronization fix
+ synchronized (pendingBlockEntityTickers) {
+ if (!this.pendingBlockEntityTickers.isEmpty()) {
+ this.blockEntityTickers.addAll(this.pendingBlockEntityTickers);
+ this.pendingBlockEntityTickers.clear();
+ }
}
+ // DivineMC end - Regionized Chunk Ticking - synchronization fix
// Spigot start
boolean runsNormally = this.tickRateManager().runsNormally();
diff --git a/net/minecraft/world/level/block/ShulkerBoxBlock.java b/net/minecraft/world/level/block/ShulkerBoxBlock.java
index e08083fbb6c3090c9a6f78dbbe487cbd4fec485a..d5d77110e7799223a66c2d6e47a1d9b4653f3ec4 100644
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
@@ -414,28 +57,6 @@ index e08083fbb6c3090c9a6f78dbbe487cbd4fec485a..d5d77110e7799223a66c2d6e47a1d9b4
}
public static Block getBlockByColor(@Nullable DyeColor color) {
diff --git a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
index 5d17213a692016d2f005c7820bf2cf1f42ce411f..ccb2e0c28aeaebbeef15fbb650fa3c2e5c241ceb 100644
--- a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
+++ b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
@@ -53,7 +53,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
this.addAndRun(pos, new CollectingNeighborUpdater.MultiNeighborUpdate(pos.immutable(), block, orientation, facing));
}
- private void addAndRun(BlockPos pos, CollectingNeighborUpdater.NeighborUpdates updates) {
+ private synchronized void addAndRun(BlockPos pos, CollectingNeighborUpdater.NeighborUpdates updates) { // DivineMC - Regionized Chunk Ticking - synchronized
boolean flag = this.count > 0;
boolean flag1 = this.maxChainedNeighborUpdates >= 0 && this.count >= this.maxChainedNeighborUpdates;
this.count++;
@@ -72,7 +72,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
}
}
- private void runUpdates() {
+ private synchronized void runUpdates() { // DivineMC - Regionized Chunk Ticking - synchronized
try {
while (!this.stack.isEmpty() || !this.addedThisLayer.isEmpty()) {
for (int i = this.addedThisLayer.size() - 1; i >= 0; i--) {
diff --git a/net/minecraft/world/level/redstone/NeighborUpdater.java b/net/minecraft/world/level/redstone/NeighborUpdater.java
index f45cf0136e77ed5a903d033a7b0611e5edc23db9..e5b0cc92a2f9cdb89cd2436f6591531f8ae91d28 100644
--- a/net/minecraft/world/level/redstone/NeighborUpdater.java

View File

@@ -0,0 +1,386 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Mon, 9 Jun 2025 13:51:43 +0300
Subject: [PATCH] Regionized Chunk Ticking
This patch adds regionized chunk ticking feature, by grouping adjacent chunks into regions and processing each region on its own thread.
Original idea by Dueris, modified by NONPLAYT and heavily optimized by dan28000
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
index 35b6f8365f4568da7bc0f4e47c39cb3690292aaf..e28d859b457ca0e24bc6dc9d6cd4a97f12ae0671 100644
--- a/net/minecraft/network/Connection.java
+++ b/net/minecraft/network/Connection.java
@@ -327,7 +327,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
private static void syncAfterConfigurationChange(ChannelFuture future) {
try {
- future.syncUninterruptibly();
+ future.awaitUninterruptibly(5000L); // DivineMC - In rare cases this can get stuck, so we time out instead in worst case 5s of lag
} catch (Exception var2) {
if (var2 instanceof ClosedChannelException) {
LOGGER.info("Connection closed during protocol change");
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 04dd1bec1aff470e67a21fb0b25932685992ec82..72a0a80f1fffa43e143c80c689db5302f462114e 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -737,7 +737,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start - optimise chunk tick iteration
final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.world.level.chunk.LevelChunk> tickingChunks = ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel)this.level).moonrise$getPlayerTickingChunks();
- final LevelChunk[] raw = tickingChunks.getRawDataUnchecked();
+ final LevelChunk[] raw = tickingChunks.toArray(new LevelChunk[0]); // DivineMC - Regionized Chunk Ticking - sync fix
final int size = tickingChunks.size();
Objects.checkFromToIndex(0, size, raw.length);
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 6ea62fbffda38e477ef8e119608fc93793db95c3..dda53860397ee52f64209a8d08a7707cfa2f7592 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -57,7 +57,7 @@ import org.slf4j.Logger;
public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache { // Paper - rewrite chunk system
private static final Logger LOGGER = LogUtils.getLogger();
private final DistanceManager distanceManager;
- private final ServerLevel level;
+ protected final ServerLevel level; // DivineMC - Regionized Chunk Ticking - private -> protected
public final Thread mainThread;
final ThreadedLevelLightEngine lightEngine;
public final ServerChunkCache.MainThreadExecutor mainThreadProcessor;
@@ -71,8 +71,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
private final long[] lastChunkPos = new long[4];
private final ChunkStatus[] lastChunkStatus = new ChunkStatus[4];
private final ChunkAccess[] lastChunk = new ChunkAccess[4];
- private final List<LevelChunk> spawningChunks = new ObjectArrayList<>();
- private final Set<ChunkHolder> chunkHoldersToBroadcast = new ReferenceOpenHashSet<>();
+ // DivineMC start - Regionized Chunk Ticking
+ private final ObjectArrayList<LevelChunk> spawningChunks = new ObjectArrayList<>();
+ private final Set<ChunkHolder> chunkHoldersToBroadcast = java.util.Collections.synchronizedSet(new ReferenceOpenHashSet<>());
+ // DivineMC end - Regionized Chunk Ticking
@Nullable
@VisibleForDebug
private NaturalSpawner.SpawnState lastSpawnState;
@@ -156,34 +158,46 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
// Paper end - rewrite chunk system
// Paper start - chunk tick iteration optimisations
private final ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom shuffleRandom = new ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom(0L);
- private void iterateTickingChunksFaster() {
+ private void iterateTickingChunksFaster(final CompletableFuture<Void> spawns) { // DivineMC - Regionized Chunk Ticking
final ServerLevel world = this.level;
final int randomTickSpeed = world.getGameRules().getInt(GameRules.RULE_RANDOMTICKING);
// TODO check on update: impl of forEachBlockTickingChunk will only iterate ENTITY ticking chunks!
// TODO check on update: consumer just runs tickChunk
- final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.world.level.chunk.LevelChunk> entityTickingChunks = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$getEntityTickingChunks();
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<LevelChunk> entityTickingChunks = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$getEntityTickingChunks(); // DivineMC - Regionized Chunk Ticking
// note: we can use the backing array here because:
// 1. we do not care about new additions
// 2. _removes_ are impossible at this stage in the tick
- final LevelChunk[] raw = entityTickingChunks.getRawDataUnchecked();
+ final LevelChunk[] raw = entityTickingChunks.toArray(new LevelChunk[0]); // DivineMC - use toArray instead of getRawDataUnchecked this way is safe and doesn't have performance impact
final int size = entityTickingChunks.size();
- java.util.Objects.checkFromToIndex(0, size, raw.length);
- for (int i = 0; i < size; ++i) {
- world.tickChunk(raw[i], randomTickSpeed);
-
- // call mid-tick tasks for chunk system
- if ((i & 7) == 0) {
- // DivineMC start - Parallel world ticking
- if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) {
- ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer) this.level.getServer()).moonrise$executeMidTickTasks();
- continue;
+ // DivineMC start - Regionized Chunk Ticking
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableRegionizedChunkTicking) {
+ if (this instanceof org.bxteam.divinemc.async.rct.RegionizedChunkTicking rct) {
+ rct.execute(spawns, raw);
+ }
+ } else {
+ java.util.Objects.checkFromToIndex(0, size, raw.length);
+ for (int i = 0; i < size; ++i) {
+ world.tickChunk(raw[i], randomTickSpeed);
+
+ // call mid-tick tasks for chunk system
+ if ((i & 7) == 0) {
+ // DivineMC start - Parallel world ticking
+ if (!org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableParallelWorldTicking) {
+ ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer) this.level.getServer()).moonrise$executeMidTickTasks();
+ continue;
+ }
+ // DivineMC end - Parallel world ticking
}
- // DivineMC end - Parallel world ticking
+ }
+
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncNaturalSpawn) {
+ spawns.join();
}
}
+ // DivineMC end - Regionized Chunk Ticking
}
// Paper end - chunk tick iteration optimisations
@@ -502,14 +516,21 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
long gameTime = this.level.getGameTime();
long l = gameTime - this.lastInhabitedUpdate;
this.lastInhabitedUpdate = gameTime;
- if (!this.level.isDebug()) {
- if (this.level.tickRateManager().runsNormally()) {
- this.tickChunks(l);
- }
+ // DivineMC start - Regionized Chunk Ticking
+ if (this.level.isDebug()) {
+ return;
+ }
+
+ if (!this.level.tickRateManager().runsNormally()) { // DivineMC - when frozen only broadcast changed chunks and don't run async mob spawning
this.broadcastChangedChunks();
+ return;
}
+ this.tickChunks(l);
+ this.broadcastChangedChunks();
+ // DivineMC end - Regionized Chunk Ticking
+
// DivineMC start - Pufferfish: Optimize mob spawning
if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableAsyncSpawning) {
for (ServerPlayer player : this.level.players) {
@@ -553,14 +574,18 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
}
private void broadcastChangedChunks() {
- for (ChunkHolder chunkHolder : this.chunkHoldersToBroadcast) {
- LevelChunk tickingChunk = chunkHolder.getChunkToSend(); // Paper - rewrite chunk system
- if (tickingChunk != null) {
- chunkHolder.broadcastChanges(tickingChunk);
+ // DivineMC start - Regionized Chunk Ticking
+ synchronized (chunkHoldersToBroadcast) {
+ for (ChunkHolder chunkHolder : this.chunkHoldersToBroadcast) {
+ LevelChunk tickingChunk = chunkHolder.getChunkToSend(); // Paper - rewrite chunk system
+ if (tickingChunk != null) {
+ chunkHolder.broadcastChanges(tickingChunk);
+ }
}
- }
- this.chunkHoldersToBroadcast.clear();
+ this.chunkHoldersToBroadcast.clear();
+ }
+ // DivineMC end - Regionized Chunk Ticking
}
private void tickChunks(long timeInhabited) {
@@ -610,6 +635,24 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
filteredSpawningCategories = List.of();
}
+ // DivineMC start - Regionized Chunk Ticking
+ final CompletableFuture<Void> spawns;
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.asyncNaturalSpawn) {
+ spawns = CompletableFuture.runAsync(() -> naturalSpawn(filteredSpawningCategories, timeInhabited), org.bxteam.divinemc.async.rct.RegionizedChunkTicking.REGION_EXECUTOR);
+ } else {
+ naturalSpawn(filteredSpawningCategories, timeInhabited);
+ spawns = new CompletableFuture<>();
+ }
+ // DivineMC end - Regionized Chunk Ticking
+
+ this.iterateTickingChunksFaster(spawns); // Paper - chunk tick iteration optimisations // DivineMC - Regionized Chunk Ticking
+ if (_boolean) {
+ this.level.tickCustomSpawners(this.spawnEnemies);
+ }
+ }
+
+ // DivineMC start - Regionized Chunk Ticking
+ private void naturalSpawn(List<MobCategory> filteredSpawningCategories, long timeInhabited) {
List<LevelChunk> list = this.spawningChunks;
try {
@@ -627,12 +670,12 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
} finally {
list.clear();
}
+ }
- this.iterateTickingChunksFaster(); // Paper - chunk tick iteration optimisations
- if (_boolean) {
- this.level.tickCustomSpawners(this.spawnEnemies);
- }
+ protected net.minecraft.world.level.entity.EntityTickList getEntityTickList() {
+ return level.entityTickList;
}
+ // DivineMC end - Regionized Chunk Ticking
private void tickSpawningChunk(LevelChunk chunk, long timeInhabited, List<MobCategory> spawnCategories, NaturalSpawner.SpawnState spawnState) {
ChunkPos pos = chunk.getPos();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index ca9883277c0f036c94e861f7917ca42facd3c47b..8c98c2593eec14a8a378041e94cf52b8fbfedc30 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -197,7 +197,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
private final LevelTicks<Block> blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded);
private final LevelTicks<Fluid> fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded);
private final PathTypeCache pathTypesByPosCache = new PathTypeCache();
- final Set<Mob> navigatingMobs = new ObjectOpenHashSet<>();
+ final Set<Mob> navigatingMobs = java.util.Collections.synchronizedSet(new ObjectOpenHashSet<>()); // DivineMC - Regionized Chunk Ticking
volatile boolean isUpdatingNavigations;
protected final Raids raids;
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>();
@@ -666,19 +666,37 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
boolean flag = server.forceSynchronousWrites();
DataFixer fixerUpper = server.getFixerUpper();
// Paper - rewrite chunk system
- this.chunkSource = new ServerChunkCache(
- this,
- levelStorageAccess,
- fixerUpper,
- server.getStructureManager(),
- dispatcher,
- chunkGenerator,
- this.spigotConfig.viewDistance, // Spigot
- this.spigotConfig.simulationDistance, // Spigot
- flag,
- null, // Paper - rewrite chunk system
- () -> server.overworld().getDataStorage()
- );
+ // DivineMC start - Regionized Chunk Ticking
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableRegionizedChunkTicking) {
+ this.chunkSource = new org.bxteam.divinemc.async.rct.RegionizedChunkTicking(
+ this,
+ levelStorageAccess,
+ fixerUpper,
+ server.getStructureManager(),
+ dispatcher,
+ chunkGenerator,
+ this.spigotConfig.viewDistance, // Spigot
+ this.spigotConfig.simulationDistance, // Spigot
+ flag,
+ null, // Paper - rewrite chunk system
+ () -> server.overworld().getDataStorage()
+ );
+ } else {
+ this.chunkSource = new ServerChunkCache(
+ this,
+ levelStorageAccess,
+ fixerUpper,
+ server.getStructureManager(),
+ dispatcher,
+ chunkGenerator,
+ this.spigotConfig.viewDistance, // Spigot
+ this.spigotConfig.simulationDistance, // Spigot
+ flag,
+ null, // Paper - rewrite chunk system
+ () -> server.overworld().getDataStorage()
+ );
+ }
+ // DivineMC end - Regionized Chunk Ticking
this.chunkSource.getGeneratorState().ensureStructuresGenerated();
this.portalForcer = new PortalForcer(this);
this.updateSkyBrightness();
@@ -846,6 +864,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.dragonFight.tick();
}
+ // DivineMC start - Regionized Chunk Ticking
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.enableRegionizedChunkTicking) {
+ this.tickBlockEntities();
+ return;
+ }
+ // DivineMC end - Regionized Chunk Ticking
+
io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR
this.entityTickList
.forEach(
@@ -1874,22 +1899,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
if (Shapes.joinIsNotEmpty(collisionShape, collisionShape1, BooleanOp.NOT_SAME)) {
List<PathNavigation> list = new ObjectArrayList<>();
- try { // Paper - catch CME see below why
- for (Mob mob : this.navigatingMobs) {
- PathNavigation navigation = mob.getNavigation();
- if (navigation.shouldRecomputePath(pos)) {
- list.add(navigation);
+ // DivineMC start - Regionized Chunk Ticking
+ synchronized (this.navigatingMobs) {
+ for (Mob mob : this.navigatingMobs) {
+ PathNavigation navigation = mob.getNavigation();
+ if (navigation.shouldRecomputePath(pos)) {
+ list.add(navigation);
+ }
}
}
- // Paper start - catch CME see below why
- } catch (final java.util.ConcurrentModificationException concurrentModificationException) {
- // This can happen because the pathfinder update below may trigger a chunk load, which in turn may cause more navigators to register
- // In this case we just run the update again across all the iterators as the chunk will then be loaded
- // As this is a relative edge case it is much faster than copying navigators (on either read or write)
- this.sendBlockUpdated(pos, oldState, newState, flags);
- return;
- }
- // Paper end - catch CME see below why
+ // DivineMC end - Regionized Chunk Ticking
try {
this.isUpdatingNavigations = true;
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 7fe5cb2ea1c81b12baf302999a2794f20018707c..738cbde3595165e0f05c0a6fde21499e98dc850b 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -113,7 +113,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
.build();
public final org.bxteam.divinemc.util.BlockEntityTickersList blockEntityTickers = new org.bxteam.divinemc.util.BlockEntityTickersList(); // DivineMC - optimize block entity removals - Fix MC-117075
protected final CollectingNeighborUpdater neighborUpdater;
- private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
+ private final List<TickingBlockEntity> pendingBlockEntityTickers = java.util.Collections.synchronizedList(Lists.newArrayList()); // DivineMC - Regionized Chunk Ticking
private boolean tickingBlockEntities;
public final Thread thread;
private final boolean isDebug;
@@ -145,7 +145,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public boolean captureBlockStates = false;
public boolean captureTreeGeneration = false;
- public Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
+ public Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlockStates = java.util.Collections.synchronizedMap(new java.util.LinkedHashMap<>()); // Paper // DivineMC - Regionized Chunk Ticking
public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
@Nullable
public List<net.minecraft.world.entity.item.ItemEntity> captureDrops;
@@ -1459,10 +1459,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public void tickBlockEntities() {
this.tickingBlockEntities = true;
- if (!this.pendingBlockEntityTickers.isEmpty()) {
- this.blockEntityTickers.addAll(this.pendingBlockEntityTickers);
- this.pendingBlockEntityTickers.clear();
+ // DivineMC start - Regionized Chunk Ticking - synchronization fix
+ synchronized (pendingBlockEntityTickers) {
+ if (!this.pendingBlockEntityTickers.isEmpty()) {
+ this.blockEntityTickers.addAll(this.pendingBlockEntityTickers);
+ this.pendingBlockEntityTickers.clear();
+ }
}
+ // DivineMC end - Regionized Chunk Ticking - synchronization fix
// Spigot start
boolean runsNormally = this.tickRateManager().runsNormally();
diff --git a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
index 5d17213a692016d2f005c7820bf2cf1f42ce411f..ccb2e0c28aeaebbeef15fbb650fa3c2e5c241ceb 100644
--- a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
+++ b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
@@ -53,7 +53,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
this.addAndRun(pos, new CollectingNeighborUpdater.MultiNeighborUpdate(pos.immutable(), block, orientation, facing));
}
- private void addAndRun(BlockPos pos, CollectingNeighborUpdater.NeighborUpdates updates) {
+ private synchronized void addAndRun(BlockPos pos, CollectingNeighborUpdater.NeighborUpdates updates) { // DivineMC - Regionized Chunk Ticking - synchronized
boolean flag = this.count > 0;
boolean flag1 = this.maxChainedNeighborUpdates >= 0 && this.count >= this.maxChainedNeighborUpdates;
this.count++;
@@ -72,7 +72,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
}
}
- private void runUpdates() {
+ private synchronized void runUpdates() { // DivineMC - Regionized Chunk Ticking - synchronized
try {
while (!this.stack.isEmpty() || !this.addedThisLayer.isEmpty()) {
for (int i = this.addedThisLayer.size() - 1; i >= 0; i--) {

View File

@@ -452,10 +452,10 @@ index d03d075d5c56b7d2beb5f0aafecbb69f5b3bbf5b..ce3b8f4161dde3e2758c5d33445da150
}
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 74f63e549f8cadc80de26fcad11923151e0c40eb..c549f0203fb278a37f1c3246a98bf3d6e3216afe 100644
index dda53860397ee52f64209a8d08a7707cfa2f7592..8acdce5a4f5546d0fb5907cfc45731c40372e3ed 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -462,8 +462,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -461,8 +461,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
public boolean isPositionTicking(long chunkPos) {
// Paper start - rewrite chunk system

View File

@@ -279,311 +279,326 @@ diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png
index 518591dd83289e041a16e2c2e7d7e7640d4b2e1b..f54753531b3bf2e8b5377f342465e727c7da98f2 100644
GIT binary patch
literal 6677
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
DA-Nv<
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
Mr>mdKI;Vst03o>^`Tzg`
literal 9260
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
HqBZh=dic2S
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