diff --git a/luminol-api/paper-patches/features/0006-FoliaPR-Add-TPS-From-Region.patch b/luminol-api/paper-patches/features/0006-FoliaPR-Add-TPS-From-Region.patch new file mode 100644 index 0000000..02bb205 --- /dev/null +++ b/luminol-api/paper-patches/features/0006-FoliaPR-Add-TPS-From-Region.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrHua269 +Date: Sun, 12 Jan 2025 15:39:43 +0800 +Subject: [PATCH] FoliaPR Add TPS From Region + + +diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java +index 9eecd3a68a36d06c66d5f2cdc98c048fe8737337..f139bcd2d64f9ecc6db4c21170d42011642190f7 100644 +--- a/src/main/java/org/bukkit/Bukkit.java ++++ b/src/main/java/org/bukkit/Bukkit.java +@@ -2426,6 +2426,28 @@ public final class Bukkit { + } + // Paper end + ++ // Folia start ++ /** ++ * Gets the current location TPS. ++ * ++ * @param location the location for which to get the TPS ++ * @return current location TPS (5s, 15s, 1m, 5m, 15m in Folia-Server), or null if the region doesn't exist ++ */ ++ public double @Nullable [] getTPS(Location location) { ++ return server.getTPS(location); ++ } ++ ++ /** ++ * Gets the current chunk TPS. ++ * ++ * @param chunk the chunk for which to get the TPS ++ * @return current chunk TPS (5s, 15s, 1m, 5m, 15m in Folia-Server), or null if the region doesn't exist ++ */ ++ public double @Nullable [] getTPS(Chunk chunk){ ++ return server.getTPS(chunk); ++ } ++ // Folia end ++ + /** + * Get the advancement specified by this key. + * +diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java +index 041ebeb28378c2f81ccbc586fea9583e059cfbd7..482c8b456a16f53310ee45a6ec5746e0241fab41 100644 +--- a/src/main/java/org/bukkit/Server.java ++++ b/src/main/java/org/bukkit/Server.java +@@ -2110,6 +2110,24 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + double getAverageTickTime(); + // Paper end + ++ // Folia start ++ /** ++ * Gets the current location TPS. ++ * ++ * @param location the location for which to get the TPS ++ * @return current location TPS (5s, 15s, 1m, 5m, 15m in Folia-Server), or null if the region doesn't exist ++ */ ++ public double @Nullable [] getTPS(Location location); ++ ++ /** ++ * Gets the current chunk TPS. ++ * ++ * @param chunk the chunk for which to get the TPS ++ * @return current chunk TPS (5s, 15s, 1m, 5m, 15m in Folia-Server), or null if the region doesn't exist ++ */ ++ public double @Nullable [] getTPS(Chunk chunk); ++ // Folia end ++ + // Paper start + /** + * Gets the active {@link org.bukkit.command.CommandMap} diff --git a/luminol-server/minecraft-patches/features/0033-Gale-Skip-entity-move-if-movement-is-zero.patch b/luminol-server/minecraft-patches/features/0033-Gale-Skip-entity-move-if-movement-is-zero.patch new file mode 100644 index 0000000..7559137 --- /dev/null +++ b/luminol-server/minecraft-patches/features/0033-Gale-Skip-entity-move-if-movement-is-zero.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrHua269 +Date: Sun, 12 Jan 2025 15:35:15 +0800 +Subject: [PATCH] Gale Skip entity move if movement is zero + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 41313532c739027351d6fd848aa1c515aa4acd4a..d58f2bfde617ab55a550cbf8eb0187c9663d38fc 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -1104,7 +1104,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + private volatile boolean preventMoving = false; + //Luminol end + ++ private boolean boundingBoxChanged = false; // Gale - VMP - skip entity move if movement is zero ++ + public void move(MoverType type, Vec3 movement) { ++ // Gale start - VMP - skip entity move if movement is zero ++ if (!this.boundingBoxChanged && movement.equals(Vec3.ZERO)) { ++ return; ++ } ++ // Gale end - VMP - skip entity move if movement is zero + final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity + // Paper start - detailed watchdog information + ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main"); +@@ -5031,6 +5038,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public final void setBoundingBox(AABB bb) { ++ // Gale start - VMP - skip entity move if movement is zero ++ if (!this.bb.equals(bb)) { ++ this.boundingBoxChanged = true; ++ } ++ // Gale end - VMP - skip entity move if movement is zero + // CraftBukkit start - block invalid bounding boxes + double minX = bb.minX, + minY = bb.minY, diff --git a/luminol-server/minecraft-patches/features/0034-Sparkly-Paper-Optimize-canSee-checks.patch b/luminol-server/minecraft-patches/features/0034-Sparkly-Paper-Optimize-canSee-checks.patch new file mode 100644 index 0000000..046fbaf --- /dev/null +++ b/luminol-server/minecraft-patches/features/0034-Sparkly-Paper-Optimize-canSee-checks.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrHua269 +Date: Sun, 12 Jan 2025 15:35:43 +0800 +Subject: [PATCH] Sparkly Paper Optimize canSee checks + + +diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java +index 65b9a49e84d9bde75c249651e974d57bc1a43277..20203ae554751920fd4a490190b9593015437f0f 100644 +--- a/net/minecraft/server/level/ChunkMap.java ++++ b/net/minecraft/server/level/ChunkMap.java +@@ -1223,7 +1223,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + // Folia end - region threading + // CraftBukkit start - respect vanish API +- if (flag && (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSee(this.entity.getBukkitEntity()))) { // Paper - only consider hits // Folia - region threading ++ if (flag && (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSeeChunkMapUpdatePlayer(this.entity.getBukkitEntity()))) { // Paper - only consider hits // Folia - region threading // SparklyPaper - optimize canSee checks + flag = false; + } + // CraftBukkit end diff --git a/luminol-server/minecraft-patches/features/0035-SparklyPaper-Skip-distanceToSqr-call-in.patch b/luminol-server/minecraft-patches/features/0035-SparklyPaper-Skip-distanceToSqr-call-in.patch new file mode 100644 index 0000000..89be9cd --- /dev/null +++ b/luminol-server/minecraft-patches/features/0035-SparklyPaper-Skip-distanceToSqr-call-in.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrHua269 +Date: Sun, 12 Jan 2025 15:37:25 +0800 +Subject: [PATCH] SparklyPaper Skip "distanceToSqr" call in + "ServerEntity#sendChanges" if the delta movement hasn't changed + + +diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java +index 0fb253aa55a24b56b17f524b3261c5b75c7d7e59..1de43a4969a2a4535239b15a7bc30d99eb6934c6 100644 +--- a/net/minecraft/server/level/ServerEntity.java ++++ b/net/minecraft/server/level/ServerEntity.java +@@ -195,6 +195,8 @@ public class ServerEntity { + + if (this.entity.hasImpulse || this.trackDelta || this.entity instanceof LivingEntity && ((LivingEntity)this.entity).isFallFlying()) { + Vec3 deltaMovement = this.entity.getDeltaMovement(); ++ ++ if (deltaMovement != this.lastSentMovement) { // SparklyPaper start - skip distanceToSqr call in ServerEntity#sendChanges if the delta movement hasn't changed + double d = deltaMovement.distanceToSqr(this.lastSentMovement); + if (d > 1.0E-7 || d > 0.0 && deltaMovement.lengthSqr() == 0.0) { + this.lastSentMovement = deltaMovement; +@@ -212,6 +214,7 @@ public class ServerEntity { + this.broadcast.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement)); + } + } ++ } // SparklyPaper end + } + + if (packet != null) { diff --git a/luminol-server/paper-patches/features/0031-Sparkly-Paper-Optimize-canSee-checks.patch b/luminol-server/paper-patches/features/0031-Sparkly-Paper-Optimize-canSee-checks.patch new file mode 100644 index 0000000..7cb6661 --- /dev/null +++ b/luminol-server/paper-patches/features/0031-Sparkly-Paper-Optimize-canSee-checks.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrHua269 +Date: Sun, 12 Jan 2025 15:35:44 +0800 +Subject: [PATCH] Sparkly Paper Optimize canSee checks + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index f6da4c065e362db093a882edbb3238ec48cb7999..0a4d27e11f0a9514012cb90112e397bf73180bd6 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -207,7 +207,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + private boolean hasPlayedBefore = false; + private final ConversationTracker conversationTracker = new ConversationTracker(); + private final Set channels = new HashSet(); +- private final Map>> invertedVisibilityEntities = new HashMap<>(); ++ private final Map>> invertedVisibilityEntities = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // SparklyPaper - optimize canSee checks + private final Set unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player + private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); + private int hash = 0; +@@ -2260,9 +2260,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + + @Override + public boolean canSee(org.bukkit.entity.Entity entity) { +- return this.equals(entity) || entity.isVisibleByDefault() ^ this.invertedVisibilityEntities.containsKey(entity.getUniqueId()); // SPIGOT-7312: Can always see self ++ return this.equals(entity) || entity.isVisibleByDefault() ^ (!invertedVisibilityEntities.isEmpty() && this.invertedVisibilityEntities.containsKey(entity.getUniqueId())); // SPIGOT-7312: Can always see self // SparklyPaper - optimize canSee checks + } + ++ // SparklyPaper - optimize canSee checks ++ // The check in ChunkMap#updatePlayer already rejects if it is the same entity, so we don't need to check it twice, especially because CraftPlayer's equals check is a bit expensive ++ public boolean canSeeChunkMapUpdatePlayer(org.bukkit.entity.Entity entity) { ++ return entity.isVisibleByDefault() ^ (!invertedVisibilityEntities.isEmpty() && this.invertedVisibilityEntities.containsKey(entity.getUniqueId())); // SPIGOT-7312: Can always see self // SparklyPaper - optimize canSee checks ++ } ++ // SparklyPaper end ++ + public boolean canSeePlayer(UUID uuid) { + org.bukkit.entity.Entity entity = this.getServer().getPlayer(uuid); + diff --git a/luminol-server/paper-patches/features/0032-Leaf-Skip-event-if-no-listeners.patch b/luminol-server/paper-patches/features/0032-Leaf-Skip-event-if-no-listeners.patch new file mode 100644 index 0000000..af39cd2 --- /dev/null +++ b/luminol-server/paper-patches/features/0032-Leaf-Skip-event-if-no-listeners.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrHua269 +Date: Sun, 12 Jan 2025 15:37:56 +0800 +Subject: [PATCH] Leaf Skip event if no listeners + + +diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +index 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..9180f23529a31b6b0a5b38bb7cda3e32d487f691 100644 +--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java ++++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +@@ -36,15 +36,17 @@ class PaperEventManager { + + // SimplePluginManager + public void callEvent(@NotNull Event event) { ++ // Leaf start - Skip event if no listeners ++ RegisteredListener[] listeners = event.getHandlers().getRegisteredListeners(); ++ if (listeners.length == 0) return; ++ // Leaf end - Skip event if no listeners ++ + if (event.isAsynchronous() && this.server.isPrimaryThread()) { + throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously."); + } else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) { + throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); + } + +- HandlerList handlers = event.getHandlers(); +- RegisteredListener[] listeners = handlers.getRegisteredListeners(); +- + for (RegisteredListener registration : listeners) { + if (!registration.getPlugin().isEnabled()) { + continue; diff --git a/luminol-server/paper-patches/features/0033-FoliaPR-Add-TPS-From-Region.patch b/luminol-server/paper-patches/features/0033-FoliaPR-Add-TPS-From-Region.patch new file mode 100644 index 0000000..bd3908d --- /dev/null +++ b/luminol-server/paper-patches/features/0033-FoliaPR-Add-TPS-From-Region.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrHua269 +Date: Sun, 12 Jan 2025 15:38:13 +0800 +Subject: [PATCH] FoliaPR Add TPS From Region + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index cf4740f436fbcff73604ec7459001f2de15a45fe..dc8d811c1ae01f5382612ad00b917e2b2ad2b460 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -3123,6 +3123,42 @@ public final class CraftServer implements Server { + }; + } + ++ // Folia start ++ @Override ++ public double[] getTPS(org.bukkit.Location location) { ++ final int x = location.blockX() >> 4; ++ final int z = location.blockZ() >> 4; ++ final ServerLevel world = ((CraftWorld) location.getWorld()).getHandle(); ++ return getTPSFromRegion(world, x, z); ++ } ++ ++ @Override ++ public double[] getTPS(org.bukkit.Chunk chunk) { ++ final int x = chunk.getX(); ++ final int z = chunk.getZ(); ++ final ServerLevel world = ((CraftWorld) chunk.getWorld()).getHandle(); ++ return getTPSFromRegion(world, x, z); ++ } ++ ++ private double[] getTPSFromRegion(ServerLevel world, int x, int z) { ++ io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion ++ region = world.regioniser.getRegionAtSynchronised(x, z); ++ if (region == null) { ++ return null; ++ } else { ++ io.papermc.paper.threadedregions.TickRegions.TickRegionData regionData = region.getData(); ++ final long currTime = System.nanoTime(); ++ return new double[] { ++ regionData.getRegionSchedulingHandle().getTickReport5s(currTime).tpsData().segmentAll().average(), ++ regionData.getRegionSchedulingHandle().getTickReport15s(currTime).tpsData().segmentAll().average(), ++ regionData.getRegionSchedulingHandle().getTickReport1m(currTime).tpsData().segmentAll().average(), ++ regionData.getRegionSchedulingHandle().getTickReport5m(currTime).tpsData().segmentAll().average(), ++ regionData.getRegionSchedulingHandle().getTickReport15m(currTime).tpsData().segmentAll().average(), ++ }; ++ } ++ } ++ // Folia end ++ + // Paper start - adventure sounds + @Override + public void playSound(final net.kyori.adventure.sound.Sound sound) {