9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-22 16:29:23 +00:00

make parallel world ticking to disable or enable; update mspt command and purpur tps bar

This commit is contained in:
NONPLAYT
2025-03-08 17:25:09 +03:00
parent 9cfad68baf
commit 1614fe9dc6
19 changed files with 609 additions and 331 deletions

View File

@@ -261,7 +261,7 @@ index 5ab2c8333178335515e619b87ae420f948c83bd1..9d2bc41befd0f73b6a0f097d45fbe771
}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 781030cb2e0316151c20351f04347c8db63f43e1..527547b98b70429830a3cf82fddba202e0ba8131 100644
index 781030cb2e0316151c20351f04347c8db63f43e1..3002ed51a579e81c3266da79a5dd38bac0b4a39c 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -306,6 +306,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -272,7 +272,76 @@ index 781030cb2e0316151c20351f04347c8db63f43e1..527547b98b70429830a3cf82fddba202
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
@@ -1757,35 +1758,49 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -338,24 +339,36 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private long lastMidTickExecute;
private long lastMidTickExecuteFailure;
+ // DivineMC start - Parallel world ticking
+ private boolean tickLevelMidTickTasks(ServerLevel world) {
+ long currTime = System.nanoTime();
+ if (currTime - ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$getLastMidTickFailure() <= TASK_EXECUTION_FAILURE_BACKOFF) {
+ return false;
+ }
+ if (!world.getChunkSource().pollTask()) {
+ // we need to back off if this fails
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$setLastMidTickFailure(currTime);
+ return false;
+ }
+ return true;
+ }
+ // DivineMC end - Parallel world ticking
+
private boolean tickMidTickTasks() {
// give all worlds a fair chance at by targeting them all.
// if we execute too many tasks, that's fine - we have logic to correctly handle overuse of allocated time.
- boolean executed = false;
- for (final ServerLevel world : this.getAllLevels()) {
- long currTime = System.nanoTime();
- if (currTime - ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$getLastMidTickFailure() <= TASK_EXECUTION_FAILURE_BACKOFF) {
- continue;
- }
- if (!world.getChunkSource().pollTask()) {
- // we need to back off if this fails
- ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$setLastMidTickFailure(currTime);
- } else {
- executed = true;
+ // DivineMC start - Parallel world ticking
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && Thread.currentThread() instanceof ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread levelThread) {
+ return this.tickLevelMidTickTasks(levelThread.currentlyTickingServerLevel);
+ } else {
+ boolean executed = false;
+ for (final ServerLevel world : this.getAllLevels()) {
+ executed = executed || this.tickLevelMidTickTasks(world);
}
- }
- return executed;
+ return executed;
+ }
+ // DivineMC end - Parallel world ticking
}
@Override
@@ -1706,6 +1719,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}
+ // DivineMC start - Parallel world ticking
+ private void tickLevel(ServerLevel serverLevel, BooleanSupplier hasTimeLeft) {
+ try {
+ serverLevel.tick(hasTimeLeft);
+ } catch (Throwable levelTickingException) {
+ CrashReport crashReport = CrashReport.forThrowable(levelTickingException, "Exception ticking world");
+ serverLevel.fillReportDetails(crashReport);
+ throw new ReportedException(crashReport);
+ }
+ }
+ // DivineMC end - Parallel world ticking
+
protected void tickChildren(BooleanSupplier hasTimeLeft) {
ProfilerFiller profilerFiller = Profiler.get();
this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing());
@@ -1757,35 +1782,49 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
this.isIteratingOverLevels = true; // Paper - Throw exception on world create while being ticked
@@ -287,7 +356,10 @@ index 781030cb2e0316151c20351f04347c8db63f43e1..527547b98b70429830a3cf82fddba202
- if (this.tickCount % 20 == 0) {
- profilerFiller.push("timeSync");
- this.synchronizeTime(serverLevel);
+ // DivineMC start - parallel world ticking
- profilerFiller.pop();
- }
- // CraftBukkit end */
+ // DivineMC start - Parallel world ticking
+ java.util.ArrayDeque<java.util.concurrent.Future<ServerLevel>> tasks = new java.util.ArrayDeque<>();
+ try {
+ for (ServerLevel serverLevel : this.getAllLevels()) {
@@ -297,56 +369,53 @@ index 781030cb2e0316151c20351f04347c8db63f43e1..527547b98b70429830a3cf82fddba202
+ net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = serverLevel.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers
+ serverLevel.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur - Ridables
+ profilerFiller.push(() -> serverLevel + " " + serverLevel.dimension().location());
+
+ profilerFiller.push("tick");
+
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) {
+ serverLevelTickingSemaphore.acquire();
+ tasks.add(
+ serverLevel.tickExecutor.submit(() -> {
+ try {
+ ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread currentThread = (ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread) Thread.currentThread();
+ currentThread.currentlyTickingServerLevel = serverLevel;
+
+ serverLevel.tick(hasTimeLeft);
+ } catch (Throwable throwable) {
+ CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
+
+ serverLevel.fillReportDetails(crashreport);
+ throw new ReportedException(crashreport);
- profilerFiller.push("tick");
+ try {
+ tickLevel(serverLevel, hasTimeLeft);
+ } finally {
+ serverLevelTickingSemaphore.release();
+ }
+ }, serverLevel)
+ );
+
+ profilerFiller.pop();
profilerFiller.pop();
+ serverLevel.explosionDensityCache.clear(); // Paper - Optimize explosions
}
- // CraftBukkit end */
+ } else {
+ tickLevel(serverLevel, hasTimeLeft);
+ }
- profilerFiller.push("tick");
-
- try {
- serverLevel.tick(hasTimeLeft);
- } catch (Throwable var7) {
- CrashReport crashReport = CrashReport.forThrowable(var7, "Exception ticking world");
- serverLevel.fillReportDetails(crashReport);
- throw new ReportedException(crashReport);
+ while (!tasks.isEmpty()) {
+ tasks.pop().get();
+ profilerFiller.pop();
+ profilerFiller.pop();
+ serverLevel.explosionDensityCache.clear(); // Paper - Optimize explosions
}
-
- profilerFiller.pop();
- profilerFiller.pop();
- serverLevel.explosionDensityCache.clear(); // Paper - Optimize explosions
+ while (!tasks.isEmpty()) {
+ tasks.pop().get();
+ }
+ } catch (java.lang.InterruptedException | java.util.concurrent.ExecutionException e) {
+ throw new RuntimeException(e); // Propagate exception
+ throw new RuntimeException(e);
}
+ // DivineMC end - parallel world ticking
+ // DivineMC end - Parallel world ticking
this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
profilerFiller.popPush("connection");
@@ -1876,6 +1891,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1876,6 +1915,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
Map<ResourceKey<Level>, ServerLevel> oldLevels = this.levels;
Map<ResourceKey<Level>, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels);
newLevels.remove(level.dimension());
@@ -355,22 +424,24 @@ index 781030cb2e0316151c20351f04347c8db63f43e1..527547b98b70429830a3cf82fddba202
}
// CraftBukkit end
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 61eeec6a0d789e5e44abdeb5826d7ee2307301ba..440824d74912f9cabe950b9b27386fbf715f7884 100644
index 61eeec6a0d789e5e44abdeb5826d7ee2307301ba..d6b8486d8ec534b8fcfa50899cae4281acf9e7cb 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -243,6 +243,10 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -243,6 +243,12 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
+ // DivineMC start - parallel world ticking
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) {
+ serverLevelTickingSemaphore = new java.util.concurrent.Semaphore(org.bxteam.divinemc.DivineConfig.parallelThreadCount);
+ DedicatedServer.LOGGER.info("Using " + serverLevelTickingSemaphore.availablePermits() + " permits for parallel world ticking");
+ DedicatedServer.LOGGER.info("Using {} permits for parallel world ticking", serverLevelTickingSemaphore.availablePermits());
+ }
+ // DivineMC end - parallel world ticking
/*// Purpur start - Purpur config files // Purpur - Configurable void damage height and damage
try {
org.purpurmc.purpur.PurpurConfig.init((java.io.File) options.valueOf("purpur-settings"));
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index fdfb92daeb5dd60360a80baf5c1778d641cfd9be..eeb9ae85b4863a2054cc08837b66a6e47f1e0315 100644
index fdfb92daeb5dd60360a80baf5c1778d641cfd9be..04d36514e55e31d867dca6cd46fdef4fa601c97d 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -184,7 +184,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -398,24 +469,40 @@ index fdfb92daeb5dd60360a80baf5c1778d641cfd9be..eeb9ae85b4863a2054cc08837b66a6e4
this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle
}
@@ -1291,7 +1293,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -1289,12 +1291,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
if (fluidState.is(fluid)) {
fluidState.tick(this, pos, blockState);
}
// Paper start - rewrite chunk system
if ((++this.tickedBlocksOrFluids & 7L) != 0L) {
- ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks();
+ // ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); // DivineMC - remove
- // Paper start - rewrite chunk system
- if ((++this.tickedBlocksOrFluids & 7L) != 0L) {
+ // DivineMC start - Parallel world ticking
+ ++this.tickedBlocksOrFluids;
+ if (!org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && (this.tickedBlocksOrFluids & 7L) != 0L) {
((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks();
}
- // Paper end - rewrite chunk system
-
+ // DivineMC end - Parallel world ticking
}
// Paper end - rewrite chunk system
@@ -1304,7 +1306,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
private void tickBlock(BlockPos pos, Block block) {
@@ -1302,12 +1304,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
if (blockState.is(block)) {
blockState.tick(this, pos, this.random);
}
// Paper start - rewrite chunk system
if ((++this.tickedBlocksOrFluids & 7L) != 0L) {
- ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks();
+ // ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks(); // DivineMC - remove
- // Paper start - rewrite chunk system
- if ((++this.tickedBlocksOrFluids & 7L) != 0L) {
+ // DivineMC start - Parallel world ticking
+ ++this.tickedBlocksOrFluids;
+ if (!org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && (this.tickedBlocksOrFluids & 7L) != 0L) {
((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks();
}
- // Paper end - rewrite chunk system
-
+ // DivineMC end - Parallel world ticking
}
// Paper end - rewrite chunk system
// Paper start - log detailed entity tick information
@@ -1564,6 +1566,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
@@ -434,19 +521,18 @@ index fdfb92daeb5dd60360a80baf5c1778d641cfd9be..eeb9ae85b4863a2054cc08837b66a6e4
// Paper start - extra debug info
if (entity.valid) {
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 515b2178e71a3723eace26c89032e45678145224..a33071d4b9b5ab75bcef93411e67d4f7c47d5c62 100644
index 515b2178e71a3723eace26c89032e45678145224..7bafc62f601d0205bc673c2b6accbd2a80c75277 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -428,6 +428,8 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -427,6 +427,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
return this.viewDistanceHolder;
}
// Paper end - rewrite chunk system
+ public boolean hasTickedAtLeastOnceInNewWorld = false; // DivineMC - parallel world ticking
+
public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) {
super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile);
this.textFilter = server.createTextFilterForPlayer(this);
@@ -803,6 +805,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -803,6 +804,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@Override
public void tick() {
@@ -454,7 +540,7 @@ index 515b2178e71a3723eace26c89032e45678145224..a33071d4b9b5ab75bcef93411e67d4f7
// CraftBukkit start
if (this.joining) {
this.joining = false;
@@ -1448,6 +1451,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1448,6 +1450,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
return this;
} else {
// CraftBukkit start
@@ -462,55 +548,33 @@ index 515b2178e71a3723eace26c89032e45678145224..a33071d4b9b5ab75bcef93411e67d4f7
/*
this.isChangingDimension = true;
LevelData levelData = level.getLevelData();
@@ -1815,6 +1819,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1815,6 +1818,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
return OptionalInt.empty();
} else {
// CraftBukkit start
+ // DivineMC start - parallel world ticking
+ if (!hasTickedAtLeastOnceInNewWorld) {
+ MinecraftServer.LOGGER.warn("Ignoring request to open container " + abstractContainerMenu + " because we haven't ticked in the current world yet!", new Throwable());
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && !hasTickedAtLeastOnceInNewWorld) {
+ MinecraftServer.LOGGER.warn("Ignoring request to open container {} because we haven't ticked in the current world yet!", abstractContainerMenu, new Throwable());
+ return OptionalInt.empty();
+ }
+ // DivineMC end - parallel world ticking
this.containerMenu = abstractContainerMenu; // Moved up
if (!this.isImmobile())
this.connection
@@ -1879,6 +1889,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1879,6 +1888,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
}
@Override
public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+ // DivineMC start - parallel world ticking (debugging)
+ if (org.bxteam.divinemc.DivineConfig.logContainerCreationStacktraces) {
+ MinecraftServer.LOGGER.warn("Closing " + this.getBukkitEntity().getName() + " inventory that was created at", this.containerMenu.containerCreationStacktrace);
+ MinecraftServer.LOGGER.warn("Closing {} inventory that was created at", this.getBukkitEntity().getName(), this.containerMenu.containerCreationStacktrace);
+ }
+ // DivineMC end - parallel world ticking (debugging)
org.bukkit.craftbukkit.event.CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
// Paper end - Inventory close reason
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index f9987beae080f37456bbd195a0b0cd3be40e622a..8c7c18be474fb54e860ef554bbe820a33f5c83f0 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -572,7 +572,7 @@ public class ServerGamePacketListenerImpl
return;
}
// Paper end - Prevent moving into unloaded chunks
- if (d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) {
+ if (!org.bxteam.divinemc.DivineConfig.alwaysAllowWeirdMovement && (d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner())) { // DivineMC - stop weird movement
// CraftBukkit end
LOGGER.warn(
"{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5
@@ -602,7 +602,7 @@ public class ServerGamePacketListenerImpl
d5 = d2 - rootVehicle.getZ();
d7 = d3 * d3 + d4 * d4 + d5 * d5;
boolean flag2 = false;
- if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
+ if (!org.bxteam.divinemc.DivineConfig.alwaysAllowWeirdMovement && (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold)) { // Spigot // DivineMC - stop weird movement
flag2 = true; // Paper - diff on change, this should be moved wrongly
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
}
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 04fdd32394e473995648842027b88bf7ed0136ba..9f73125b4604aa5db4eeaa924a9d24976ec1c3a1 100644
index 04fdd32394e473995648842027b88bf7ed0136ba..676b56c2898d714423dcc87170f325963749cec7 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -150,6 +150,7 @@ public abstract class PlayerList {
@@ -521,20 +585,22 @@ index 04fdd32394e473995648842027b88bf7ed0136ba..9f73125b4604aa5db4eeaa924a9d2497
player.isRealPlayer = true; // Paper
player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed
GameProfile gameProfile = player.getGameProfile();
@@ -716,6 +717,12 @@ public abstract class PlayerList {
@@ -716,6 +717,14 @@ public abstract class PlayerList {
return this.respawn(player, keepInventory, reason, eventReason, null);
}
public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason, org.bukkit.Location location) {
+ // DivineMC start - parallel world ticking (additional concurrency issues logs)
+ if (location != null) // TODO: Is this really never null, or is IntelliJ IDEA tripping? Because I'm pretty sure that this can be null and there isn't any @NotNull annotations
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) {
+ if (location != null)
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot respawn player off-main, from world " + player.serverLevel().getWorld().getName() + " to world " + location.getWorld().getName());
+ else
+ ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot respawn player off-main, respawning in world " + player.serverLevel().getWorld().getName());
+ }
+ // DivineMC end - parallel world ticking (additional concurrency issues logs)
this.players.remove(player);
this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
player.serverLevel().removePlayerImmediately(player, reason);
@@ -725,6 +732,7 @@ public abstract class PlayerList {
@@ -725,6 +734,7 @@ public abstract class PlayerList {
ServerPlayer serverPlayer = player;
Level fromWorld = player.level();
player.wonGame = false;
@@ -543,7 +609,7 @@ index 04fdd32394e473995648842027b88bf7ed0136ba..9f73125b4604aa5db4eeaa924a9d2497
serverPlayer.connection = player.connection;
serverPlayer.restoreFrom(player, keepInventory);
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 80f2d38449f1db1d9b6926e4552d3061cb88b4af..356a1bfc610214912f58c4126cdd5694ffecfcb8 100644
index 3709efe15b30e4140ba677ffdcd4634b06e34d7d..33f24b21e2170700f3d38e072c106e1a65bafc62 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -850,7 +850,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -564,15 +630,15 @@ index 80f2d38449f1db1d9b6926e4552d3061cb88b4af..356a1bfc610214912f58c4126cdd5694
List<Entity> list = new ArrayList<>(passengers.size());
this.ejectPassengers();
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
index 3dcd8df0b395a8fed8bc0cbe0ff78f4ae0056fd3..228c63bf506548666ce87fae694e2270c97c6770 100644
index 3dcd8df0b395a8fed8bc0cbe0ff78f4ae0056fd3..43a421306ee2ebd68981d12ec382ad63cdfeb897 100644
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -93,7 +93,14 @@ public abstract class AbstractContainerMenu {
@@ -92,8 +92,14 @@ public abstract class AbstractContainerMenu {
}
public void startOpen() {}
// CraftBukkit end
+ public Throwable containerCreationStacktrace; // DivineMC - parallel world ticking
+
protected AbstractContainerMenu(@Nullable MenuType<?> menuType, int containerId) {
+ // DivineMC start - parallel world ticking (debugging)
+ if (org.bxteam.divinemc.DivineConfig.logContainerCreationStacktraces) {
@@ -598,7 +664,7 @@ index 264b713e8b7c3d5f7d8e1facc90a60349f2cf414..f461b060e03edf4102290a424ab008b8
serverLevel.capturedBlockStates.clear();
org.bukkit.event.world.StructureGrowEvent structureEvent = null;
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index b4c2602ecf6b943ab022866231f74b850269af8f..ad80b2fe21a09f070bc5e299e18533c2ec811ca3 100644
index b4c2602ecf6b943ab022866231f74b850269af8f..38190a7cf602d1b52c9d8a37bef0d917dd8bae1b 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -172,6 +172,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -617,25 +683,32 @@ index b4c2602ecf6b943ab022866231f74b850269af8f..ad80b2fe21a09f070bc5e299e18533c2
// CraftBukkit start - tree generation
if (this.captureTreeGeneration) {
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
@@ -1537,7 +1539,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -1535,11 +1537,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
toRemove.add(tickingBlockEntity); // Paper - Fix MC-117075; use removeAll
} else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) {
tickingBlockEntity.tick();
// Paper start - rewrite chunk system
if ((++tickedEntities & 7) == 0) {
- ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
+ // ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
- // Paper start - rewrite chunk system
- if ((++tickedEntities & 7) == 0) {
+ // DivineMC start - Parallel world ticking
+ ++tickedEntities;
+ if (!org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && (tickedEntities & 7) == 0) {
((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
}
// Paper end - rewrite chunk system
- // Paper end - rewrite chunk system
+ // DivineMC end - Parallel world ticking
}
@@ -1560,7 +1562,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
}
this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075
@@ -1560,7 +1563,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
// Paper end - Prevent block entity and entity crashes
}
- this.moonrise$midTickTasks(); // Paper - rewrite chunk system
+ // this.moonrise$midTickTasks(); // Paper - rewrite chunk system
+ // this.moonrise$midTickTasks(); // Paper - rewrite chunk system // DivineMC - Parallel world ticking - commented out
}
// Paper start - Option to prevent armor stands from doing entity lookups
@@ -1703,6 +1705,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -1703,6 +1706,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@Nullable
public BlockEntity getBlockEntity(BlockPos pos, boolean validate) {
@@ -643,7 +716,7 @@ index b4c2602ecf6b943ab022866231f74b850269af8f..ad80b2fe21a09f070bc5e299e18533c2
// Paper start - Perf: Optimize capturedTileEntities lookup
net.minecraft.world.level.block.entity.BlockEntity blockEntity;
if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(pos)) != null) {
@@ -1720,6 +1723,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -1720,6 +1724,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
}
public void setBlockEntity(BlockEntity blockEntity) {
@@ -651,7 +724,7 @@ index b4c2602ecf6b943ab022866231f74b850269af8f..ad80b2fe21a09f070bc5e299e18533c2
BlockPos blockPos = blockEntity.getBlockPos();
if (!this.isOutsideBuildHeight(blockPos)) {
// CraftBukkit start
@@ -1804,6 +1808,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -1804,6 +1809,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@Override
public List<Entity> getEntities(@Nullable Entity entity, AABB boundingBox, Predicate<? super Entity> predicate) {
@@ -659,13 +732,21 @@ index b4c2602ecf6b943ab022866231f74b850269af8f..ad80b2fe21a09f070bc5e299e18533c2
Profiler.get().incrementCounter("getEntities");
List<Entity> list = Lists.newArrayList();
@@ -2116,8 +2121,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -2116,8 +2122,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public abstract RecipeAccess recipeAccess();
public BlockPos getBlockRandomPos(int x, int y, int z, int yMask) {
- this.randValue = this.randValue * 3 + 1013904223;
- int i = this.randValue >> 2;
+ int i = this.random.nextInt() >> 2; // DivineMC - parallel world ticking
+ // DivineMC start - Parallel world ticking
+ int i;
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) {
+ i = this.random.nextInt() >> 2;
+ } else {
+ this.randValue = this.randValue * 3 + 1013904223;
+ i = this.randValue >> 2;
+ }
+ // DivineMC end - Parallel world ticking
return new BlockPos(x + (i & 15), y + (i >> 16 & yMask), z + (i >> 8 & 15));
}
@@ -721,33 +802,36 @@ index 904369f4d7db41026183f2de7c96c2f0f4dc204d..1a3f07834fd1483aa77f7733512908b6
return true;
} else {
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..0f56ea9dd444148b134a3d97f0b7c4563df73e39 100644
index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..4293c5f11a17500353b63cad399727ece1461c5e 100644
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
@@ -292,7 +292,7 @@ public class RedStoneWireBlock extends Block {
// Paper start - Optimize redstone (Eigencraft)
// The bulk of the new functionality is found in RedstoneWireTurbo.java
- io.papermc.paper.redstone.RedstoneWireTurbo turbo = new io.papermc.paper.redstone.RedstoneWireTurbo(this);
+ // io.papermc.paper.redstone.RedstoneWireTurbo turbo = new io.papermc.paper.redstone.RedstoneWireTurbo(this);
/*
* Modified version of pre-existing updateSurroundingRedstone, which is called from
@@ -308,7 +308,7 @@ public class RedStoneWireBlock extends Block {
@@ -308,7 +308,13 @@ public class RedStoneWireBlock extends Block {
if (orientation != null) {
source = pos.relative(orientation.getFront().getOpposite());
}
- turbo.updateSurroundingRedstone(worldIn, pos, state, source);
+ worldIn.turbo.updateSurroundingRedstone(worldIn, pos, state, source); // DivineMC - parallel world ticking
+ // DivineMC start - Parallel world ticking
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) {
+ worldIn.turbo.updateSurroundingRedstone(worldIn, pos, state, source);
+ } else {
+ turbo.updateSurroundingRedstone(worldIn, pos, state, source);
+ }
+ // DivineMC end
return;
}
updatePowerStrength(worldIn, pos, state, orientation, blockAdded);
@@ -336,7 +336,7 @@ public class RedStoneWireBlock extends Block {
@@ -336,7 +342,13 @@ public class RedStoneWireBlock extends Block {
// [Space Walker] suppress shape updates and emit those manually to
// bypass the new neighbor update stack.
if (level.setBlock(pos, state, Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS)) {
- turbo.updateNeighborShapes(level, pos, state);
+ level.turbo.updateNeighborShapes(level, pos, state); // DivineMC - parallel world ticking
+ // DivineMC start - Parallel world ticking
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) {
+ level.turbo.updateNeighborShapes(level, pos, state);
+ } else {
+ turbo.updateNeighborShapes(level, pos, state);
+ }
+ // DivineMC end - Parallel world ticking
}
}
}
@@ -778,7 +862,7 @@ index e014f052e9b0f5ca6b28044e2389782b7d0e0cb8..d10f8909fcfa930c726f2620e3ffc912
java.util.List<org.bukkit.block.BlockState> blocks = new java.util.ArrayList<>(level.capturedBlockStates.values());
level.capturedBlockStates.clear();
diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
index 26db603ed681a6c302596627d4dd5bf8a9bafc4e..3b56375f705a0d65901f702e53e1fc609eeaf1a6 100644
index 26db603ed681a6c302596627d4dd5bf8a9bafc4e..b761f12131699bdd075a39f19d96cb70ae8f4eda 100644
--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
@@ -77,6 +77,12 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
@@ -786,8 +870,8 @@ index 26db603ed681a6c302596627d4dd5bf8a9bafc4e..3b56375f705a0d65901f702e53e1fc60
}
public static boolean canUnlock(Player player, LockCode code, Component displayName, @Nullable BlockEntity blockEntity) {
+ // DivineMC start - parallel world ticking
+ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != serverPlayer.serverLevel()) {
+ net.minecraft.server.MinecraftServer.LOGGER.warn("Player " + serverPlayer.getScoreboardName() + " (" + serverPlayer.getStringUUID() + ") attempted to open a BlockEntity @ " + blockEntity.getLevel().getWorld().getName() + " " + blockEntity.getBlockPos().getX() + ", " + blockEntity.getBlockPos().getY() + ", " + blockEntity.getBlockPos().getZ() + " while they were in a different world " + serverPlayer.level().getWorld().getName() + " than the block themselves!");
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != serverPlayer.serverLevel()) {
+ net.minecraft.server.MinecraftServer.LOGGER.warn("Player {} ({}) attempted to open a BlockEntity @ {} {}, {}, {} while they were in a different world {} than the block themselves!", serverPlayer.getScoreboardName(), serverPlayer.getStringUUID(), blockEntity.getLevel().getWorld().getName(), blockEntity.getBlockPos().getX(), blockEntity.getBlockPos().getY(), blockEntity.getBlockPos().getZ(), serverPlayer.level().getWorld().getName());
+ return false;
+ }
+ // DivineMC end - parallel world ticking
@@ -898,7 +982,7 @@ index cf7311c507de09a8f89934e430b2201e8bdffe51..30bd72ad2f66616a89b78fb0677109b8
// CraftBukkit end
}
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 5652ed5fb03a4a1a94c348109cb499196f909712..6167f72d1e374a7093f9880ab50e27eda603a680 100644
index 048ad8e11c6913ef08c977c7fab3200cc610519c..66c7f0d2adc8c00b53125b8cdc5da8c4319eedb5 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -367,6 +367,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@@ -910,13 +994,13 @@ index 5652ed5fb03a4a1a94c348109cb499196f909712..6167f72d1e374a7093f9880ab50e27ed
int y = pos.getY();
LevelChunkSection section = this.getSection(this.getSectionIndex(y));
diff --git a/net/minecraft/world/level/entity/EntityTickList.java b/net/minecraft/world/level/entity/EntityTickList.java
index 423779a2b690f387a4f0bd07b97b50e0baefda76..f43f318577efff0c920029d467a54608614f410c 100644
index 423779a2b690f387a4f0bd07b97b50e0baefda76..2567e3a0988fcd21a39b0c82e1a4b43946810987 100644
--- a/net/minecraft/world/level/entity/EntityTickList.java
+++ b/net/minecraft/world/level/entity/EntityTickList.java
@@ -11,16 +11,27 @@ import net.minecraft.world.entity.Entity;
@@ -10,17 +10,27 @@ import net.minecraft.world.entity.Entity;
public class EntityTickList {
private final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<net.minecraft.world.entity.Entity> entities = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>(); // Paper - rewrite chunk system
+ // DivineMC start - parallel world ticking
+ // Used to track async entity additions/removals/loops
+ private final net.minecraft.server.level.ServerLevel serverLevel;
@@ -925,7 +1009,7 @@ index 423779a2b690f387a4f0bd07b97b50e0baefda76..f43f318577efff0c920029d467a54608
+ this.serverLevel = serverLevel;
+ }
+ // DivineMC end - parallel world ticking
+
private void ensureActiveIsNotIterated() {
// Paper - rewrite chunk system
}
@@ -941,7 +1025,7 @@ index 423779a2b690f387a4f0bd07b97b50e0baefda76..f43f318577efff0c920029d467a54608
this.ensureActiveIsNotIterated();
this.entities.remove(entity); // Paper - rewrite chunk system
}
@@ -30,6 +41,7 @@ public class EntityTickList {
@@ -30,6 +40,7 @@ public class EntityTickList {
}
public void forEach(Consumer<Entity> entity) {

View File

@@ -5,19 +5,19 @@ Subject: [PATCH] Optimize hoppers
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 527547b98b70429830a3cf82fddba202e0ba8131..ee45df82c3328d5cf91cb3e56786aec2d5263641 100644
index 3002ed51a579e81c3266da79a5dd38bac0b4a39c..9fdd4bbbe0e4c75880e9f24741fea7c60c57d09a 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1765,7 +1765,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1789,7 +1789,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
serverLevel.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent
serverLevel.updateLagCompensationTick(); // Paper - lag compensation
- net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = serverLevel.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers
serverLevel.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur - Ridables
profilerFiller.push(() -> serverLevel + " " + serverLevel.dimension().location());
profilerFiller.push("tick");
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index eeb9ae85b4863a2054cc08837b66a6e47f1e0315..8ad95bf8bde55e13f08bcdda332d5079e8bd6296 100644
index 04d36514e55e31d867dca6cd46fdef4fa601c97d..6fc3db6fa365da0512ff3c845586a9d54e8b23b2 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -195,7 +195,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe

View File

@@ -1,13 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 1 Feb 2025 18:03:13 +0300
Subject: [PATCH] Stop teleporting players when they move too quickly
Subject: [PATCH] Option to allow weird movement and disable teleporting
players when they move too quickly
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index aabce23007006fe2dca1e4ac7c0657d2a1cae30e..f52e0ba1ef613895c2f21f39da852593d2f7883f 100644
index f9987beae080f37456bbd195a0b0cd3be40e622a..41365099c2a49a2bc977464081a7c270f210a6be 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -572,7 +572,7 @@ public class ServerGamePacketListenerImpl
return;
}
// Paper end - Prevent moving into unloaded chunks
- if (d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) {
+ if (!org.bxteam.divinemc.DivineConfig.alwaysAllowWeirdMovement && (d7 - d6 > Math.max(100.0, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner())) { // DivineMC - stop weird movement
// CraftBukkit end
LOGGER.warn(
"{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5
@@ -602,7 +602,7 @@ public class ServerGamePacketListenerImpl
d5 = d2 - rootVehicle.getZ();
d7 = d3 * d3 + d4 * d4 + d5 * d5;
boolean flag2 = false;
- if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
+ if (!org.bxteam.divinemc.DivineConfig.alwaysAllowWeirdMovement && (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold)) { // Spigot // DivineMC - stop weird movement
flag2 = true; // Paper - diff on change, this should be moved wrongly
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7));
}
@@ -1444,18 +1444,22 @@ public class ServerGamePacketListenerImpl
if (this.shouldCheckPlayerMovement(isFallFlying)) {
float f2 = isFallFlying ? 300.0F : 100.0F;

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Lag compensation
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index ee45df82c3328d5cf91cb3e56786aec2d5263641..138de3fed3cc7a4dd0633dfdaf9c883f5f6fbd54 100644
index 9fdd4bbbe0e4c75880e9f24741fea7c60c57d09a..ad308e75a58e7db5247489b5d4447b1271ee0102 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -307,6 +307,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -16,7 +16,7 @@ index ee45df82c3328d5cf91cb3e56786aec2d5263641..138de3fed3cc7a4dd0633dfdaf9c883f
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
@@ -1577,6 +1578,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1589,6 +1590,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
this.server.spark.tickStart(); // Paper - spark
@@ -25,7 +25,7 @@ index ee45df82c3328d5cf91cb3e56786aec2d5263641..138de3fed3cc7a4dd0633dfdaf9c883f
this.tickCount++;
this.tickRateManager.tick();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 5dfab22692947e0e372044c6dca181f6847fc58a..dc91371fcaffc8477b1732b79174e7fb2bf7c6b3 100644
index 6fc3db6fa365da0512ff3c845586a9d54e8b23b2..e684eaed9740c3236a8f2bd7cce0d86661632a87 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -219,6 +219,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -66,7 +66,7 @@ index 5dfab22692947e0e372044c6dca181f6847fc58a..dc91371fcaffc8477b1732b79174e7fb
this.serverLevelData.setDayTime(time);
// Purpur start - Configurable daylight cycle
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 30d02d18c3bfc891eb543428143149ed2044fc0f..ef4d526a343aaede08fa4dee48b146f7597a0b75 100644
index e7f1be39ecc532e83d9099e81a2dfd8ed5f0df7d..34a1a6e92a3fcb1e0f1e8e7ccf6cbce7eda8e10e 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -559,6 +559,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -244,7 +244,7 @@ index b631e35e965b1914cdeeddab8bd6bdbfd2465079..bb7dab597850fba8f0dff4461fc518e0
}
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 6167f72d1e374a7093f9880ab50e27eda603a680..88dc5f6e6668d802dc1a21bd894f8ddb1e568033 100644
index 66c7f0d2adc8c00b53125b8cdc5da8c4319eedb5..1cdff5ee25e6ef66e6aae221e61eee7829b213ed 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -913,6 +913,19 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p

View File

@@ -5,13 +5,13 @@ Subject: [PATCH] MSPT Tracking for each world
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 138de3fed3cc7a4dd0633dfdaf9c883f5f6fbd54..506f0469d1a9ee58de0e7a34a61a8092e451dcfd 100644
index ad308e75a58e7db5247489b5d4447b1271ee0102..8feec3f633f2fa12591fb84c90e0b28b7fde7697 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1778,7 +1778,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread currentThread = (ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread) Thread.currentThread();
currentThread.currentlyTickingServerLevel = serverLevel;
@@ -1724,7 +1724,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// DivineMC start - Parallel world ticking
private void tickLevel(ServerLevel serverLevel, BooleanSupplier hasTimeLeft) {
try {
+ // DivineMC start - MSPT Tracking for each world
+ long i = Util.getNanos();
serverLevel.tick(hasTimeLeft);
@@ -21,11 +21,11 @@ index 138de3fed3cc7a4dd0633dfdaf9c883f5f6fbd54..506f0469d1a9ee58de0e7a34a61a8092
+ serverLevel.tickTimes10s.add(this.tickCount, j);
+ serverLevel.tickTimes60s.add(this.tickCount, j);
+ // DivineMC end - MSPT Tracking for each world
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
} catch (Throwable levelTickingException) {
CrashReport crashReport = CrashReport.forThrowable(levelTickingException, "Exception ticking world");
serverLevel.fillReportDetails(crashReport);
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index dc91371fcaffc8477b1732b79174e7fb2bf7c6b3..ba5a803b3ecd2b76c2d3ffd2dc9ea1e95914dd03 100644
index e684eaed9740c3236a8f2bd7cce0d86661632a87..7aef92967cb8a662e644225a4122a544f3cff937 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -575,6 +575,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe

View File

@@ -6,7 +6,7 @@ Subject: [PATCH] Skip EntityScheduler's executeTick checks if there isn't any
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 506f0469d1a9ee58de0e7a34a61a8092e451dcfd..b7815831ff1a2fa9aa52e96f1a50a5aa6823ff8a 100644
index 8feec3f633f2fa12591fb84c90e0b28b7fde7697..7c0081b01140800977ad2dc053d4c4619f263fc2 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -308,6 +308,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -17,7 +17,7 @@ index 506f0469d1a9ee58de0e7a34a61a8092e451dcfd..b7815831ff1a2fa9aa52e96f1a50a5aa
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
@@ -1715,17 +1716,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1747,17 +1748,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit
// Paper start - Folia scheduler API
((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) org.bukkit.Bukkit.getGlobalRegionScheduler()).tick();

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Re-Fix MC-117075
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index ad80b2fe21a09f070bc5e299e18533c2ec811ca3..7c80f90ccab0f90a4c76c2d195f4aaa0b12deb9a 100644
index 38190a7cf602d1b52c9d8a37bef0d917dd8bae1b..533b6d4c5238607818002f0b43ff71226c645886 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -115,7 +115,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -25,8 +25,8 @@ index ad80b2fe21a09f070bc5e299e18533c2ec811ca3..7c80f90ccab0f90a4c76c2d195f4aaa0
+ this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // DivineMC - optimize block entity removals - Fix MC-117075
} else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) {
tickingBlockEntity.tick();
// Paper start - rewrite chunk system
@@ -1546,6 +1546,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
// DivineMC start - Parallel world ticking
@@ -1547,6 +1547,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
}
this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075

View File

@@ -206,10 +206,10 @@ index 30bd254542d631676494f349ff3f44f52d54ab2f..6c728ae3b58bc1b8449d34c6c7409161
private static final String PREFIX = "data:image/png;base64,";
public static final Codec<ServerStatus.Favicon> CODEC = Codec.STRING.comapFlatMap(string -> {
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 440824d74912f9cabe950b9b27386fbf715f7884..374d74d459fb5548a47c0cb3adcf432ee83003d1 100644
index d6b8486d8ec534b8fcfa50899cae4281acf9e7cb..f56bfa062d47c2c333e774ec618710d6dd49e833 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -666,6 +666,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -668,6 +668,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public boolean enforceSecureProfile() {
@@ -287,7 +287,7 @@ index 398c1733824b689520170de0be94006731afa5cd..072e9b8810a6ccc292f1eb5ffe02355a
if (packet == null || this.processedDisconnect) { // Spigot
return;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 9f73125b4604aa5db4eeaa924a9d24976ec1c3a1..5d312dd133c89b51bdb6f7c519e16b718c1dfb79 100644
index 676b56c2898d714423dcc87170f325963749cec7..13f9f9ad57c8f2575dfe5822122abccf29c367a9 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -274,7 +274,7 @@ public abstract class PlayerList {
@@ -299,7 +299,7 @@ index 9f73125b4604aa5db4eeaa924a9d24976ec1c3a1..5d312dd133c89b51bdb6f7c519e16b71
)
);
player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
@@ -1326,6 +1326,7 @@ public abstract class PlayerList {
@@ -1328,6 +1328,7 @@ public abstract class PlayerList {
}
public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public

View File

@@ -20,10 +20,10 @@ index 4535858701b2bb232b9d2feb2af6551526232ddc..aa4dd7517e8be167aef1eaf7aa907e3c
if (var4 instanceof ReportedException reportedException && reportedException.getCause() instanceof OutOfMemoryError) {
throw makeReportedException(var4, packet, processor);
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index b7815831ff1a2fa9aa52e96f1a50a5aa6823ff8a..85f81c83aff81133289a03f12a059729b7d2e00e 100644
index 7c0081b01140800977ad2dc053d4c4619f263fc2..8c6c7f2296e4dca882c9f349772aec02e9d92ee1 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1789,6 +1789,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1734,6 +1734,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
serverLevel.tickTimes10s.add(this.tickCount, j);
serverLevel.tickTimes60s.add(this.tickCount, j);
// DivineMC end - MSPT Tracking for each world
@@ -31,9 +31,9 @@ index b7815831ff1a2fa9aa52e96f1a50a5aa6823ff8a..85f81c83aff81133289a03f12a059729
+ } catch (org.bxteam.divinemc.util.exception.UpdateSuppressorException e) {
+ LOGGER.info(e.getMessage());
+ // DivineMC end - Catch update suppressors
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
} catch (Throwable levelTickingException) {
CrashReport crashReport = CrashReport.forThrowable(levelTickingException, "Exception ticking world");
serverLevel.fillReportDetails(crashReport);
diff --git a/net/minecraft/world/level/block/ShulkerBoxBlock.java b/net/minecraft/world/level/block/ShulkerBoxBlock.java
index cdf835ff107bc1eadde706d69384e687626fce70..c04c66668395fa9167e027131daf75c0e9ee6eff 100644
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java

View File

@@ -36,10 +36,10 @@ index d7922847bd398d809e8b8a31bf136c804305a32b..559fd3d12dc5bc84bd976e684153295d
new java.util.concurrent.LinkedBlockingQueue<>(),
new com.google.common.util.concurrent.ThreadFactoryBuilder()
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 85f81c83aff81133289a03f12a059729b7d2e00e..3f286034d50b53fbd71b4f64d83dc78b46f57f1d 100644
index 8c6c7f2296e4dca882c9f349772aec02e9d92ee1..3bb5f956c2763007a83bc209d339c0159cb1ea8e 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -2814,8 +2814,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2838,8 +2838,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] lithium: block_entity_ticking.sleeping
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index c3163e9f79fcf62e7d7a75d8f27695e232dc7e8c..12bb73f65872d68e5ec4f37ecd8e0122c1fd721f 100644
index 7aef92967cb8a662e644225a4122a544f3cff937..87837ab5ac16786db0b0ddd420b9f7cb797e5bbb 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -2439,7 +2439,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -35,7 +35,7 @@ index c3163e9f79fcf62e7d7a75d8f27695e232dc7e8c..12bb73f65872d68e5ec4f37ecd8e0122
public String getWatchdogStats() {
return String.format(
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 7c80f90ccab0f90a4c76c2d195f4aaa0b12deb9a..9f5a219e2fae7bb08ab921d13d9ae9e782d2afdb 100644
index 533b6d4c5238607818002f0b43ff71226c645886..9cde0f691e51072d02faf9df184030bf9675cb1a 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -1535,7 +1535,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -45,9 +45,9 @@ index 7c80f90ccab0f90a4c76c2d195f4aaa0b12deb9a..9f5a219e2fae7bb08ab921d13d9ae9e7
- } else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) {
+ } else if (runsNormally && this.shouldTickBlockPosFilterNull(this, tickingBlockEntity.getPos())) { // DivineMC - lithium: block_entity_ticking.sleeping
tickingBlockEntity.tick();
// Paper start - rewrite chunk system
if ((++tickedEntities & 7) == 0) {
@@ -1552,6 +1552,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
// DivineMC start - Parallel world ticking
++tickedEntities;
@@ -1553,6 +1553,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
this.spigotConfig.currentPrimedTnt = 0; // Spigot
}

View File

@@ -5,14 +5,14 @@ Subject: [PATCH] Parallel world ticking
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b92a8a80c5 100644
index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..c153e79ebe1f2338f0d0ca6b45b392794ecd2fd7 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
@@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class TickThread extends Thread {
private static final Logger LOGGER = LoggerFactory.getLogger(TickThread.class);
+ public static final boolean HARD_THROW = !org.bxteam.divinemc.DivineBootstrap.disableTickThreadHardThrow; // DivineMC - parallel world ticking - THIS SHOULD NOT BE DISABLED SINCE IT CAN CAUSE DATA CORRUPTION!
+ public static final boolean HARD_THROW = !org.bxteam.divinemc.DivineConfig.disableHardThrow; // DivineMC - Parallel world ticking
private static String getThreadContext() {
return "thread=" + Thread.currentThread().getName();
@@ -21,7 +21,7 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
if (!isTickThread()) {
LOGGER.error("Thread failed main thread check: " + reason + ", context=" + getThreadContext(), new Throwable());
- throw new IllegalStateException(reason);
+ if (HARD_THROW) throw new IllegalStateException(reason); // DivineMC - parallel world ticking - THIS SHOULD NOT BE DISABLED SINCE IT CAN CAUSE DATA CORRUPTION!
+ if (HARD_THROW) throw new IllegalStateException(reason); // DivineMC - Parallel world ticking
}
}
@@ -29,7 +29,7 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
if (!isTickThreadFor(world, pos)) {
final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos;
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + " - " + getTickThreadInformation(world.getServer()); // DivineMC - parallel world ticking
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + " - " + getTickThreadInformation(world.getServer()); // DivineMC - Parallel world ticking
LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex);
}
@@ -38,7 +38,7 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
if (!isTickThreadFor(world, pos, blockRadius)) {
final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius;
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius + " - " + getTickThreadInformation(world.getServer()); // DivineMC - parallel world ticking
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius + " - " + getTickThreadInformation(world.getServer()); // DivineMC - Parallel world ticking
LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex);
}
@@ -47,7 +47,7 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
if (!isTickThreadFor(world, chunkX, chunkZ)) {
final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ);
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ) + " - " + getTickThreadInformation(world.getServer()); // DivineMC - parallel world ticking
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ) + " - " + getTickThreadInformation(world.getServer()); // DivineMC - Parallel world ticking
LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex);
}
@@ -56,7 +56,7 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
if (!isTickThreadFor(entity)) {
final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity);
+ reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity) + " - " + getTickThreadInformation(entity.getServer()); // DivineMC - parallel world ticking
+ reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity) + " - " + getTickThreadInformation(entity.getServer()); // DivineMC - Parallel world ticking
LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex);
}
@@ -65,27 +65,26 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
if (!isTickThreadFor(world, aabb)) {
final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb;
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb + " - " + getTickThreadInformation(world.getServer()); // DivineMC - parallel world ticking
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb + " - " + getTickThreadInformation(world.getServer()); // DivineMC - Parallel world ticking
LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex);
}
@@ -87,12 +88,69 @@ public class TickThread extends Thread {
@@ -87,12 +88,67 @@ public class TickThread extends Thread {
public static void ensureTickThread(final Level world, final double blockX, final double blockZ, final String reason) {
if (!isTickThreadFor(world, blockX, blockZ)) {
final String ex = "Thread failed main thread check: " +
- reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ);
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ) + " - " + getTickThreadInformation(world.getServer()); // DivineMC - parallel world ticking
+ reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ) + " - " + getTickThreadInformation(world.getServer()); // DivineMC - Parallel world ticking
LOGGER.error(ex, new Throwable());
throw new IllegalStateException(ex);
}
}
+ // DivineMC start - parallel world ticking
+ // DivineMC start - Parallel world ticking
+ public static void ensureTickThread(final net.minecraft.server.level.ServerLevel world, final String reason) {
+ if (!isTickThreadFor(world)) {
+ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
+ if (HARD_THROW) throw new IllegalStateException(reason);
+ }
+ }
+
@@ -94,8 +93,7 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
+ boolean isServerLevelTickThread = isServerLevelTickThread();
+ if (!isTickThread || isServerLevelTickThread) {
+ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread ONLY tick thread check: " + reason, new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
+ if (HARD_THROW) throw new IllegalStateException(reason);
+ }
+ }
+
@@ -135,107 +133,70 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
+ public static boolean isServerLevelTickThread() {
+ return Thread.currentThread() instanceof ServerLevelTickThread;
+ }
+ // DivineMC end - parallel world ticking
+ // DivineMC end - Parallel world ticking
+
public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */
private static final AtomicInteger ID_GENERATOR = new AtomicInteger();
@@ -126,8 +184,13 @@ public class TickThread extends Thread {
@@ -126,47 +182,71 @@ public class TickThread extends Thread {
return false;
}
+ // DivineMC start - parallel world ticking
+ // DivineMC start - Parallel world ticking
public static boolean isTickThreadFor(final Level world, final BlockPos pos) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(world);
}
public static boolean isTickThreadFor(final Level world, final BlockPos pos, final int blockRadius) {
@@ -135,38 +198,99 @@ public class TickThread extends Thread {
- return isTickThread();
+ return isTickThreadFor(world);
}
public static boolean isTickThreadFor(final Level world, final ChunkPos pos) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(world);
}
public static boolean isTickThreadFor(final Level world, final Vec3 pos) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(world);
}
public static boolean isTickThreadFor(final Level world, final int chunkX, final int chunkZ) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(world);
}
public static boolean isTickThreadFor(final Level world, final AABB aabb) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(world);
}
public static boolean isTickThreadFor(final Level world, final double blockX, final double blockZ) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(world);
}
public static boolean isTickThreadFor(final Level world, final Vec3 position, final Vec3 deltaMovement, final int buffer) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(world);
}
public static boolean isTickThreadFor(final Level world, final int fromChunkX, final int fromChunkZ, final int toChunkX, final int toChunkZ) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(world);
}
public static boolean isTickThreadFor(final Level world, final int chunkX, final int chunkZ, final int radius) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(world);
+ }
+
+ public static boolean isTickThreadFor(final Level world) {
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ if (Thread.currentThread() instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == world;
+ } else return currentThread instanceof TickThread;
+ } else return isTickThread();
}
public static boolean isTickThreadFor(final Entity entity) {
@@ -244,11 +205,7 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
+ return true;
+ }
+
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
+ return serverLevelTickThread.currentlyTickingServerLevel == entity.level();
+ } else return currentThread instanceof TickThread;
+ return isTickThreadFor(entity.level());
+ }
+
+ public static class ServerLevelTickThread extends TickThread {
@@ -262,7 +219,7 @@ index 69cdd304d255d52c9b7dc9b6a33ffdb630b79abe..e40e1a21c720ddecf84abf5f399b48b9
+
+ public net.minecraft.server.level.ServerLevel currentlyTickingServerLevel;
}
+ // DivineMC end - parallel world ticking
+ // DivineMC end - Parallel world ticking
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index ca60f91ef012c94174a0803eb77699ba9ecff5e1..35afd7268a6f8c5c9d0da751459867c1d8e404bf 100644
@@ -557,21 +514,23 @@ index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..951e47811e861dffd59cc39e2dcd6fd6
net.minecraft.world.item.ItemStack nms = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item);
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index 56453454cbd4b9e9270fc833f8ab38d5fa7a3763..cfc4237211b994a222983a2d1f879cb0f515b581 100644
index 56453454cbd4b9e9270fc833f8ab38d5fa7a3763..a8e740b255336c2d611e44129418b5fb29792592 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -249,8 +249,8 @@ public final class CraftBlockStates {
@@ -249,8 +249,10 @@ public final class CraftBlockStates {
net.minecraft.world.level.block.state.BlockState blockData = craftBlock.getNMS();
BlockEntity tileEntity = craftBlock.getHandle().getBlockEntity(blockPosition);
// Paper start - block state snapshots
- boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT;
- CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot;
+ boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT.get(); // DivineMC - parallel world ticking
+ CraftBlockEntityState.DISABLE_SNAPSHOT.set(!useSnapshot); // DivineMC - parallel world ticking
+ // DivineMC start - Parallel world ticking
+ boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT.get();
+ CraftBlockEntityState.DISABLE_SNAPSHOT.set(!useSnapshot);
+ // DivineMC end - Parallel world ticking
try {
// Paper end
CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity);
@@ -258,7 +258,7 @@ public final class CraftBlockStates {
@@ -258,7 +260,7 @@ public final class CraftBlockStates {
return blockState;
// Paper start
} finally {

View File

@@ -1,50 +0,0 @@
--- a/src/main/java/io/papermc/paper/command/MSPTCommand.java
+++ b/src/main/java/io/papermc/paper/command/MSPTCommand.java
@@ -78,6 +_,47 @@
)
)
);
+
+ // DivineMC start - MSPT Tracking for each world
+ sender.sendMessage(text());
+ sender.sendMessage(text().content("World tick times ").color(GOLD)
+ .append(text().color(YELLOW)
+ .append(
+ text("("),
+ text("avg", GRAY),
+ text("/"),
+ text("min", GRAY),
+ text("/"),
+ text("max", GRAY),
+ text(")")
+ )
+ ).append(
+ text(" from last 5s"),
+ text(",", GRAY),
+ text(" 10s"),
+ text(",", GRAY),
+ text(" 1m"),
+ text(":", YELLOW)
+ )
+ );
+ for (net.minecraft.server.level.ServerLevel serverLevel : server.getAllLevels()) {
+ List<Component> worldTimes = new ArrayList<>();
+ worldTimes.addAll(eval(serverLevel.tickTimes5s.getTimes()));
+ worldTimes.addAll(eval(serverLevel.tickTimes10s.getTimes()));
+ worldTimes.addAll(eval(serverLevel.tickTimes60s.getTimes()));
+
+ sender.sendMessage(text().content("◴ " + serverLevel.getWorld().getName() + ": ").color(GOLD)
+ .append(text().color(GRAY)
+ .append(
+ worldTimes.get(0), SLASH, worldTimes.get(1), SLASH, worldTimes.get(2), text(", ", YELLOW),
+ worldTimes.get(3), SLASH, worldTimes.get(4), SLASH, worldTimes.get(5), text(", ", YELLOW),
+ worldTimes.get(6), SLASH, worldTimes.get(7), SLASH, worldTimes.get(8)
+ )
+ )
+ );
+ }
+ // DivineMC end - MSPT Tracking for each world
+
return true;
}

View File

@@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 8 Mar 2025 16:58:24 +0300
Subject: [PATCH] MSPT Tracking for each world
diff --git a/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java b/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java
index 8769993e7ca59da309087051a3cd38fc562c15d1..3d1b183da57e7e267973db27867c7d9a6a64c044 100644
--- a/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java
+++ b/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java
@@ -4,6 +4,8 @@ import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import net.minecraft.server.level.ServerLevel;
+import org.bukkit.craftbukkit.CraftWorld;
import org.purpurmc.purpur.PurpurConfig;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@@ -28,14 +30,64 @@ public class TPSBarTask extends BossBarTask {
@Override
void updateBossBar(BossBar bossbar, Player player) {
- bossbar.progress(getBossBarProgress());
- bossbar.color(getBossBarColor());
- bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
+ // DivineMC start - MSPT Tracking for each world
+ if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) {
+ ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle();
+
+ double worldMspt = calculateWorldMSPT(serverLevel);
+ double worldTps = Math.min(20.0, 1000.0 / Math.max(worldMspt, 0.001));
+
+ double originalTps = this.tps;
+ double originalMspt = this.mspt;
+
+ try {
+ this.tps = worldTps;
+ this.mspt = worldMspt;
+
+ Component msptWithWorld = Component.empty()
+ .append(getMSPTColor())
+ .append(Component.text(" [" + player.getWorld().getName() + "]").color(net.kyori.adventure.text.format.NamedTextColor.GRAY));
+
+ bossbar.progress(getBossBarProgress());
+ bossbar.color(getBossBarColor());
+ bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
+ Placeholder.component("tps", getTPSColor()),
+ Placeholder.component("mspt", msptWithWorld),
+ Placeholder.component("ping", getPingColor(player.getPing()))
+ ));
+ } finally {
+ this.tps = originalTps;
+ this.mspt = originalMspt;
+ }
+ } else {
+ bossbar.progress(getBossBarProgress());
+ bossbar.color(getBossBarColor());
+ bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
Placeholder.component("tps", getTPSColor()),
Placeholder.component("mspt", getMSPTColor()),
Placeholder.component("ping", getPingColor(player.getPing()))
- ));
+ ));
+ }
+ // DivineMC end - MSPT Tracking for each world
+ }
+
+ // DivineMC start - MSPT Tracking for each world
+ private double calculateWorldMSPT(ServerLevel serverLevel) {
+ long[] times = serverLevel.tickTimes5s.getTimes();
+ long total = 0L;
+ int count = 0;
+
+ for (long value : times) {
+ if (value > 0L) {
+ total += value;
+ count++;
+ }
+ }
+
+ if (count == 0) return 0.0;
+ return (double) total / (double) count * 1.0E-6D;
}
+ // DivineMC end - MSPT Tracking for each world
@Override
public void run() {

View File

@@ -10,7 +10,6 @@ import java.nio.file.Paths;
public class DivineBootstrap {
private static final Logger LOGGER = LoggerFactory.getLogger("bootstrap");
public static final boolean disableTickThreadHardThrow = Boolean.parseBoolean(System.getProperty("DivineMC.disableTickThreadHardThrow", "false"));
public static void boot(final OptionSet options) {
runPreBootTasks();

View File

@@ -152,16 +152,19 @@ public class DivineConfig {
return config.getStringList(key);
}
public static boolean enableParallelWorldTicking = true;
public static int parallelThreadCount = 4;
public static boolean logContainerCreationStacktraces = false;
public static boolean disableHardThrow = false;
private static void parallelWorldTicking() {
parallelThreadCount = getInt("settings.parallel-world-ticking.thread-count", parallelThreadCount);
logContainerCreationStacktraces = getBoolean("settings.parallel-world-ticking.log-container-creation-stacktraces", logContainerCreationStacktraces);
setComment("settings.parallel-world-ticking",
"Parallel World Ticking executes each worlds tick in a separate thread while ensuring that all worlds complete their tick before the next cycle begins.",
enableParallelWorldTicking = getBoolean("settings.parallel-world-ticking.enable", enableParallelWorldTicking,
"Enables Parallel World Ticking, which executes each worlds tick in a separate thread while ensuring that all worlds complete their tick before the next cycle begins.",
"",
"Read more info about this feature at https://bxteam.org/docs/divinemc/features/parallel-world-ticking");
parallelThreadCount = getInt("settings.parallel-world-ticking.thread-count", parallelThreadCount);
logContainerCreationStacktraces = getBoolean("settings.parallel-world-ticking.log-container-creation-stacktraces", logContainerCreationStacktraces);
disableHardThrow = getBoolean("settings.parallel-world-ticking.disable-hard-throw", disableHardThrow,
"Disables annoying 'not on main thread' throws. But, THIS IS NOT RECOMMENDED because you SHOULD FIX THE ISSUES THEMSELVES instead of RISKING DATA CORRUPTION! If you lose something, take the blame on yourself.");
}
public static boolean nativeAccelerationEnabled = true;

View File

@@ -10,6 +10,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.PluginManager;
import org.bxteam.divinemc.command.subcommands.MSPTCommand;
import org.bxteam.divinemc.command.subcommands.ReloadCommand;
import org.bxteam.divinemc.command.subcommands.VersionCommand;
import org.jetbrains.annotations.Nullable;
@@ -29,11 +30,13 @@ public final class DivineCommand extends Command {
private static final DivineSubCommand RELOAD_SUBCOMMAND = new ReloadCommand();
private static final DivineSubCommand VERSION_SUBCOMMAND = new VersionCommand();
private static final DivineSubCommand MSPT_SUBCOMMAND = new MSPTCommand();
private static final Map<String, DivineSubCommand> SUBCOMMANDS = Util.make(() -> {
final Map<Set<String>, DivineSubCommand> commands = new HashMap<>();
commands.put(Set.of(ReloadCommand.LITERAL_ARGUMENT), RELOAD_SUBCOMMAND);
commands.put(Set.of(VersionCommand.LITERAL_ARGUMENT), VERSION_SUBCOMMAND);
commands.put(Set.of(MSPTCommand.LITERAL_ARGUMENT), MSPT_SUBCOMMAND);
return commands.entrySet().stream()
.flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))

View File

@@ -0,0 +1,171 @@
package org.bxteam.divinemc.command.subcommands;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.PermissionDefault;
import org.bxteam.divinemc.DivineConfig;
import org.bxteam.divinemc.command.DivineCommand;
import org.bxteam.divinemc.command.DivineSubCommandPermission;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.stream.LongStream;
import static net.kyori.adventure.text.format.NamedTextColor.*;
@DefaultQualifier(NonNull.class)
public final class MSPTCommand extends DivineSubCommandPermission {
public static final String LITERAL_ARGUMENT = "mspt";
public static final String PERM = DivineCommand.BASE_PERM + "." + LITERAL_ARGUMENT;
private static final DecimalFormat DF = new DecimalFormat("########0.0");
private static final Component SLASH = Component.text("/");
public MSPTCommand() {
super(PERM, PermissionDefault.TRUE);
}
@Override
public boolean execute(CommandSender sender, String subCommand, String[] args) {
if (!DivineConfig.enableParallelWorldTicking) {
sender.sendMessage(Component.text("Per-world MSPT tracking is only available when parallel world ticking is enabled.", RED));
sender.sendMessage(Component.text("Please enable it in divinemc.yml to use this command.", GRAY));
return true;
}
boolean compactMode = args.length > 0 && args[0].equalsIgnoreCase("compact");
MinecraftServer server = MinecraftServer.getServer();
if (compactMode) {
displayCompactStats(sender, server);
} else {
sender.sendMessage(Component.text("━━━━━━━━━━━━━ ", GOLD)
.append(Component.text("MSPT Statistics", YELLOW))
.append(Component.text(" ━━━━━━━━━━━━━", GOLD)));
displayServerMSPT(sender, server);
sender.sendMessage(Component.empty());
displayWorldMSPT(sender, server);
}
return true;
}
private void displayCompactStats(CommandSender sender, MinecraftServer server) {
List<Component> serverTimes = eval(server.tickTimes5s.getTimes());
sender.sendMessage(Component.text("Server: ", GOLD)
.append(joinComponents(serverTimes, SLASH)));
List<ServerLevel> worlds = new ArrayList<>();
server.getAllLevels().forEach(worlds::add);
for (int i = 0; i < worlds.size(); i++) {
ServerLevel level = worlds.get(i);
List<Component> worldTimes = eval(level.tickTimes5s.getTimes());
sender.sendMessage(Component.text(level.getWorld().getName() + ": ", GOLD)
.append(joinComponents(worldTimes, SLASH)));
if (i < worlds.size() - 1) {
sender.sendMessage(Component.empty());
}
}
}
private void displayServerMSPT(CommandSender sender, MinecraftServer server) {
sender.sendMessage(Component.text("Server tick times ", GOLD)
.append(Component.text("(avg/min/max)", YELLOW)));
sendTickLine(sender, " 5s: ", eval(server.tickTimes5s.getTimes()), GOLD, SLASH);
sendTickLine(sender, " 10s: ", eval(server.tickTimes10s.getTimes()), GOLD, SLASH);
sendTickLine(sender, " 60s: ", eval(server.tickTimes60s.getTimes()), GOLD, SLASH);
}
private void displayWorldMSPT(CommandSender sender, MinecraftServer server) {
sender.sendMessage(Component.text("World-specific tick times ", GOLD)
.append(Component.text("(avg/min/max)", YELLOW)));
List<ServerLevel> worlds = new ArrayList<>();
server.getAllLevels().forEach(worlds::add);
for (int i = 0; i < worlds.size(); i++) {
ServerLevel level = worlds.get(i);
List<Component> worldTimes = new ArrayList<>();
worldTimes.addAll(eval(level.tickTimes5s.getTimes()));
worldTimes.addAll(eval(level.tickTimes10s.getTimes()));
worldTimes.addAll(eval(level.tickTimes60s.getTimes()));
sender.sendMessage(Component.text("", YELLOW)
.append(Component.text(level.getWorld().getName(), GOLD)));
sendTickLine(sender, " 5s: ", worldTimes.subList(0, 3), GRAY, SLASH);
sendTickLine(sender, " 10s: ", worldTimes.subList(3, 6), GRAY, SLASH);
sendTickLine(sender, " 60s: ", worldTimes.subList(6, 9), GRAY, SLASH);
if (i < worlds.size() - 1) {
sender.sendMessage(Component.empty());
}
}
}
private static List<Component> eval(long[] times) {
LongSummaryStatistics stats = LongStream.of(times)
.filter(value -> value > 0L)
.summaryStatistics();
if (stats.getCount() == 0) {
return Arrays.asList(
Component.text("N/A", GRAY),
Component.text("N/A", GRAY),
Component.text("N/A", GRAY)
);
}
double avg = stats.getAverage() * 1.0E-6;
double min = stats.getMin() * 1.0E-6;
double max = stats.getMax() * 1.0E-6;
return Arrays.asList(getColoredValue(avg), getColoredValue(min), getColoredValue(max));
}
private static Component getColoredValue(double value) {
NamedTextColor color = value >= 50 ? RED
: value >= 40 ? YELLOW
: value >= 30 ? NamedTextColor.GOLD
: value >= 20 ? GREEN
: AQUA;
return Component.text(DF.format(value) + "ms", color);
}
private void sendTickLine(CommandSender sender, String label, List<Component> tickComponents, NamedTextColor labelColor, Component separator) {
sender.sendMessage(Component.text(label, labelColor)
.append(joinComponents(tickComponents, separator)));
}
private Component joinComponents(List<Component> components, Component separator) {
Component result = Component.empty();
for (int i = 0; i < components.size(); i++) {
result = result.append(components.get(i));
if (i < components.size() - 1) {
result = result.append(separator);
}
}
return result;
}
@Override
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args) {
if (!DivineConfig.enableParallelWorldTicking) {
return Collections.emptyList();
}
if (args.length == 1) {
return Collections.singletonList("compact");
}
return Collections.emptyList();
}
}

View File

@@ -1,5 +1,6 @@
package org.bxteam.divinemc.command.subcommands;
import net.kyori.adventure.text.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import org.bukkit.command.Command;
@@ -9,14 +10,15 @@ import org.bukkit.permissions.PermissionDefault;
import org.bxteam.divinemc.command.DivineCommand;
import org.bxteam.divinemc.command.DivineSubCommandPermission;
import org.bxteam.divinemc.DivineConfig;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
import java.io.File;
import java.io.IOException;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
import static net.kyori.adventure.text.format.NamedTextColor.RED;
import static net.kyori.adventure.text.format.NamedTextColor.*;
@DefaultQualifier(NonNull.class)
public final class ReloadCommand extends DivineSubCommandPermission {
public final static String LITERAL_ARGUMENT = "reload";
public static final String PERM = DivineCommand.BASE_PERM + "." + LITERAL_ARGUMENT;
@@ -32,8 +34,8 @@ public final class ReloadCommand extends DivineSubCommandPermission {
}
private void doReload(final CommandSender sender) {
Command.broadcastCommandMessage(sender, text("Please note that this command is not supported and may cause issues.", RED));
Command.broadcastCommandMessage(sender, text("If you encounter any issues please use the /stop command to restart your server.", RED));
Command.broadcastCommandMessage(sender, Component.text("Please note that this command is not supported and may cause issues.", RED));
Command.broadcastCommandMessage(sender, Component.text("If you encounter any issues please use the /stop command to restart your server.", RED));
MinecraftServer server = ((CraftServer) sender.getServer()).getServer();
@@ -47,12 +49,12 @@ public final class ReloadCommand extends DivineSubCommandPermission {
try {
level.divineConfig.init();
} catch (IOException e) {
MinecraftServer.LOGGER.error("Failed to reload DivineMC world config for level " + level.dimension().location(), e);
MinecraftServer.LOGGER.error("Failed to reload DivineMC world config for level {}", level.dimension().location(), e);
}
level.resetBreedingCooldowns();
}
server.server.reloadCount++;
Command.broadcastCommandMessage(sender, text("DivineMC config reload complete.", GREEN));
Command.broadcastCommandMessage(sender, Component.text("DivineMC config reload complete.", GREEN));
}
}