Compare commits

..

15 Commits

Author SHA1 Message Date
M2ke4U
9080749e08 Fix wrong value check again* 2023-12-14 10:31:39 +08:00
M2ke4U
66166c485c Merge remote-tracking branch 'origin/ver/1.20.2' into ver/1.20.2 2023-12-14 10:22:34 +08:00
M2ke4U
d8d3e9b85b Corrected wrong math.min calling in tpsbar 2023-12-14 10:21:35 +08:00
M2ke4U
acd8e7916c Correct wrong jar name 2023-12-11 20:34:31 +08:00
M2ke4U
140ccf5e74 Fix async mob spawning issue 2023-12-11 20:19:30 +08:00
M2ke4U
625f9a11cd Added back worldborder command 2023-12-11 20:03:34 +08:00
M2ke4U
2458672f0b Use cached thread pool to process mob spawning tasks to fix some issue 2023-12-10 22:00:09 +08:00
M2ke4U
431aaa9094 Optimize mob spawning(Async mob spawn state calc) 2023-12-09 22:24:02 +08:00
M2ke4U
fc74aa3e91 Corrected permission check in tpsbar commande 2023-12-09 20:02:41 +08:00
M2ke4U
dc6d7e9ca4 Complete tpsbar 2023-12-07 20:25:50 +08:00
M2ke4U
ea1df79c5d Added async pathfinding from kaiiju 2023-12-07 20:08:57 +08:00
M2ke4U
6f659aec21 Revert "Remove fluid direction optimization"
This reverts commit 5e5c48dab1.
2023-12-05 20:15:43 +08:00
M2ke4U
5e5c48dab1 Remove fluid direction optimization 2023-12-04 20:30:23 +08:00
M2ke4U
1b8acda958 Add config for root user warning 2023-11-30 22:42:49 +08:00
M2ke4U
bad67403c4 Fix and optimize tpsbar 2023-11-29 22:55:42 +08:00
6 changed files with 1915 additions and 22 deletions

View File

@@ -51,13 +51,13 @@ jobs:
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
./gradlew publish
- name: Rename jar file
run: mv build/libs/Luminol-paperclip-1.20.2-R0.1-SNAPSHOT-reobf.jar build/libs/lunminol-1.20.2-paperclip.jar
run: mv build/libs/Luminol-paperclip-1.20.2-R0.1-SNAPSHOT-reobf.jar build/libs/luminol-1.20.2-paperclip.jar
- name: Release Artifacts
uses: svenstaro/upload-release-action@v2
with:
release_name: "Luminol MC1.20.2 - ${{ github.event.repository.updated_at}}"
tag: "1.20.2-${{ github.run_id }}"
repo_token: "${{ secrets.GITHUB_TOKEN }}"
file: "build/libs/lunminol-1.20.2-paperclip.jar"
file: "build/libs/luminol-1.20.2-paperclip.jar"
file_glob: true
prerelease: false

View File

@@ -63,7 +63,7 @@ index 90a6cfd011aaefe66fda79f887380ab2d62a07b1..0657fce8aabb956a400b3cead53c28ef
enableSandDuping = get("fixes.enable_sand_duping",enableSandDuping,"If this enabled,The value of safe teleportation will always be false and sand duping will be enabled");
diff --git a/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java b/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f74f748501d2f915869e9077dd2f2206075346b
index 0000000000000000000000000000000000000000..ac8f0e3bf130ba6dfd7202e2f480352218154cdc
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java
@@ -0,0 +1,40 @@
@@ -79,7 +79,7 @@ index 0000000000000000000000000000000000000000..3f74f748501d2f915869e9077dd2f220
+public class TpsBarCommand extends Command {
+ public TpsBarCommand(@NotNull String name) {
+ super(name);
+ this.setPermission("molia.commands.tpsbar");
+ this.setPermission("luminol.commands.tpsbar");
+ this.setDescription("Show the tps and mspt through a bossbar");
+ this.setUsage("/tpsbar");
+ }
@@ -109,10 +109,10 @@ index 0000000000000000000000000000000000000000..3f74f748501d2f915869e9077dd2f220
+}
diff --git a/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..98505b8ba09b93534eaa1b400d0c244ecb66e0ea
index 0000000000000000000000000000000000000000..baec715e0c20e920ccb99f2f07d84fcb6f2b434e
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
@@ -0,0 +1,206 @@
@@ -0,0 +1,204 @@
+package me.earthme.luminol.functions;
+
+import com.google.common.collect.Lists;
@@ -139,7 +139,6 @@ index 0000000000000000000000000000000000000000..98505b8ba09b93534eaa1b400d0c244e
+public class GlobalServerTpsBar {
+ protected static final MinecraftInternalPlugin NULL_PLUGIN = new MinecraftInternalPlugin();
+ protected static final Map<UUID,BossBar> uuid2Bossbars = new HashMap<>();
+ protected static final List<UUID> visibleExclude = Lists.newCopyOnWriteArrayList();
+ protected static volatile ScheduledTask tpsbarTask = null;
+
+ public static void init(){
@@ -162,16 +161,11 @@ index 0000000000000000000000000000000000000000..98505b8ba09b93534eaa1b400d0c244e
+ }
+
+ public static boolean isPlayerVisible(Player player){
+ return !visibleExclude.contains(player.getUniqueId());
+ return ((CraftPlayer) player).getHandle().isTpsBarVisible;
+ }
+
+ public static void setVisibilityForPlayer(Player target,boolean canSee){
+ if (!canSee){
+ visibleExclude.add(target.getUniqueId());
+ return;
+ }
+
+ visibleExclude.remove(target.getUniqueId());
+ ((CraftPlayer) target).getHandle().isTpsBarVisible = canSee;
+ }
+
+ private static void update(){
@@ -186,11 +180,9 @@ index 0000000000000000000000000000000000000000..98505b8ba09b93534eaa1b400d0c244e
+ final UUID uuid = bossBarEntry.getKey();
+ boolean shouldRemove = true;
+
+ for (Player player : Bukkit.getOnlinePlayers()){
+ if (player.getUniqueId() == uuid){
+ shouldRemove = !isPlayerVisible(player);
+ break;
+ }
+ final Player target = Bukkit.getPlayer(uuid);
+ if (target != null){
+ shouldRemove = !isPlayerVisible(target);
+ }
+
+ if (shouldRemove){
@@ -199,7 +191,13 @@ index 0000000000000000000000000000000000000000..98505b8ba09b93534eaa1b400d0c244e
+ }
+
+ for (UUID uuid : toRemove){
+ uuid2Bossbars.remove(uuid);
+ final BossBar removed = uuid2Bossbars.remove(uuid);
+ if (removed != null){
+ final Player targetPlayer = Bukkit.getPlayer(uuid);
+ if (targetPlayer != null){
+ targetPlayer.hideBossBar(removed);
+ }
+ }
+ }
+ }
+
@@ -216,7 +214,7 @@ index 0000000000000000000000000000000000000000..98505b8ba09b93534eaa1b400d0c244e
+
+ BossBar targetBossbar = uuid2Bossbars.get(nmsPlayer.getUUID());
+
+ if (targetBossbar == null && !visibleExclude.contains(nmsPlayer.getUUID()) && isPlayerVisible(apiPlayer)){
+ if (targetBossbar == null && isPlayerVisible(apiPlayer)){
+ targetBossbar = BossBar.bossBar(Component.text(""),0.0F, BossBar.Color.valueOf(LuminolConfig.tpsColors[3]), BossBar.Overlay.NOTCHED_20);
+ uuid2Bossbars.put(nmsPlayer.getUUID(),targetBossbar);
+ apiPlayer.showBossBar(targetBossbar);
@@ -238,7 +236,7 @@ index 0000000000000000000000000000000000000000..98505b8ba09b93534eaa1b400d0c244e
+ Placeholder.component("ping",getPingComponent(player.getPing()))
+ ));
+ bar.color(barColorFromTps(tps));
+ bar.progress((float) Math.min(mspt / 50,1.0));
+ bar.progress((float) Math.max(mspt / 50,0));
+ }
+
+ private static @NotNull Component getPingComponent(int ping){
@@ -354,3 +352,41 @@ index f0bf57a7acd77eeffbeeb6743ba58166823022fd..4a1e068c27853a38db0641806626e7ac
super.stopServer();
//Util.shutdownExecutors(); // Paper - moved into super
SkullBlockEntity.clear();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 97bfb92e52c3c5ef1cd22afe2b97c204eb45025a..d7a280427442bac8cc8ccb542d24d4e0901df70a 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -278,6 +278,7 @@ public class ServerPlayer extends Player {
// Paper start - replace player chunk loader
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
+ public volatile boolean isTpsBarVisible = false;
public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances getViewDistances() {
return this.viewDistances.get();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 6c8f6e26687b557fcdcd65c657d8b35d3fde805e..06c92a2d3ecb3b747c2303819f72c1c41967af8c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2216,6 +2216,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
handle.expToDrop = data.getInt("expToDrop");
handle.keepLevel = data.getBoolean("keepLevel");
}
+
+ //Luminol start - Tpsbar
+ getHandle().isTpsBarVisible = data.getBoolean("tpsbarVisible");
+ //Luminol end
}
}
@@ -2237,6 +2241,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
data.putLong("lastPlayed", System.currentTimeMillis());
data.putString("lastKnownName", handle.getScoreboardName());
+ //Luminol start - Tpsbar
+ data.putBoolean("tpsbarVisible",handle.isTpsBarVisible);
+ //Luminol end
+
// Paper start - persist for use in offline save data
if (!nbttagcompound.contains("Paper")) {
nbttagcompound.put("Paper", new CompoundTag());

View File

@@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Thu, 30 Nov 2023 22:41:04 +0800
Subject: [PATCH] Add config for root user warning
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 8bf7a0235ed292d6cb3beca9b786a69148e0b4d9..7ada58f2fa83a47908723bdf1e5c5fbbc2f5ffa9 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -33,6 +33,7 @@ public class LuminolConfig {
public static boolean disableUsernameCheck = false;
public static boolean disableOfflineModeWarning = false;
public static boolean fixSpectorTeleportFolia = false;
+ public static boolean disableRootUserWarning = false;
public static boolean safeTeleportation = true;
public static boolean enableSandDuping = false;
@@ -134,6 +135,7 @@ public class LuminolConfig {
disableUsernameCheck = get("misc.disable_username_check",disableUsernameCheck,"Disable username check that can accept usernames with other characters(such as Chinese).Not recommended to use");
fixSpectorTeleportFolia = get("misc.fix_folia_spector_teleport",fixSpectorTeleportFolia);
disableOfflineModeWarning = get("misc.disable_offline_mode_warning",disableOfflineModeWarning);
+ disableRootUserWarning = get("misc.disable_root_user_warning",disableRootUserWarning);
if (tpsbarEnabled){
initTpsbar();
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 4cc62104942e58ededd5c838f4bd5c4db0d574d4..964777e992974dc02ee106ec47efd2e04f3b76c3 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -178,7 +178,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
}
// Paper start - detect running as root
- if (io.papermc.paper.util.ServerEnvironment.userIsRootOrAdmin()) {
+ if (io.papermc.paper.util.ServerEnvironment.userIsRootOrAdmin() && !LuminolConfig.disableRootUserWarning) { //Luminol - Add config for root user warning
DedicatedServer.LOGGER.warn("****************************");
DedicatedServer.LOGGER.warn("YOU ARE RUNNING THIS SERVER AS AN ADMINISTRATIVE OR ROOT USER. THIS IS NOT ADVISED.");
DedicatedServer.LOGGER.warn("YOU ARE OPENING YOURSELF UP TO POTENTIAL RISKS WHEN DOING THIS.");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,483 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sat, 9 Dec 2023 22:19:49 +0800
Subject: [PATCH] Optimize mob spawning(Async mob spawn state calc)
diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
index 41b9405d6759d865e0d14dd4f95163e9690e967d..091b1ae822e1c0517e59572e7a9bda11e998c0ee 100644
--- a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
+++ b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
@@ -26,7 +26,7 @@ public abstract class AreaMap<E> {
// we use linked for better iteration.
// map of: coordinate to set of objects in coordinate
- protected final Long2ObjectOpenHashMap<PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<E>> areaMap = new Long2ObjectOpenHashMap<>(1024, 0.7f);
+ protected Long2ObjectOpenHashMap<PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<E>> areaMap = new Long2ObjectOpenHashMap<>(1024, 0.7f); // Pufferfish - not actually final
protected final PooledLinkedHashSets<E> pooledHashSets;
protected final ChangeCallback<E> addCallback;
@@ -160,7 +160,8 @@ public abstract class AreaMap<E> {
protected abstract PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<E> getEmptySetFor(final E object);
// expensive op, only for debug
- protected void validate(final E object, final int viewDistance) {
+ protected void validate0(final E object, final int viewDistance) { // Pufferfish - rename this thing just in case it gets used I'd rather a compile time error.
+ if (true) throw new UnsupportedOperationException(); // Pufferfish - not going to put in the effort to fix this if it doesn't ever get used.
int entiesGot = 0;
int expectedEntries = (2 * viewDistance + 1);
expectedEntries *= expectedEntries;
diff --git a/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java
index 46954db7ecd35ac4018fdf476df7c8020d7ce6c8..1ad890a244bdf6df48a8db68cb43450e08c788a6 100644
--- a/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java
+++ b/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java
@@ -5,7 +5,7 @@ import net.minecraft.server.level.ServerPlayer;
/**
* @author Spottedleaf
*/
-public final class PlayerAreaMap extends AreaMap<ServerPlayer> {
+public class PlayerAreaMap extends AreaMap<ServerPlayer> { // Pufferfish - not actually final
public PlayerAreaMap() {
super();
diff --git a/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java b/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..fdcb62d12164024a5f354d60cc863821a18d1b2a
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java
@@ -0,0 +1,31 @@
+package gg.pufferfish.pufferfish.util;
+
+import com.destroystokyo.paper.util.misc.PlayerAreaMap;
+import com.destroystokyo.paper.util.misc.PooledLinkedHashSets;
+import java.util.concurrent.ConcurrentHashMap;
+import net.minecraft.server.level.ServerPlayer;
+
+public final class AsyncPlayerAreaMap extends PlayerAreaMap {
+
+ public AsyncPlayerAreaMap() {
+ super();
+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f));
+ }
+
+ public AsyncPlayerAreaMap(final PooledLinkedHashSets<ServerPlayer> pooledHashSets) {
+ super(pooledHashSets);
+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f));
+ }
+
+ public AsyncPlayerAreaMap(final PooledLinkedHashSets<ServerPlayer> pooledHashSets, final ChangeCallback<ServerPlayer> addCallback,
+ final ChangeCallback<ServerPlayer> removeCallback) {
+ this(pooledHashSets, addCallback, removeCallback, null);
+ }
+
+ public AsyncPlayerAreaMap(final PooledLinkedHashSets<ServerPlayer> pooledHashSets, final ChangeCallback<ServerPlayer> addCallback,
+ final ChangeCallback<ServerPlayer> removeCallback, final ChangeSourceCallback<ServerPlayer> changeSourceCallback) {
+ super(pooledHashSets, addCallback, removeCallback, changeSourceCallback);
+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f));
+ }
+
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java b/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..facd55463d44cb7e3d2ca6892982f5497b8dded1
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java
@@ -0,0 +1,40 @@
+package gg.pufferfish.pufferfish.util;
+
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
+import java.util.Map;
+import org.jetbrains.annotations.Nullable;
+
+public class Long2ObjectOpenHashMapWrapper<V> extends Long2ObjectOpenHashMap<V> {
+
+ private final Map<Long, V> backingMap;
+
+ public Long2ObjectOpenHashMapWrapper(Map<Long, V> map) {
+ backingMap = map;
+ }
+
+ @Override
+ public V put(Long key, V value) {
+ return backingMap.put(key, value);
+ }
+
+ @Override
+ public V get(Object key) {
+ return backingMap.get(key);
+ }
+
+ @Override
+ public V remove(Object key) {
+ return backingMap.remove(key);
+ }
+
+ @Nullable
+ @Override
+ public V putIfAbsent(Long key, V value) {
+ return backingMap.putIfAbsent(key, value);
+ }
+
+ @Override
+ public int size() {
+ return backingMap.size();
+ }
+}
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
index 7ca275826609bcf96f103a8c50beaa47c3b4068b..dc5399bd5dba9dd33a7cfd644327c2568a6ad051 100644
--- a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
@@ -4,6 +4,7 @@ import com.destroystokyo.paper.util.maplist.ReferenceList;
import com.destroystokyo.paper.util.misc.PlayerAreaMap;
import com.destroystokyo.paper.util.misc.PooledLinkedHashSets;
import com.mojang.logging.LogUtils;
+import gg.pufferfish.pufferfish.util.AsyncPlayerAreaMap;
import io.papermc.paper.chunk.system.scheduling.ChunkHolderManager;
import io.papermc.paper.util.CoordinateUtils;
import io.papermc.paper.util.TickThread;
@@ -14,6 +15,7 @@ import it.unimi.dsi.fastutil.longs.Long2ReferenceMap;
import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.CrashReport;
import net.minecraft.ReportedException;
import net.minecraft.core.BlockPos;
@@ -58,6 +60,10 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -145,6 +151,10 @@ public final class RegionizedWorldData {
into.wanderingTraderSpawnDelay = Math.max(from.wanderingTraderSpawnDelay, into.wanderingTraderSpawnDelay);
into.wanderingTraderSpawnChance = Math.max(from.wanderingTraderSpawnChance, into.wanderingTraderSpawnChance);
}
+
+ //Luminol start - Async mob spawning
+ from.lastAsyncSpawnStateTask = null; //Discard the task currently processing
+ //Luminol end
}
@Override
@@ -302,6 +312,10 @@ public final class RegionizedWorldData {
regionizedWorldData.wanderingTraderSpawnDelay = from.wanderingTraderSpawnDelay;
regionizedWorldData.villageSiegeState = new VillageSiegeState(); // just re set it, as the spawn pos will be invalid
}
+
+ //Luminol start - Async mob spawning
+ from.lastAsyncSpawnStateTask = null; //Reset the task
+ //Luminol end
}
};
@@ -398,6 +412,22 @@ public final class RegionizedWorldData {
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos;
public final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap();
+ //Luminol start - Asnc mob spawning
+ public volatile CompletableFuture<NaturalSpawner.SpawnState> lastAsyncSpawnStateTask = null;
+ public static ThreadPoolExecutor ASYNC_MOB_SPAWNING_EXECUTOR;
+ public static void initMobSpawningExecutor(){
+ if (LuminolConfig.enableAsyncMobSpawning){
+ ASYNC_MOB_SPAWNING_EXECUTOR = new ThreadPoolExecutor(
+ 1,
+ Integer.MAX_VALUE,
+ 1,
+ TimeUnit.MINUTES,
+ new LinkedBlockingQueue<>()
+ );
+ }
+ }
+ //Luminol end
+
public static final class TempCollisionList<T> {
final UnsafeList<T> list = new UnsafeList<>(64);
boolean inUse;
@@ -430,7 +460,7 @@ public final class RegionizedWorldData {
// Mob spawning
private final PooledLinkedHashSets<ServerPlayer> pooledHashSets = new PooledLinkedHashSets<>();
- public final PlayerAreaMap mobSpawnMap = new PlayerAreaMap(this.pooledHashSets);
+ public final PlayerAreaMap mobSpawnMap = new AsyncPlayerAreaMap(this.pooledHashSets); //Luminol - Async mob spawning
public int catSpawnerNextTick = 0;
public int patrolSpawnerNextTick = 0;
public int phantomSpawnerNextTick = 0;
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index e8cd180bab5c196db09ded74aea676b4412fc6e9..534f54be1495b1a8f754bec0eb1aba8306c1d902 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -2,6 +2,7 @@ package me.earthme.luminol;
import dev.kaiijumc.kaiiju.region.RegionFileFormat;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import io.papermc.paper.threadedregions.RegionizedWorldData;
import me.earthme.luminol.commands.TpsBarCommand;
import me.earthme.luminol.functions.GlobalServerTpsBar;
import net.minecraft.core.registries.BuiltInRegistries;
@@ -62,6 +63,7 @@ public class LuminolConfig {
public static boolean asyncPathProcessing = false;
public static int asyncPathProcessingMaxThreads = 0;
public static int asyncPathProcessingKeepalive = 60;
+ public static boolean enableAsyncMobSpawning = false;
public static void init() throws IOException {
PARENT_FOLDER.mkdir();
@@ -188,6 +190,8 @@ public class LuminolConfig {
asyncPathProcessingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1);
if (!asyncPathProcessing)
asyncPathProcessingMaxThreads = 0;
+ enableAsyncMobSpawning = get("optimizations.enable_async_mob_spawning",enableAsyncMobSpawning);
+ RegionizedWorldData.initMobSpawningExecutor();
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/me/earthme/luminol/utils/AsyncMobSpawnExecutor.java b/src/main/java/me/earthme/luminol/utils/AsyncMobSpawnExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..88d5b188ccfb17fe1ae4b08f32565f27569cad5c
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/utils/AsyncMobSpawnExecutor.java
@@ -0,0 +1,71 @@
+package me.earthme.luminol.utils;
+
+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue;
+import net.minecraft.server.MinecraftServer;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.LockSupport;
+
+public class AsyncMobSpawnExecutor implements Runnable, Executor {
+ private final MultiThreadedQueue<Runnable> allTasks = new MultiThreadedQueue<>();
+ private final Thread worker = new Thread(this);
+ private AtomicBoolean shouldRunNext = new AtomicBoolean(true);
+ private AtomicBoolean isRunning = new AtomicBoolean(false);
+ private AtomicBoolean isIdle = new AtomicBoolean(false);
+
+ public boolean isRunning(){
+ return this.isRunning.get();
+ }
+
+ public void startExecutor(){
+ this.worker.setDaemon(true);
+ this.worker.setContextClassLoader(MinecraftServer.class.getClassLoader());
+ this.worker.start();
+ }
+
+ public void forceTerminate(){
+ this.shouldRunNext.set(false);
+ if (this.isRunning.get()){
+ this.allTasks.clear();
+ LockSupport.unpark(this.worker);
+ }
+ }
+
+ public void dropAllTasks(){
+ this.allTasks.clear();
+ }
+
+ @Override
+ public void run() {
+ this.isRunning.set(true);
+ try {
+ while (this.shouldRunNext.get()){
+ final Runnable task = this.allTasks.poll();
+ if (task != null){
+ this.isIdle.set(false);
+
+ try {
+ task.run();
+ }catch (Exception e){
+ e.printStackTrace(); //TODO - Exception processing?
+ }
+
+ continue;
+ }
+
+ this.isIdle.set(true);
+ LockSupport.park();
+ }
+ }finally {
+ this.isRunning.set(false);
+ }
+ }
+
+ @Override
+ public void execute(@NotNull Runnable command) {
+ this.allTasks.offer(command);
+ LockSupport.unpark(this.worker); //Notify
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index b9b1dfe04eda8498f0ceff0aee66489d2a02b814..c470eafef884075b6e4d170adc2ced96a4beb517 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -11,13 +11,15 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
-import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javax.annotation.Nullable;
+
+import io.papermc.paper.threadedregions.RegionizedWorldData;
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
@@ -487,32 +489,38 @@ public class ServerChunkCache extends ChunkSource {
this.level.timings.countNaturalMobs.startTiming(); // Paper - timings
int l = this.distanceManager.getNaturalSpawnChunkCount();
// Paper start - per player mob spawning
- NaturalSpawner.SpawnState spawnercreature_d; // moved down
+ NaturalSpawner.SpawnState spawnercreature_d = null; // moved down
profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); try { // Folia - profiler
- if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
- // re-set mob counts
- for (ServerPlayer player : regionizedWorldData.getLocalPlayers()) { // Folia - region threading
- // Paper start - per player mob spawning backoff
- for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) {
- player.mobCounts[ii] = 0;
-
- int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm?
- if (newBackoff < 0) {
- newBackoff = 0;
+ if (!LuminolConfig.enableAsyncMobSpawning){ //Luminol
+ if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
+ // re-set mob counts
+ for (ServerPlayer player : regionizedWorldData.getLocalPlayers()) { // Folia - region threading
+ // Paper start - per player mob spawning backoff
+ for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) {
+ player.mobCounts[ii] = 0;
+
+ int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm?
+ if (newBackoff < 0) {
+ newBackoff = 0;
+ }
+ player.mobBackoffCounts[ii] = newBackoff;
}
- player.mobBackoffCounts[ii] = newBackoff;
+ // Paper end - per player mob spawning backoff
}
- // Paper end - per player mob spawning backoff
+ spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true); // Folia - region threading
+ } else {
+ spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading
}
- spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true); // Folia - region threading
- } else {
- spawnercreature_d = NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading
+ }//Luminol
+ //Luminol start - Async mob spawning
+ if (!LuminolConfig.enableAsyncMobSpawning){
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.completedFuture(spawnercreature_d);
}
} finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); } // Folia - profiler
// Paper end
this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings
- regionizedWorldData.lastSpawnState = spawnercreature_d; // Folia - region threading
+ //regionizedWorldData.lastSpawnState = spawnercreature_d; // Folia - region threading //Luminol - Async mob spawning
gameprofilerfiller.popPush("filteringLoadedChunks");
// Paper - optimise chunk tick iteration
// Paper - optimise chunk tick iteration
@@ -610,7 +618,12 @@ public class ServerChunkCache extends ChunkSource {
chunk1.incrementInhabitedTime(j);
if (spawn && flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration
++spawnChunkCount; // Folia - profiler
- NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1);
+
+ //Luminol start - Async mob spawning
+ if (regionizedWorldData.lastAsyncSpawnStateTask != null && regionizedWorldData.lastAsyncSpawnStateTask.isDone()){
+ NaturalSpawner.spawnForChunk(this.level, chunk1, regionizedWorldData.lastAsyncSpawnStateTask.join(), this.spawnFriendlies, this.spawnEnemies, flag1);
+ }
+ //Luminol end
}
if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration
@@ -667,6 +680,36 @@ public class ServerChunkCache extends ChunkSource {
gameprofilerfiller.pop();
gameprofilerfiller.pop();
this.chunkMap.tick();
+
+ //Luminol start - Async mob spawning
+ if (LuminolConfig.enableAsyncMobSpawning){
+ //Luminol - Copied down
+ if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
+ // re-set mob counts
+ for (ServerPlayer player : regionizedWorldData.getLocalPlayers()) { // Folia - region threading
+ // Paper start - per player mob spawning backoff
+ for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) {
+ player.mobCounts[ii] = 0;
+
+ int newBackoff = player.mobBackoffCounts[ii] - 1; // TODO make configurable bleed // TODO use nonlinear algorithm?
+ if (newBackoff < 0) {
+ newBackoff = 0;
+ }
+ player.mobBackoffCounts[ii] = newBackoff;
+ }
+ // Paper end - per player mob spawning backoff
+ }
+
+ if (regionizedWorldData.lastAsyncSpawnStateTask == null || regionizedWorldData.lastAsyncSpawnStateTask.isDone()){
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.supplyAsync(() -> NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true),RegionizedWorldData.ASYNC_MOB_SPAWNING_EXECUTOR);
+ }
+ } else {
+ if (regionizedWorldData.lastAsyncSpawnStateTask == null || regionizedWorldData.lastAsyncSpawnStateTask.isDone()){
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.supplyAsync(() -> NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false), RegionizedWorldData.ASYNC_MOB_SPAWNING_EXECUTOR);
+ }
+ }
+ }
+ //Luminol end
}
}
@@ -809,7 +852,7 @@ public class ServerChunkCache extends ChunkSource {
@VisibleForDebug
public NaturalSpawner.SpawnState getLastSpawnState() {
io.papermc.paper.threadedregions.RegionizedWorldData worldData = this.level.getCurrentWorldData(); // Folia - region threading
- return worldData == null ? null : worldData.lastSpawnState; // Folia - region threading
+ return worldData.lastAsyncSpawnStateTask != null && worldData.lastAsyncSpawnStateTask.isDone() ? worldData.lastAsyncSpawnStateTask.join() : null; // Folia - region threading //Luminol - Async mob spawning
}
public void removeTicketsOnClosing() {
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index 5caca2a34849189ea42d2699f6d8672e0d7251cb..b21243d494fd1989e7d6c2b98b08e090dc2f38b7 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -1,6 +1,9 @@
package net.minecraft.world.level;
+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
import com.mojang.logging.LogUtils;
+import io.papermc.paper.threadedregions.RegionizedServer;
+import io.papermc.paper.util.TickThread;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
@@ -117,6 +120,15 @@ public final class NaturalSpawner {
object2intopenhashmap.addTo(enumcreaturetype, 1);
// Paper start
if (countMobs) {
+ //Luminol start - Async mob spawning
+ if (!TickThread.isTickThread()){
+ RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(chunk.level,chunk.locX,chunk.locZ,()->{
+ chunk.level.getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
+ });
+ return;
+ }
+ //Luminol end
+
chunk.level.getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
}
// Paper end

View File

@@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Mon, 11 Dec 2023 20:00:10 +0800
Subject: [PATCH] Added back worldborder command
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 3435bdeaf723c64103f7c924ea42a4ec78f2ba01..a7732effbb2885b398d18df2e581f7a0f279a85a 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -202,7 +202,7 @@ public class Commands {
TitleCommand.register(this.dispatcher);
//TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later
WeatherCommand.register(this.dispatcher);
- //WorldBorderCommand.register(this.dispatcher); // Folia - region threading - TODO later
+ WorldBorderCommand.register(this.dispatcher); // Folia - region threading - TODO later //Lumino - Add back world border
if (JvmProfiler.INSTANCE.isAvailable()) {
JfrCommand.register(this.dispatcher);
}