9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-29 20:09:17 +00:00

Readd PWT

This commit is contained in:
Dreeam
2025-06-06 00:26:36 +08:00
parent 982d0044d6
commit 72a8fb8d95
61 changed files with 437 additions and 752 deletions

View File

@@ -0,0 +1,129 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Thu, 6 Mar 2025 00:26:19 +0100
Subject: [PATCH] SparklyPaper: Track each world MSPT
Original project: https://github.com/SparklyPower/SparklyPaper
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index c9b8bc9592d5fce77750de89fa886db383d92a89..1dc599e28682b59c8389ff2ada100b405bf97240 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1687,7 +1687,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Leaf start - SparklyPaper - parallel world ticking mod (move level ticking logic out for branch convergence)
private void tickLevel(ServerLevel serverLevel, BooleanSupplier hasTimeLeft) {
try {
+ long i = Util.getNanos(); // SparklyPaper - track world's MSPT
serverLevel.tick(hasTimeLeft);
+ // SparklyPaper start - track world's MSPT
+ long j = Util.getNanos() - i;
+
+ // These are from the "tickServer" function
+ serverLevel.tickTimes5s.add(this.tickCount, j);
+ serverLevel.tickTimes10s.add(this.tickCount, j);
+ serverLevel.tickTimes60s.add(this.tickCount, j);
+ // SparklyPaper end - track world's MSPT
} 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 85bfc91ff163a2a564b7b610e27ff90e053787d0..f4b9d0bcf305d99d39e530c3369faaec60bbc5a8 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -567,6 +567,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
// Paper end - chunk tick iteration
+ // SparklyPaper start - track world's MSPT
+ public final MinecraftServer.TickTimes tickTimes5s = new MinecraftServer.TickTimes(100);
+ public final MinecraftServer.TickTimes tickTimes10s = new MinecraftServer.TickTimes(200);
+ public final MinecraftServer.TickTimes tickTimes60s = new MinecraftServer.TickTimes(1200);
+ // SparklyPaper end - track world's MSPT
+
public ServerLevel(
MinecraftServer server,
Executor dispatcher,
diff --git a/org/purpurmc/purpur/task/TPSBarTask.java b/org/purpurmc/purpur/task/TPSBarTask.java
index 8769993e7ca59da309087051a3cd38fc562c15d1..b65c839e45402c618020c77fe63b89bd19cc7d96 100644
--- a/org/purpurmc/purpur/task/TPSBarTask.java
+++ b/org/purpurmc/purpur/task/TPSBarTask.java
@@ -28,6 +28,44 @@ public class TPSBarTask extends BossBarTask {
@Override
void updateBossBar(BossBar bossbar, Player player) {
+ // SparklyPaper start - track world's MSPT
+ if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) {
+ // Get player's current world
+ net.minecraft.server.level.ServerLevel serverLevel = ((org.bukkit.craftbukkit.CraftWorld) player.getWorld()).getHandle();
+
+ // Calculate world-specific MSPT and TPS
+ double worldMspt = calculateWorldMSPT(serverLevel);
+ double worldTps = Math.min(20.0, 1000.0 / Math.max(worldMspt, 0.001)); // Avoid division by zero
+
+ // Store original values
+ double originalTps = this.tps;
+ double originalMspt = this.mspt;
+
+ try {
+ // Temporarily set to world values
+ this.tps = worldTps;
+ this.mspt = worldMspt;
+
+ // Create MSPT component with world name
+ Component msptWithWorld = Component.empty()
+ .append(getMSPTColor())
+ .append(Component.text(" [" + player.getWorld().getName() + "]").color(net.kyori.adventure.text.format.NamedTextColor.GRAY));
+
+ // Update the boss bar using the methods that depend on the fields
+ 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 {
+ // Restore original values
+ this.tps = originalTps;
+ this.mspt = originalMspt;
+ }
+ } else {
+ // Default behavior
bossbar.progress(getBossBarProgress());
bossbar.color(getBossBarColor());
bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
@@ -35,6 +73,8 @@ public class TPSBarTask extends BossBarTask {
Placeholder.component("mspt", getMSPTColor()),
Placeholder.component("ping", getPingColor(player.getPing()))
));
+ }
+ // SparklyPaper end - track world's MSPT
}
@Override
@@ -136,6 +176,25 @@ public class TPSBarTask extends BossBarTask {
return MiniMessage.miniMessage().deserialize(color, Placeholder.parsed("text", String.format("%s", ping)));
}
+ // SparklyPaper start - track world's MSPT
+ private double calculateWorldMSPT(net.minecraft.server.level.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;
+ }
+ // SparklyPaper end - track world's MSPT
+
public enum FillMode {
TPS, MSPT, PING
}

View File

@@ -230,10 +230,10 @@ index fb5077450aa9f7b7a03dd20c27a68dfdaab5ef06..f37fd3b9ab725e5b8eb7fccf9b35bbc0
player.getInventory().removeItem(ammo);
}
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 22da84734462d09a55bc599db4374e1e4f4d6bd2..2f679f03360a2847ba3d98a6698b7c0210a0b67e 100644
index c8219508cf94da71143b8672661592c66b341782..6278fe737a555f47625098828a03952cf9b859a7 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -170,6 +170,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
@@ -171,6 +171,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
public final Map<ServerExplosion.CacheKey, Float> explosionDensityCache = new java.util.HashMap<>(); // Paper - Optimize explosions
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here
public final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = org.dreeam.leaf.config.modules.opt.FastRNG.enabled ? new org.dreeam.leaf.util.math.random.FasterRandomSource(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()) : new ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()); // Gale - Pufferfish - move random tick random // Leaf - Faster random generator

View File

@@ -9,10 +9,10 @@ Leaf: ~48ms (-36%)
This should help drastically on the farms that use actively changing fluids.
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 2ecb73fc7b6754ade93bf16b48c623e6b3a955a9..4ecca1bf5ece7788f3de41d5ec58565b8a768251 100644
index f4b9d0bcf305d99d39e530c3369faaec60bbc5a8..a311f81b7f34f2c988ebcd792ca87dfd7b175f96 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -1302,6 +1302,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -1441,6 +1441,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.emptyTime = 0;
}

View File

@@ -10,10 +10,10 @@ Leaf (After): ~628ms (-96%)
This should help for massive hopper chains or hopper matrix.
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 5325989f46bd288c5a6f1362ec17d3354d55abfd..5ca0aa1fdaae3ba03a464e2c5bc061adc076b649 100644
index 8d8d909c4b9496ae6f44ba34203ee40433d37f8c..e82e55ec400c5e338502ed7ce433372a88d4acff 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -1014,15 +1014,29 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@@ -1016,15 +1016,29 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
static class RebindableTickingBlockEntityWrapper implements TickingBlockEntity {
private TickingBlockEntity ticker;
private BlockPos cachedPos; // Leaf - Cache tile entity position
@@ -43,7 +43,7 @@ index 5325989f46bd288c5a6f1362ec17d3354d55abfd..5ca0aa1fdaae3ba03a464e2c5bc061ad
}
@Override
@@ -1032,6 +1046,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@@ -1034,6 +1048,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@Override
public boolean isRemoved() {

View File

@@ -25,10 +25,10 @@ index 3a596650feb96123c5684bb5065e20c5b005c0b9..f7a05fd098ef7b303254cd410414d50d
}
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 2f679f03360a2847ba3d98a6698b7c0210a0b67e..309dbb3b7a485ef5e13f893e53bbdbec1401422e 100644
index 6278fe737a555f47625098828a03952cf9b859a7..4158bbe0740fe2971a9e857cb4cad08ee465576a 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -1174,6 +1174,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
@@ -1177,6 +1177,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
snapshot.setFlags(flags); // Paper - always set the flag of the most recent call to mitigate issues with multiple update at the same pos with different flags
}
BlockState blockState = chunkAt.setBlockState(pos, state, flags);

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Micro optimizations for random tick
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 4ecca1bf5ece7788f3de41d5ec58565b8a768251..05173104db4c04823658930aa92645f6c2400109 100644
index a311f81b7f34f2c988ebcd792ca87dfd7b175f96..4948557d2faef1dff664cd18df7af4564a0431ff 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -905,7 +905,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -1044,7 +1044,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// Paper start - optimise random ticking
private void optimiseRandomTick(final LevelChunk chunk, final int tickSpeed) {
final LevelChunkSection[] sections = chunk.getSections();
@@ -17,7 +17,7 @@ index 4ecca1bf5ece7788f3de41d5ec58565b8a768251..05173104db4c04823658930aa92645f6
final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Leaf - Faster random generator - upcasting
final boolean doubleTickFluids = !ca.spottedleaf.moonrise.common.PlatformHooks.get().configFixMC224294();
@@ -914,41 +914,41 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -1053,41 +1053,41 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
final int offsetZ = cpos.z << 4;
for (int sectionIndex = 0, sectionsLen = sections.length; sectionIndex < sectionsLen; sectionIndex++) {

View File

@@ -11,10 +11,10 @@ As part of: Airplane (https://github.com/TECHNOVE/Airplane)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 309a31215cb63452215fd880590cffd569aee208..1db32873588673900a8afa9767c3af12c7b6742a 100644
index b89923a0b30a294c393716b666ff3377f0a835dc..cfd01993160bcc4a8a5b80c82df7c0c82b70f229 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -4579,10 +4579,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4606,10 +4606,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// Paper start - optimise collisions
public boolean updateFluidHeightAndDoFluidPushing(final TagKey<Fluid> fluid, final double flowScale) {
@@ -26,7 +26,7 @@ index 309a31215cb63452215fd880590cffd569aee208..1db32873588673900a8afa9767c3af12
final AABB boundingBox = this.getBoundingBox().deflate(1.0E-3);
final Level world = this.level;
@@ -4618,7 +4615,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4645,7 +4642,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) {
for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) {

View File

@@ -106,18 +106,18 @@ index 7b686d834e4eb36be5758b0e0a846a70d1e2294b..956d48fb7146b9eb2a5b5b4e23a83f60
final EntityCollectionBySection byType = this.entitiesByType.get(entity.getType());
byType.removeEntity(entity, sectionIndex);
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index bbd2b327c658b56a1fcf30c8b77cab987d688fcc..f8dba8be5774035744233c251c61abf572dd7d49 100644
index 1dc599e28682b59c8389ff2ada100b405bf97240..c2c904565df5fb320b98307a4d451066286ad726 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -290,6 +290,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public boolean lagging = false; // Purpur - Lagging threshold
@@ -291,6 +291,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
protected boolean upnp = false; // Purpur - UPnP Port Forwarding
public final Set<net.minecraft.world.entity.Entity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
public java.util.concurrent.Semaphore serverLevelTickingSemaphore = null; // SparklyPaper - parallel world ticking
+ @Nullable public org.dreeam.leaf.async.ai.AsyncGoalThread asyncGoalThread; // Leaf - Async target finding
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
AtomicReference<S> atomicReference = new AtomicReference<>();
@@ -1073,6 +1074,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1092,6 +1093,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
org.dreeam.leaf.async.AsyncPlayerDataSaving.IO_POOL.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS);
} catch (java.lang.InterruptedException ignored) {}
// Leaf end - Async playerdata saving
@@ -133,23 +133,22 @@ index bbd2b327c658b56a1fcf30c8b77cab987d688fcc..f8dba8be5774035744233c251c61abf5
public String getLocalIp() {
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 54910c2e1d6e6bb556e536fda060bd09402e04e8..747eb54f84650a9a507398e3d5352e001b042490 100644
index 72e871b8c7fee9b5cbd567e03baee80ee4b9c82e..41bdd0a3bb9c18f4eae3e2ca78c2946979da4f0b 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -198,6 +198,11 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -204,6 +204,10 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
DedicatedServer.LOGGER.info("Using " + serverLevelTickingSemaphore.availablePermits() + " permits for parallel world ticking"); // SparklyPaper - parallel world ticking
}
org.purpurmc.purpur.PurpurConfig.registerCommands();
// Purpur end - Purpur config files
// Leaf end - SparklyPaper - parallel world ticking mod (make configurable)
+ // Leaf start - Async target finding
+ if (org.dreeam.leaf.config.modules.async.AsyncTargetFinding.enabled) {
+ asyncGoalThread = new org.dreeam.leaf.async.ai.AsyncGoalThread(this);
+ }
+ // Leaf end - Async target finding
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
// Gale start - Pufferfish - SIMD support
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22deda686a 100644
index 4948557d2faef1dff664cd18df7af4564a0431ff..c0044f4013520fd617ec365012b10862571744f3 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -173,7 +173,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -170,7 +169,7 @@ index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22
public final ServerChunkCache chunkSource;
private final MinecraftServer server;
public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type
@@ -213,6 +222,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -216,6 +225,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current)
public boolean hasRidableMoveEvent = false; // Purpur - Ridables
final List<ServerPlayer> realPlayers; // Leaves - skip
@@ -178,7 +177,7 @@ index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22
@Override
public @Nullable LevelChunk getChunkIfLoaded(int x, int z) {
@@ -331,6 +341,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -334,6 +344,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks();
}
@@ -191,10 +190,10 @@ index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22
@Override
public final ChunkAccess moonrise$syncLoadNonFull(final int chunkX, final int chunkZ, final net.minecraft.world.level.chunk.status.ChunkStatus status) {
return this.moonrise$getChunkTaskScheduler().syncLoadNonFull(chunkX, chunkZ, status);
@@ -693,6 +709,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
@@ -703,6 +719,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle
this.realPlayers = Lists.newArrayList(); // Leaves - skip
this.tickExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new org.dreeam.leaf.async.world.SparklyPaperServerLevelTickExecutorThreadFactory(getWorld().getName())); // SparklyPaper - parallel world ticking
+ // Leaf start - Async target finding
+ if (org.dreeam.leaf.config.modules.async.AsyncTargetFinding.enabled) {
+ this.asyncGoalExecutor = new org.dreeam.leaf.async.ai.AsyncGoalExecutor(server.asyncGoalThread, this);
@@ -204,8 +203,8 @@ index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22
+ // Leaf end - Async target finding
}
// Paper start
@@ -837,12 +860,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// Leaf start - SparklyPaper - parallel world ticking - Shutdown handling for async reads
@@ -976,12 +999,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
this.moonrise$midTickTasks(); // Paper - rewrite chunk system
// Gale end - Airplane - remove lambda from ticking guard - copied from guardEntityTick
@@ -220,16 +219,16 @@ index 05173104db4c04823658930aa92645f6c2400109..e0fdf7205ff1dfab2c5cccd3d18c2b22
}
// Paper - rewrite chunk system
}
@@ -1318,6 +1343,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
@@ -1460,6 +1485,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// Leaf end - SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks)
// Paper end - rewrite chunk system
+ this.leafMidTickTasks(); // Leaf - Async target finding
}
private void tickBlock(BlockPos pos, Block block) {
@@ -1331,6 +1357,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
@@ -1476,6 +1502,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// Leaf end - SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks)
// Paper end - rewrite chunk system
+ this.leafMidTickTasks(); // Leaf - Async target finding
@@ -2047,25 +2046,27 @@ index e1717b5c854aa81fdd7b7e715d7c3498d9f86072..3627e7479b4deea28e268245410ec4cd
static class StriderPathNavigation extends GroundPathNavigation {
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 309dbb3b7a485ef5e13f893e53bbdbec1401422e..1ef49db44e8dcfd944b600ef64dbcaee36546688 100644
index 4158bbe0740fe2971a9e857cb4cad08ee465576a..e380cc68d0d88d983a1b7b1d9ef4ec8ef307761a 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -1525,6 +1525,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
@@ -1531,6 +1531,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
}
// Leaf end - SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) - do not bother with condition work / make configurable
// Paper end - rewrite chunk system
+ ((ServerLevel) this).leafMidTickTasks(); // Leaf - Async target finding
}
}
this.blockEntityTickers.removeMarkedEntries(); // SparklyPaper - optimize block entity removals
@@ -1788,7 +1789,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
@@ -1799,9 +1800,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
@Override
public List<Entity> getEntities(@Nullable Entity entity, AABB boundingBox, Predicate<? super Entity> predicate) {
- if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf start - SparklyPaper - parallel world ticking mod (make configurable)
- ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, boundingBox, "Cannot getEntities asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
- List<Entity> list = Lists.newArrayList();
+ // Leaf start - Async target finding
+ // if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf start - SparklyPaper - parallel world ticking mod (make configurable)
+ // ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, boundingBox, "Cannot getEntities asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
+ //if (org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking.enabled) // Leaf start - SparklyPaper - parallel world ticking mod (make configurable)
+ // ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, boundingBox, "Cannot getEntities asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
+ //List<Entity> list = Lists.newArrayList(); // Leaf - Async target finding - unused
+ // Leaf end - Async target finding

View File

@@ -27,10 +27,10 @@ index 3a78e7512772fd3f7cf8f221e3a72474def14bea..ba52af914e9e231caa0ac50562e9a692
public static final int GENERATED_TICKET_LEVEL = ChunkHolderManager.FULL_LOADED_TICKET_LEVEL;
public static final int LOADED_TICKET_LEVEL = ChunkTaskScheduler.getTicketLevel(ChunkStatus.EMPTY);
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 8b1652805a2ac9ebae9c99dd77e81c7a484a7abb..608d4612ed15ec04492b0137ec61e157161d792f 100644
index e4bccc642abe15b0ec4b1cf2634801065a27e11a..6a9aa085956ddd27e8910dd524ecb79caf9ae0ba 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -432,6 +432,13 @@ public abstract class PlayerList {
@@ -434,6 +434,13 @@ public abstract class PlayerList {
// this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below
// Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks
player.supressTrackerForLogin = true;

View File

@@ -6,7 +6,7 @@ Subject: [PATCH] Sakura: Optimise check inside blocks and traverse blocks
Dreeam TODO: refactor checkinsideblcoks
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 1db32873588673900a8afa9767c3af12c7b6742a..5d1027cb511be78b1e29d0e3bdc49cc9d6add346 100644
index cfd01993160bcc4a8a5b80c82df7c0c82b70f229..f866fd8a7c37b94d24d6d1e41ed0a6106a82a4ac 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -1697,6 +1697,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess

View File

@@ -22,10 +22,10 @@ index 56fd1ed7ccaf96e7eedea60fbdbf7f934939d563..d2f522ea6d0a209496848af073c9af1c
}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index f8dba8be5774035744233c251c61abf572dd7d49..2ca484a6c3e75fd392ca953737bb548ab10f2121 100644
index c2c904565df5fb320b98307a4d451066286ad726..84b90f496e5ab59d43503301fe935627af123e3f 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1771,6 +1771,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1833,6 +1833,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleTick(tickCount); // Leaves - protocol
@@ -46,10 +46,10 @@ index 16b2ca8c96e9561aa57e0903d1e98e6441044b6d..939400c18eb4e87e0bf1b131e1601f4d
private Stream<Entity> mountedOrDismounted(List<Entity> entities) {
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index ccd442b24693bc9269cc8ab3e44887d0ad3eadbd..aee177756afebd3f39917ae8a08bbbd0e2efe4df 100644
index ac7ac519ecc58a31c4b9efc24f054ec014851fb4..59a61ac969e79966484a839b7d9ca0ac50e80994 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -803,6 +803,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -805,6 +805,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
}
}
// Purpur end - Ridables
@@ -71,10 +71,10 @@ index 18f0d486c478087f404d8bb6cd840079e2c8d239..1a6f1c5f4cf13ee50bc8445845cbb973
final byte[] data = discardedPayload.data();
try {
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 608d4612ed15ec04492b0137ec61e157161d792f..7802f33f4259e9df0b2e682dd2e6bb8f6f74f25b 100644
index 6a9aa085956ddd27e8910dd524ecb79caf9ae0ba..e0f6b82d9836cb73f6fe631071bb1a0c5ec77eab 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -684,6 +684,7 @@ public abstract class PlayerList {
@@ -686,6 +686,7 @@ public abstract class PlayerList {
}
public @Nullable net.kyori.adventure.text.Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) {
org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerLeave(player); // Leaves - protocol

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Optimise BlockEntities tickersInLevel
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 5ca0aa1fdaae3ba03a464e2c5bc061adc076b649..3e00ef33413764df933c85bb836d2cd327248edd 100644
index e82e55ec400c5e338502ed7ce433372a88d4acff..155e9b807a61ab1212ee25cc79a386821596dedc 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -73,7 +73,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Only tick items at hand
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index aee177756afebd3f39917ae8a08bbbd0e2efe4df..b4e5405a3b48cc18d2dac264c5bb7ff666ad2e22 100644
index 59a61ac969e79966484a839b7d9ca0ac50e80994..82ac99c3c5b374482f3ff18f5d20bf888091e539 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -832,12 +832,19 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -834,12 +834,19 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
super.tick();
}

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Optimise player movement checks
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 5d1027cb511be78b1e29d0e3bdc49cc9d6add346..1b4aae603e965ae15d9b7e204a2ac5d31d045db0 100644
index f866fd8a7c37b94d24d6d1e41ed0a6106a82a4ac..d09a32288398d3ffa0fa6e9c6fd06f953b33688f 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -1190,7 +1190,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Add configurable death item drop knockback settings
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index b4e5405a3b48cc18d2dac264c5bb7ff666ad2e22..2a4fb4de12409166e9463eacafb13e37760a3a1b 100644
index 82ac99c3c5b374482f3ff18f5d20bf888091e539..c9fbbbef8d006a90023c70419b5be7220602ee3b 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -1051,7 +1051,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1053,7 +1053,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
if (!keepInventory) {
for (ItemStack item : this.getInventory().getContents()) {
if (!item.isEmpty() && !EnchantmentHelper.has(item, net.minecraft.world.item.enchantment.EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) {

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Optimize getScaledTrackingDistance
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 747eb54f84650a9a507398e3d5352e001b042490..595284787053a5fb7385e8493953c73a19fe7aee 100644
index 41bdd0a3bb9c18f4eae3e2ca78c2946979da4f0b..8192031ab3d947bb67eb00eec0a95ea99dce47ad 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -780,7 +780,13 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -785,7 +785,13 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public int getScaledTrackingDistance(int trackingDistance) {

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Optimize isEyeInFluid
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 1b4aae603e965ae15d9b7e204a2ac5d31d045db0..ffb23578d5d7a2a821427dae9bab343ec3c45036 100644
index d09a32288398d3ffa0fa6e9c6fd06f953b33688f..c377aef03861f2d860a7c6273f634248a6963f01 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -269,6 +269,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess

View File

@@ -77,7 +77,7 @@ index 4535858701b2bb232b9d2feb2af6551526232ddc..e65c62dbe4c1560ae153e4c4344e9194
- // Paper end - detailed watchdog information
}
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 0f9d18dd29e210ad656da211a3cb1cb25cd4efb1..d1c36cd17c83e7e0167046093c4a2b8427c8bae0 100644
index b3acfc7e00797ea16cc2c1793452f3ed97b9c61a..17c1b05f520145b84e90fc359dca4523191f08cd 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -622,8 +622,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -94,10 +94,10 @@ index 0f9d18dd29e210ad656da211a3cb1cb25cd4efb1..d1c36cd17c83e7e0167046093c4a2b84
for (LevelChunk levelChunk : list) {
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index e0fdf7205ff1dfab2c5cccd3d18c2b22deda686a..9df599e94e17da12a880df2f40a2117c5ec2a569 100644
index c0044f4013520fd617ec365012b10862571744f3..14d23006d3ec15bb3ec6f976bff6c0975662c69d 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -1373,13 +1373,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -1518,13 +1518,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// Paper end - log detailed entity tick information
public void tickNonPassenger(Entity entity) {
@@ -111,7 +111,7 @@ index e0fdf7205ff1dfab2c5cccd3d18c2b22deda686a..9df599e94e17da12a880df2f40a2117c
entity.setOldPosAndRot();
entity.tickCount++;
entity.totalEntityAge++; // Paper - age-like counter for all entities
@@ -1392,13 +1386,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -1537,13 +1531,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
for (Entity entity1 : entity.getPassengers()) {
this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
}
@@ -126,7 +126,7 @@ index e0fdf7205ff1dfab2c5cccd3d18c2b22deda686a..9df599e94e17da12a880df2f40a2117c
private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index ffb23578d5d7a2a821427dae9bab343ec3c45036..95a15fa08a5bd2bb799a125e03844259038ef290 100644
index c377aef03861f2d860a7c6273f634248a6963f01..192d65bdc9fc9ae96d460e9b0832c20a209d2b0d 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -1140,16 +1140,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -177,7 +177,7 @@ index ffb23578d5d7a2a821427dae9bab343ec3c45036..95a15fa08a5bd2bb799a125e03844259
}
private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) {
@@ -4831,9 +4805,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4858,9 +4832,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public void setDeltaMovement(Vec3 deltaMovement) {
@@ -187,7 +187,7 @@ index ffb23578d5d7a2a821427dae9bab343ec3c45036..95a15fa08a5bd2bb799a125e03844259
}
public void addDeltaMovement(Vec3 addend) {
@@ -4941,9 +4913,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4968,9 +4940,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
// Paper end - Fix MC-4
if (this.position.x != x || this.position.y != y || this.position.z != z) {

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Cache block path type
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 595284787053a5fb7385e8493953c73a19fe7aee..6dec45b376288638433f0d50e474f9713266d99c 100644
index 8192031ab3d947bb67eb00eec0a95ea99dce47ad..6400f2b68a818e771b3b27724dede7f15562b2c0 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -360,6 +360,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -365,6 +365,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
}
if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) mobSpawnExecutor.start(); // Pufferfish

View File

@@ -42,7 +42,7 @@ index 2d24d03bbdb5ee0d862cbfff2219f58afffafe12..11f4f2f3bc4c9f9f6a1f83b90f3de34c
protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 95a15fa08a5bd2bb799a125e03844259038ef290..905ffdc8d9188c40dc86216c651e22dcbd14dc95 100644
index 192d65bdc9fc9ae96d460e9b0832c20a209d2b0d..7961d8ff4fc13ca5274f6667181da5ce557ddc0f 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -370,6 +370,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess

View File

@@ -32327,10 +32327,10 @@ index 175647d57e59e838ea7b4680fbf22c161100c513..a7b772cfc89161414469cd7da374d6c7
return structureTemplate.save(new CompoundTag());
}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 2ca484a6c3e75fd392ca953737bb548ab10f2121..1540b1a571c8f44c4163f4720a9279f87a8032c9 100644
index 84b90f496e5ab59d43503301fe935627af123e3f..54e31a239d6563abe56435ee8de03e55548ead29 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -293,6 +293,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -294,6 +294,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@Nullable public org.dreeam.leaf.async.ai.AsyncGoalThread asyncGoalThread; // Leaf - Async target finding
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
package org.dreeam.leaf.async.world;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PWTEventScheduler {
private static volatile PWTEventScheduler instance;
private final ExecutorService executor;
private PWTEventScheduler() {
this.executor = Executors.newCachedThreadPool(
new ThreadFactoryBuilder()
.setNameFormat("Leaf PWT Event Scheduler Thread - %d")
.setDaemon(true)
.setPriority(Thread.NORM_PRIORITY - 2)
.build()
);
}
public static PWTEventScheduler getScheduler() {
if (instance == null) {
synchronized (PWTEventScheduler.class) {
if (instance == null) {
instance = new PWTEventScheduler();
}
}
}
return instance;
}
public void scheduleTask(Runnable task) {
this.executor.execute(task);
}
}

View File

@@ -0,0 +1,11 @@
package org.dreeam.leaf.async.world;
public enum ReadOperationType {
BLOCK_GET_BIOME,
BLOCK_GET_COMPUTED_BIOME,
BLOCK_IS_INDIRECTLY_POWERED,
BLOCK_GET_BLOCK_POWER,
BLOCK_RAY_TRACE,
BLOCK_CAN_PLACE,
BLOCK_GET_NMS_STATE
}

View File

@@ -0,0 +1,30 @@
package org.dreeam.leaf.async.world;
import ca.spottedleaf.moonrise.common.util.TickThread;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ThreadFactory;
public class SparklyPaperServerLevelTickExecutorThreadFactory implements ThreadFactory {
private final String worldName;
public SparklyPaperServerLevelTickExecutorThreadFactory(final String worldName) {
this.worldName = worldName;
}
@Override
public Thread newThread(@NotNull Runnable runnable) {
TickThread.ServerLevelTickThread tickThread = new TickThread.ServerLevelTickThread(runnable, "Leaf World Ticking Thread - " + this.worldName);
if (tickThread.isDaemon()) {
tickThread.setDaemon(false);
}
if (tickThread.getPriority() != 5) {
tickThread.setPriority(5);
}
return tickThread;
}
}

View File

@@ -0,0 +1,10 @@
package org.dreeam.leaf.async.world;
import java.util.concurrent.CompletableFuture;
public record WorldReadRequest(
ReadOperationType type,
Object[] params, // Parameters for the read operation
CompletableFuture<Object> future // Future to complete with the result
) {
}

View File

@@ -5,7 +5,7 @@ import it.unimi.dsi.fastutil.Pair;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minecraft.Util;
//import org.dreeam.leaf.command.subcommands.MSPTCommand;
import org.dreeam.leaf.command.subcommands.MSPTCommand;
import org.dreeam.leaf.command.subcommands.ReloadCommand;
import org.dreeam.leaf.command.subcommands.VersionCommand;
import org.jetbrains.annotations.NotNull;
@@ -38,13 +38,13 @@ public final class LeafCommand extends Command {
// subcommand label -> subcommand
private static final LeafSubcommand RELOAD_SUBCOMMAND = new ReloadCommand();
private static final LeafSubcommand VERSION_SUBCOMMAND = new VersionCommand();
//private static final LeafSubcommand MSPT_SUBCOMMAND = new MSPTCommand();
private static final LeafSubcommand MSPT_SUBCOMMAND = new MSPTCommand();
private static final Map<String, LeafSubcommand> SUBCOMMANDS = Util.make(() -> {
final Map<Set<String>, LeafSubcommand> 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);
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,244 @@
package org.dreeam.leaf.command.subcommands;
import net.kyori.adventure.text.Component;
import net.minecraft.server.MinecraftServer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
import org.dreeam.leaf.command.LeafCommand;
import org.dreeam.leaf.command.PermissionedLeafSubcommand;
import org.dreeam.leaf.config.modules.async.SparklyPaperParallelWorldTicking;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.PermissionDefault;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.format.NamedTextColor.*;
@DefaultQualifier(NonNull.class)
public final class MSPTCommand extends PermissionedLeafSubcommand {
public static final String LITERAL_ARGUMENT = "mspt";
public static final String PERM = LeafCommand.BASE_PERM + "." + LITERAL_ARGUMENT;
private static final DecimalFormat DF = new DecimalFormat("########0.0");
private static final Component SLASH = text("/");
public MSPTCommand() {
super(PERM, PermissionDefault.TRUE);
}
@Override
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
// Check if parallel world ticking is enabled
if (!SparklyPaperParallelWorldTicking.enabled) {
sender.sendMessage(Component.text()
.content("Per-world MSPT tracking is only available when parallel world ticking is enabled.")
.color(RED)
.build());
sender.sendMessage(Component.text()
.content("Please enable it in your Leaf configuration to use this command.")
.color(GRAY)
.build());
return true;
}
// Check if compact mode is requested
boolean compactMode = args.length > 0 && args[0].equalsIgnoreCase("compact");
MinecraftServer server = MinecraftServer.getServer();
if (compactMode) {
displayCompactStats(sender, server);
} else {
// Display header
sender.sendMessage(Component.text()
.content("━━━━━━━━━━━━━ ")
.color(GOLD)
.append(Component.text("MSPT Statistics").color(YELLOW))
.append(Component.text(" ━━━━━━━━━━━━━").color(GOLD))
.build());
// Overall server MSPT
displayServerMSPT(sender, server);
// Add separator
sender.sendMessage(Component.text(""));
// World-specific MSPT
displayWorldMSPT(sender, server);
}
return true;
}
private void displayCompactStats(CommandSender sender, MinecraftServer server) {
// Get server stats (only 5s data with avg/min/max)
List<Component> serverTimes = eval(server.tickTimes5s.getTimes());
// Display server stats in compact form
sender.sendMessage(Component.text()
.content("Server: ")
.color(GOLD)
.append(serverTimes.get(0)).append(SLASH).append(serverTimes.get(1)).append(SLASH).append(serverTimes.get(2))
.build());
// Display world stats in compact form
for (net.minecraft.server.level.ServerLevel serverLevel : server.getAllLevels()) {
List<Component> worldTimes = eval(serverLevel.tickTimes5s.getTimes());
sender.sendMessage(Component.text()
.content(serverLevel.getWorld().getName() + ": ")
.color(GOLD)
.append(worldTimes.get(0)).append(SLASH).append(worldTimes.get(1)).append(SLASH).append(worldTimes.get(2))
.build());
}
}
private void displayServerMSPT(CommandSender sender, MinecraftServer server) {
List<Component> times = new ArrayList<>();
times.addAll(eval(server.tickTimes5s.getTimes()));
times.addAll(eval(server.tickTimes10s.getTimes()));
times.addAll(eval(server.tickTimes60s.getTimes()));
sender.sendMessage(Component.text()
.content("Server tick times ")
.color(GOLD)
.append(Component.text()
.content("(avg/min/max)")
.color(YELLOW)
)
.build());
sender.sendMessage(Component.text()
.content(" 5s: ")
.color(GOLD)
.append(times.get(0)).append(SLASH).append(times.get(1)).append(SLASH).append(times.get(2))
.build());
sender.sendMessage(Component.text()
.content(" 10s: ")
.color(GOLD)
.append(times.get(3)).append(SLASH).append(times.get(4)).append(SLASH).append(times.get(5))
.build());
sender.sendMessage(Component.text()
.content(" 60s: ")
.color(GOLD)
.append(times.get(6)).append(SLASH).append(times.get(7)).append(SLASH).append(times.get(8))
.build());
}
private void displayWorldMSPT(CommandSender sender, MinecraftServer server) {
sender.sendMessage(Component.text()
.content("World-specific tick times ")
.color(GOLD)
.append(Component.text()
.content("(avg/min/max)")
.color(YELLOW)
)
.build());
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()));
// World name header
sender.sendMessage(Component.text()
.content("")
.color(YELLOW)
.append(Component.text(serverLevel.getWorld().getName()).color(GOLD))
.build());
// Display time periods
sender.sendMessage(Component.text()
.content(" 5s: ")
.color(GRAY)
.append(worldTimes.get(0)).append(SLASH).append(worldTimes.get(1)).append(SLASH).append(worldTimes.get(2))
.build());
sender.sendMessage(Component.text()
.content(" 10s: ")
.color(GRAY)
.append(worldTimes.get(3)).append(SLASH).append(worldTimes.get(4)).append(SLASH).append(worldTimes.get(5))
.build());
sender.sendMessage(Component.text()
.content(" 60s: ")
.color(GRAY)
.append(worldTimes.get(6)).append(SLASH).append(worldTimes.get(7)).append(SLASH).append(worldTimes.get(8))
.build());
boolean hasMoreWorlds = false;
Iterable<net.minecraft.server.level.ServerLevel> levels = server.getAllLevels();
for (net.minecraft.server.level.ServerLevel level : levels) {
if (level != serverLevel) {
hasMoreWorlds = true;
break;
}
}
if (hasMoreWorlds) {
sender.sendMessage(Component.text(""));
}
}
}
private static List<Component> eval(long[] times) {
long min = Integer.MAX_VALUE;
long max = 0L;
long total = 0L;
int count = 0;
for (long value : times) {
if (value > 0L) {
count++;
if (value < min) min = value;
if (value > max) max = value;
total += value;
}
}
if (count == 0) {
// No data available yet
return Arrays.asList(
text("N/A", GRAY),
text("N/A", GRAY),
text("N/A", GRAY)
);
}
double avgD = ((double) total / (double) count) * 1.0E-6D;
double minD = ((double) min) * 1.0E-6D;
double maxD = ((double) max) * 1.0E-6D;
return Arrays.asList(getColoredValue(avgD), getColoredValue(minD), getColoredValue(maxD));
}
private static Component getColoredValue(double value) {
return text(DF.format(value) + "ms",
value >= 50 ? RED :
value >= 40 ? YELLOW :
value >= 30 ? GOLD :
value >= 20 ? GREEN :
AQUA);
}
@Override
public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
if (!SparklyPaperParallelWorldTicking.enabled) {
return Collections.emptyList();
}
if (args.length == 1) {
return Collections.singletonList("compact");
}
return Collections.emptyList();
}
}