131 lines
6.3 KiB
Diff
131 lines
6.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Bacteriawa <A3167717663@hotmail.com>
|
|
Date: Tue, 21 Apr 2026 02:27:38 +0800
|
|
Subject: [PATCH] Add Portal rate limiter
|
|
|
|
|
|
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
|
index 981458f6697a79dbc9fc8cf41c088c98e556c6dd..4dbbe03d949811bf6140a35faa5e8cee8f7e28f0 100644
|
|
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
|
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
|
@@ -154,6 +154,10 @@ public final class RegionizedWorldData {
|
|
for (final ChunkHolder chunkHolder : from.chunkHoldersToBroadcast) {
|
|
into.chunkHoldersToBroadcast.add(chunkHolder);
|
|
}
|
|
+ // Luminol start - Portal rate limiter
|
|
+ into.portalRateThrottler.mergeWith(from.portalRateThrottler);
|
|
+ from.portalRateThrottler.destroy();
|
|
+ // Luminol end
|
|
}
|
|
|
|
@Override
|
|
@@ -316,6 +320,12 @@ public final class RegionizedWorldData {
|
|
into.chunkHoldersToBroadcast.add(chunkHolder);
|
|
}
|
|
}
|
|
+ // Luminol start - Portal rate limiter
|
|
+ for (var worldData : dataSet) {
|
|
+ from.portalRateThrottler.splitInto(worldData.portalRateThrottler);
|
|
+ }
|
|
+ from.portalRateThrottler.destroy();
|
|
+ // Luminol end
|
|
}
|
|
};
|
|
|
|
@@ -338,6 +348,35 @@ public final class RegionizedWorldData {
|
|
return this.isHandlingTick;
|
|
}
|
|
|
|
+ // Luminol start - Portal rate limiter
|
|
+ public final me.earthme.luminol.utils.RateThrottler portalRateThrottler = new me.earthme.luminol.utils.RateThrottler();
|
|
+ public final net.objecthunter.exp4j.Expression portalRateCapExpression = me.earthme.luminol.config.modules.function.PortalRateLimiterConfig.getExpressionIfConfigured();
|
|
+
|
|
+ private int computePortalRateCap() {
|
|
+ // expression mode is disabled
|
|
+ if (this.portalRateCapExpression == null) {
|
|
+ return me.earthme.luminol.config.modules.function.PortalRateLimiterConfig.maxPortalTeleportsPerTick;
|
|
+ }
|
|
+
|
|
+ final int tickingEntityCount = this.entityTickList.size();
|
|
+ final int tickingChunkCount = this.tickingChunks.size();
|
|
+ final int playerCount = this.localPlayers.size();
|
|
+
|
|
+ return me.earthme.luminol.config.modules.function.PortalRateLimiterConfig.computeExpression(
|
|
+ this.portalRateCapExpression,
|
|
+ tickingEntityCount,
|
|
+ tickingChunkCount,
|
|
+ playerCount
|
|
+ );
|
|
+ }
|
|
+ public boolean isPortalTeleportationOutOfRate() {
|
|
+ if (!me.earthme.luminol.config.modules.function.PortalRateLimiterConfig.enabled) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return this.portalRateThrottler.isOutOfRate(this.computePortalRateCap());
|
|
+ }
|
|
+ // Luminol end
|
|
// entities
|
|
// this is copy on write to allow packet processing to iterate safely
|
|
private final CopyOnWriteArrayList<ServerPlayer> localPlayers = new CopyOnWriteArrayList<>();
|
|
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
|
index ff6809944c2dd8a2cc7c11a8b05b0f7c17b5fb4c..fe1b70edb24e2ded42f8ca1f5ddfbae7151b147a 100644
|
|
--- a/net/minecraft/server/MinecraftServer.java
|
|
+++ b/net/minecraft/server/MinecraftServer.java
|
|
@@ -1978,6 +1978,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
//net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = level.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers // Folia - region threading
|
|
profiler.push(() -> level + " " + level.dimension().identifier());
|
|
profiler.push("tick");
|
|
+ // Luminol start - Portal rate limiter
|
|
+ regionizedWorldData.portalRateThrottler.begin();
|
|
+ // Luminol end
|
|
|
|
try {
|
|
foliaProfiler.startTimer(level.tickTimerId); try { // Folia - profiler
|
|
@@ -1992,6 +1995,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
profiler.pop();
|
|
profiler.pop();
|
|
regionizedWorldData.explosionDensityCache.clear(); // Paper - Optimize explosions // Folia - region threading
|
|
+ // Luminol start - Portal rate limiter
|
|
+ regionizedWorldData.portalRateThrottler.done();
|
|
+ // Luminol end
|
|
}
|
|
//this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked // Folia - region threading
|
|
|
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
|
index 015f0521aa65201fab990177867d10e0ea0611d4..adde187ad84ad75047096736de6e51ef81897d61 100644
|
|
--- a/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
|
@@ -1536,8 +1536,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
|
// removed from region while ticking
|
|
return;
|
|
}
|
|
+ // Luminol start - Portal rate limiter
|
|
+ var worldData = entity.level().getCurrentWorldData();
|
|
+ if (entity.portalProcess != null && worldData.isPortalTeleportationOutOfRate()) {
|
|
+ return;
|
|
+ }
|
|
+ // Luminol end
|
|
if (entity.handlePortal()) {
|
|
// portalled
|
|
+ worldData.portalRateThrottler.increase(); // Luminol - Portal rate limiter
|
|
return;
|
|
}
|
|
}
|
|
@@ -1584,8 +1591,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
|
// removed from region while ticking
|
|
return;
|
|
}
|
|
+ // Luminol start - Portal rate limiter
|
|
+ var worldData = entity.level().getCurrentWorldData();
|
|
+ if (entity.portalProcess != null && worldData.isPortalTeleportationOutOfRate()) {
|
|
+ return;
|
|
+ }
|
|
+ // Luminol end
|
|
if (entity.handlePortal()) {
|
|
// portalled
|
|
+ worldData.portalRateThrottler.increase(); // Luminol - Portal rate limiter
|
|
return;
|
|
}
|
|
// Folia end - region threading
|