Compare commits

..

10 Commits

Author SHA1 Message Date
Helvetica Volubi
d985455525 fix: introduced two patches from leaves to fix some bugs
update [Fix Incorrect Collision Behavior for Block Shape] to [Configurable collision behavior]

fix chunk reload detector
2025-06-04 13:16:00 +08:00
Helvetica Volubi
4ea7b2833b feat: add config query, set and reset support 2025-06-03 23:42:29 +08:00
Helvetica Volubi
7bc857b294 feat(pre): add config query and set function basic dependencies
refactor: update nightcore-config and move up config @interfaces
2025-06-03 01:19:54 +08:00
MrHua269
e963af5628 Removed useless patch
End gateway searching is already fixed in sync teleportation patch now
2025-05-31 18:16:54 +08:00
MrHua269
b74abd342b Fix mispatched entity custom spawning logic
we should use local players as each tickregion will only foreach their own player entities so that we won't come across async accessing world data
2025-05-31 16:36:36 +08:00
MrHua269
63507137a0 Ver 1.21.5 2025-05-30 20:26:15 +08:00
MrHua269
7b7fe5c62a Fully finish fix of chunk iteration self modification
A fix in another way of https://github.com/PaperMC/Folia/issues/363
2025-05-30 19:57:23 +08:00
Helvetica Volubi
0a00e23143 [ci skip]refactor: rename a config and edit some co-author's data 2025-05-30 00:59:42 +08:00
Helvetica Volubi
c935e6bdc8 [ci skip]docs: add a tip for long path support 2025-05-30 00:37:12 +08:00
Helvetica Volubi
31d22035f3 feat: add @TransformedConfig to auto transform config 2025-05-29 23:04:55 +08:00
91 changed files with 596 additions and 311 deletions

View File

@@ -1,10 +1,10 @@
name: Luminol CI - dev/1.21.5
name: Luminol CI - ver/1.21.5
on:
push:
branches: [ "dev/1.21.5" ]
branches: [ "ver/1.21.5" ]
pull_request:
branches: [ "dev/1.21.5" ]
branches: [ "ver/1.21.5" ]
permissions: write-all
@@ -67,6 +67,6 @@ jobs:
artifacts: |
${{ env.jar_dir }}
generateReleaseNotes: true
prerelease: true
prerelease: false
makeLatest: ${{ env.make_latest }}
token: "${{ secrets.GITHUB_TOKEN }}"

View File

@@ -23,6 +23,11 @@
- `git`
- `JDK 21 或更高版本`
特别提醒在操作前您需要启用系统和Git的长路径支持以下为部分平台的相关描述。
[`Windows`](https://learn.microsoft.com/windows/win32/fileio/maximum-file-path-limitation)
[`Git for Windows`](https://gitforwindows.org/faq.html#i-get-errors-trying-to-check-out-files-with-long-path-names)
## 了解补丁Patches
Luminol 使用和 Folia 一样的补丁系统,并为了针对不同部分的修改分成了两个目录:

View File

@@ -25,6 +25,11 @@ Before coding, you need these pieces of software / tools as Dev Environment.
- `git`
- `JDK 21 or higher`
PS: You need to enable long path support in your System and Git before start, some of the platform's resolution here.
[`Windows`](https://learn.microsoft.com/windows/win32/fileio/maximum-file-path-limitation)
[`Git for Windows`](https://gitforwindows.org/faq.html#i-get-errors-trying-to-check-out-files-with-long-path-names)
## Understanding "Patches"
Luminol uses as the same patching system as Paper,

View File

@@ -54,7 +54,7 @@
dependencies {
- implementation(project(":folia-api"))
+ implementation(project(":luminol-api")) // Luminol
+ implementation("com.electronwill.night-config:toml:3.6.6") // Luminol - Night config
+ implementation("com.electronwill.night-config:toml:3.8.2") // Luminol - Night config
+ // Abomination start
+ implementation("com.github.luben:zstd-jni:1.5.4-1")
+ implementation("org.lz4:lz4-java:1.8.0")

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Add config to modify tripwire behavior
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
index 8a3a8b0fdf9545a41501dc992c6982d9c8ce7b66..8139387c1b0814c86d770f5ef6dda952140467ea 100644
index 8a3a8b0fdf9545a41501dc992c6982d9c8ce7b66..8f9f5b0bf098a32a732e3ff9f636e3ea828e5f43 100644
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
@@ -200,10 +200,17 @@ public class TripWireHookBlock extends Block {
@@ -16,7 +16,7 @@ index 8a3a8b0fdf9545a41501dc992c6982d9c8ce7b66..8139387c1b0814c86d770f5ef6dda952
- if (blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) {
- if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates || !blockState3.is(Blocks.TRIPWIRE)) level.setBlock(blockPos1, blockState2.trySetValue(ATTACHED, flag2), 3); // Paper - prevent tripwire from updating
+ // Luminol start - tripwire and tripwireHook dupe
+ if (me.earthme.luminol.config.modules.misc.AllowTripwireDupe.enabled) {
+ if (me.earthme.luminol.config.modules.misc.TripwireBehaviorConfig.enabled) {
+ level.setBlock(blockPos1, blockState2.trySetValue(ATTACHED, flag2), 3);
+ level.getBlockState(blockPos1);
+ } else {
@@ -30,7 +30,7 @@ index 8a3a8b0fdf9545a41501dc992c6982d9c8ce7b66..8139387c1b0814c86d770f5ef6dda952
}
}
diff --git a/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java b/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java
index 49b810ae9d9a8d0718a5f8c512e15a5573ed04fd..ae48255ee384a7b4a44c8754601200d361665934 100644
index 49b810ae9d9a8d0718a5f8c512e15a5573ed04fd..37ebb23c9c053de0530254d98f2120058833f232 100644
--- a/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java
+++ b/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java
@@ -28,6 +28,11 @@ public class EndPlatformFeature extends Feature<NoneFeatureConfiguration> {
@@ -40,8 +40,8 @@ index 49b810ae9d9a8d0718a5f8c512e15a5573ed04fd..ae48255ee384a7b4a44c8754601200d3
+ // Luminol start - tripwire behavior modifier
+ java.util.List<BlockPos> blockList1 = new java.util.ArrayList<>();
+ java.util.List<BlockPos> blockList2 = new java.util.ArrayList<>();
+ boolean flag21 = !java.util.Objects.equals(me.earthme.luminol.config.modules.misc.AllowTripwireDupe.behaviorMode, "VANILLA20")
+ && !java.util.Objects.equals(me.earthme.luminol.config.modules.misc.AllowTripwireDupe.behaviorMode, "MIXED");
+ boolean flag21 = !java.util.Objects.equals(me.earthme.luminol.config.modules.misc.TripwireBehaviorConfig.behaviorMode, "VANILLA20")
+ && !java.util.Objects.equals(me.earthme.luminol.config.modules.misc.TripwireBehaviorConfig.behaviorMode, "MIXED");
for (int i = -2; i <= 2; i++) {
for (int i1 = -2; i1 <= 2; i1++) {
for (int i2 = -1; i2 < 3; i2++) {
@@ -51,8 +51,8 @@ index 49b810ae9d9a8d0718a5f8c512e15a5573ed04fd..ae48255ee384a7b4a44c8754601200d3
if (dropBlocks) {
- blockList.destroyBlock(blockPos, true, null); // CraftBukkit
+ boolean flag = false;
+ if (me.earthme.luminol.config.modules.misc.AllowTripwireDupe.enabled) {
+ switch (me.earthme.luminol.config.modules.misc.AllowTripwireDupe.behaviorMode) {
+ if (me.earthme.luminol.config.modules.misc.TripwireBehaviorConfig.enabled) {
+ switch (me.earthme.luminol.config.modules.misc.TripwireBehaviorConfig.behaviorMode) {
+ case "VANILLA20": {
+ flag = true;
+ }
@@ -82,7 +82,7 @@ index 49b810ae9d9a8d0718a5f8c512e15a5573ed04fd..ae48255ee384a7b4a44c8754601200d3
- if (dropBlocks) {
- blockList.placeBlocks(state -> level.destroyBlock(state.getPosition(), true, null));
+ if (flag21 || !me.earthme.luminol.config.modules.misc.AllowTripwireDupe.enabled) {
+ if (flag21 || !me.earthme.luminol.config.modules.misc.TripwireBehaviorConfig.enabled) {
+ if (dropBlocks) {
+ blockList.placeBlocks(state -> level.destroyBlock(state.getPosition(), true, null));
+ } else {

View File

@@ -3,9 +3,11 @@ From: MrHua269 <wangxyper@163.com>
Date: Wed, 22 Jan 2025 17:23:16 +0800
Subject: [PATCH] Gale: Optimize noise generation
Co-authored by: Martijn Muijsers <martijnmuijsers@live.nl>, ishland <ishlandmc@yeah.net>
As part of: Gale (https://github.com/GaleMC/Gale/blob/276e903b2688f23b19bdc8d493c0bf87656d2400/patches/server/0106-Optimize-noise-generation.patch) and C2ME (https://github.com/RelativityMC/C2ME-fabric)
Licensed under: MIT (https://opensource.org/licenses/MIT)
Co-authored by: Martijn Muijsers <martijnmuijsers@live.nl>
ishland <ishlandmc@yeah.net>
As part of: Gale (https://github.com/GaleMC/Gale/blob/276e903b2688f23b19bdc8d493c0bf87656d2400/patches/server/0106-Optimize-noise-generation.patch)
C2ME (https://github.com/RelativityMC/C2ME-fabric)
Licensed under: MIT (https://opensource.org/licenses/MIT)
diff --git a/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java b/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
index fb11a2eea540d55e50eab59f9857ca5d99f556f8..dcc1a3f8b611c9f103b848db90b077b984b60ada 100644

View File

@@ -3,8 +3,10 @@ From: MrHua269 <wangxyper@163.com>
Date: Wed, 22 Jan 2025 17:18:00 +0800
Subject: [PATCH] Gale: Replace AI attributes with optimized collections
Co-authored by: Martijn Muijsers <martijnmuijsers@live.nl>, 2No2Name <2No2Name@web.de>
As part of: Gale (https://github.com/GaleMC/Gale/blob/276e903b2688f23b19bdc8d493c0bf87656d2400/patches/server/0087-Replace-AI-attributes-with-optimized-collections.patch) and Lithium (https://github.com/CaffeineMC/lithium-fabric)
Co-authored by: Martijn Muijsers <martijnmuijsers@live.nl>
2No2Name <2No2Name@web.de>
As part of: Gale (https://github.com/GaleMC/Gale/blob/276e903b2688f23b19bdc8d493c0bf87656d2400/patches/server/0087-Replace-AI-attributes-with-optimized-collections.patch)
Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/net/minecraft/world/entity/ai/attributes/AttributeMap.java

View File

@@ -3,8 +3,10 @@ From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 15:35:15 +0800
Subject: [PATCH] Gale: Skip entity move if movement is zero
Co-authored by: Martijn Muijsers <martijnmuijsers@live.nl>, ishland <ishlandmc@yeah.net>
As part of: Gale (https://github.com/GaleMC/Gale/blob/276e903b2688f23b19bdc8d493c0bf87656d2400/patches/server/0103-Skip-entity-move-if-movement-is-zero.patch) and VMP (https://github.com/RelativityMC/VMP-fabric)
Co-authored by: Martijn Muijsers <martijnmuijsers@live.nl>
ishland <ishlandmc@yeah.net>
As part of: Gale (https://github.com/GaleMC/Gale/blob/276e903b2688f23b19bdc8d493c0bf87656d2400/patches/server/0103-Skip-entity-move-if-movement-is-zero.patch)
VMP (https://github.com/RelativityMC/VMP-fabric)
Licensed under: MIT (https://opensource.org/licenses/MIT)
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java

View File

@@ -3,8 +3,10 @@ From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 14:15:24 +0800
Subject: [PATCH] Gale: Use platform math functions
Co-authored by: Martijn Muijsers <martijnmuijsers@live.nl>, Xymb <xymb@endcrystal.me>
As part of: Gale (https://github.com/GaleMC/Gale/blob/276e903b2688f23b19bdc8d493c0bf87656d2400/patches/server/0019-Use-platform-math-functions.patch) and Kaiiju(https://github.com/KaiijuMC/Kaiiju)
Co-authored by: Martijn Muijsers <martijnmuijsers@live.nl>
Xymb <xymb@endcrystal.me>
As part of: Gale (https://github.com/GaleMC/Gale/blob/276e903b2688f23b19bdc8d493c0bf87656d2400/patches/server/0019-Use-platform-math-functions.patch)
Kaiiju (https://github.com/KaiijuMC/Kaiiju)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/util/Mth.java b/net/minecraft/util/Mth.java

View File

@@ -0,0 +1,55 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Wed, 4 Jun 2025 12:51:07 +0800
Subject: [PATCH] Leaves: Configurable collision behavior
Co-authored by: Fortern <blueten.ki@gmail.com>
As part of: Leaves (https://github.com/LeavesMC/Leaves/blob/c5f18b7864206cea4411211b51787f10affbcb9c/leaves-server/minecraft-patches/features/0111-Configurable-collision-behavior.patch)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
index e1bf7bc3cca63101b3c0550b5b4c0d28d0f3776e..06747460178b7cfccb393cc19d9808cebbb6ddf8 100644
--- a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
+++ b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
@@ -101,6 +101,14 @@ public final class CollisionUtil {
(box1.minZ - box2.maxZ) < -COLLISION_EPSILON && (box1.maxZ - box2.minZ) > COLLISION_EPSILON;
}
+ // Leaves start - Configurable collision behavior
+ public static boolean voxelShapeIntersectVanilla(final AABB box1, final AABB box2) {
+ return box1.minX < box2.maxX && box1.maxX > box2.minX &&
+ box1.minY < box2.maxY && box1.maxY > box2.minY &&
+ box1.minZ < box2.maxZ && box1.maxZ > box2.minZ;
+ }
+ // Leaves end - Configurable collision behavior
+
// assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON
public static double collideX(final AABB target, final AABB source, final double source_move) {
if ((source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON &&
@@ -2025,7 +2033,7 @@ public final class CollisionUtil {
AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation();
if (singleAABB != null) {
singleAABB = singleAABB.move((double)blockX, (double)blockY, (double)blockZ);
- if (!voxelShapeIntersect(aabb, singleAABB)) {
+ if (shouldSkip(aabb, blockCollision, singleAABB)) { // Leaves - Configurable collision behavior
continue;
}
@@ -2078,6 +2086,17 @@ public final class CollisionUtil {
return ret;
}
+ // Leaves start - Configurable collision behavior
+ private static boolean shouldSkip(AABB aabb, VoxelShape blockCollision, AABB singleAABB) {
+ boolean isBlockShape = blockCollision == Shapes.block();
+ return switch (me.earthme.luminol.config.modules.misc.CollisionBehaviorConfig.behaviorMode) {
+ case "VANILLA" -> !voxelShapeIntersectVanilla(aabb, singleAABB);
+ case "BLOCK_SHAPE_VANILLA" -> isBlockShape && !voxelShapeIntersectVanilla(aabb, singleAABB) || !isBlockShape && !voxelShapeIntersect(aabb, singleAABB);
+ default -> !voxelShapeIntersect(aabb, singleAABB); // All other value as Paper to access this
+ };
+ }
+ // Leaves end - Configurable collision behavior
+
public static boolean getEntityHardCollisions(final Level world, final Entity entity, AABB aabb,
final List<AABB> into, final int collisionFlags, final Predicate<Entity> predicate) {
final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0;

View File

@@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sat, 8 Feb 2025 14:25:16 +0800
Subject: [PATCH] Leaves: Fix Incorrect Collision Behavior for Block Shape
Co-authored by: Fortern <blueten.ki@gmail.com>
As part of: Leaves (https://github.com/LeavesMC/Leaves/blob/f553c53e4230aa032e54a69b6479f1959ed24a60/leaves-server/minecraft-patches/features/0110-Fix-Incorrect-Collision-Behavior-for-Block-Shape.patch)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
index e1bf7bc3cca63101b3c0550b5b4c0d28d0f3776e..ea01087967dd9ff32b23661079e97ea468d31163 100644
--- a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
+++ b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
@@ -101,6 +101,14 @@ public final class CollisionUtil {
(box1.minZ - box2.maxZ) < -COLLISION_EPSILON && (box1.maxZ - box2.minZ) > COLLISION_EPSILON;
}
+ // Leaves start
+ public static boolean voxelShapeIntersectVanilla(final net.minecraft.world.phys.AABB box1, final net.minecraft.world.phys.AABB box2) {
+ return box1.minX < box2.maxX && box1.maxX > box2.minX &&
+ box1.minY < box2.maxY && box1.maxY > box2.minY &&
+ box1.minZ < box2.maxZ && box1.maxZ > box2.minZ;
+ }
+ // Leaves end
+
// assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON
public static double collideX(final AABB target, final AABB source, final double source_move) {
if ((source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON &&
@@ -2025,7 +2033,10 @@ public final class CollisionUtil {
AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation();
if (singleAABB != null) {
singleAABB = singleAABB.move((double)blockX, (double)blockY, (double)blockZ);
- if (!voxelShapeIntersect(aabb, singleAABB)) {
+ // Leaves start - Fix incorrect collision behavior for block shape
+ boolean isBlockShape = blockCollision == net.minecraft.world.phys.shapes.Shapes.block();
+ if (isBlockShape && !voxelShapeIntersectVanilla(aabb, singleAABB) || !isBlockShape && !voxelShapeIntersect(aabb, singleAABB)) {
+ // Leaves end - Fix incorrect collision behavior for block shape
continue;
}

View File

@@ -0,0 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Wed, 4 Jun 2025 12:54:22 +0800
Subject: [PATCH] Leaves: Fix chunk reload detector
Co-authored by: Fortern <blueten.ki@gmail.com>
As part of: Leaves (https://github.com/LeavesMC/Leaves/blob/c5f18b7864206cea4411211b51787f10affbcb9c/leaves-server/minecraft-patches/features/0123-Fix-chunk-reload-detector.patch)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
index b118e91f1e0b5a8b8c0b2a4a32faabc5a34a5954..663bd286426537daf97ae09dc7e076a9ec6d4c9c 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -376,7 +376,7 @@ public class ServerEntity {
if (!list.isEmpty()) {
consumer.accept(new ClientboundSetEquipmentPacket(this.entity.getId(), list, true)); // Paper - data sanitization
}
- ((LivingEntity) this.entity).detectEquipmentUpdates(); // CraftBukkit - SPIGOT-3789: sync again immediately after sending
+ if (this.entity.totalEntityAge == 0) ((LivingEntity) this.entity).detectEquipmentUpdates(); // CraftBukkit - SPIGOT-3789: sync again immediately after sending // Leaves - fix chunk reload detector (#492)
}
if (!this.entity.getPassengers().isEmpty()) {

View File

@@ -8,7 +8,7 @@ As part of: Leaves (https://github.com/LeavesMC/Leaves/blob/f553c53e4230aa032e54
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 5564bba66959a2a280f700f6c6a05d292faced88..4492f3ab470c0bf735b6fdc69115c1ebbcd727ef 100644
index bcc0c3cfa5be4daeec6e95a1b63a6cd38890f04d..e83c6a81e318a05580f5c811cb2543a83435f04c 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -1285,7 +1285,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc

View File

@@ -8,7 +8,7 @@ As part of: Pufferfish (https://github.com/pufferfish-gg/Pufferfish/blob/04bc249
Licensed under: GPL-3.0 (https://github.com/pufferfish-gg/Pufferfish/blob/04bc249f9eee6157338b6884113b6fa3192bf59b/PATCH-LICENSE)
diff --git a/net/minecraft/world/entity/monster/EnderMan.java b/net/minecraft/world/entity/monster/EnderMan.java
index ab7f7846d3fc0252c6f71277b3e67d7a785a96b5..0f496f0e1c63bc3d8b17a8f0cb065138cb079334 100644
index 5ae08be75ca01924fc78bdd8d6bb6747ddc21aea..6e0b6304205210cc60293329fe30bd6c99cd263a 100644
--- a/net/minecraft/world/entity/monster/EnderMan.java
+++ b/net/minecraft/world/entity/monster/EnderMan.java
@@ -300,11 +300,18 @@ public class EnderMan extends Monster implements NeutralMob {

View File

@@ -8,7 +8,7 @@ Co-authored by: MrPowerGamerBR <git@mrpowergamerbr.com>
As part of: SparklyPaper (https://github.com/SparklyPower/SparklyPaper/blob/a69d3690472c9967772ffd4d4bd1f41403b7ea6f/sparklypaper-server/minecraft-patches/features/0002-Skip-distanceToSqr-call-in-ServerEntity-sendChanges-.patch)
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
index b118e91f1e0b5a8b8c0b2a4a32faabc5a34a5954..8c232ae73a8c6500723994af3a28b36814cccae0 100644
index 663bd286426537daf97ae09dc7e076a9ec6d4c9c..8739b4e806878cf3a4af9ad1aef7f2a55880d503 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -205,6 +205,8 @@ public class ServerEntity {

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Correct player respawn place
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 4492f3ab470c0bf735b6fdc69115c1ebbcd727ef..8b9c823deed1844fa69d1456a91ac65487b8ae69 100644
index e83c6a81e318a05580f5c811cb2543a83435f04c..2f2726ed97658732751032b21752840702da233e 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -492,8 +492,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Sun, 9 Mar 2025 11:39:01 +0800
Subject: [PATCH] Do not search the block out of current region
Skip getting the blocks don't belong to current tickregion.
notice: this bug is actually caused by another bug of the teleportAsync implementation.
diff --git a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
index fc529ece01d8a85e600eb8910662010ab6851d82..7364515b7e489c5e97c7ca693458ff2ae9335c6e 100644
--- a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
@@ -432,6 +432,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity {
if (i != 0 || i1 != 0 || allowBedrock) {
for (int y = level.getMaxY(); y > (blockPos == null ? level.getMinY() : blockPos.getY()); y--) {
BlockPos blockPos1 = new BlockPos(pos.getX() + i, y, pos.getZ() + i1);
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor((Level) level, blockPos1)) continue; // Luminol - Do not search the block out of current region as we might be at the edge of the tickregion
BlockState blockState = level.getBlockState(blockPos1);
if (blockState.isCollisionShapeFullBlock(level, blockPos1) && (allowBedrock || !blockState.is(Blocks.BEDROCK))) {
blockPos = blockPos1;

View File

@@ -7,10 +7,10 @@ We use the old-like logics which is in 1.21.4.
Might fixes: https://github.com/PaperMC/Folia/issues/363
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 6dc5b1a8bdba998e11bcdf352bcc0fc7161a484c..753b36a7b1c2627540c62bea78565b880803a175 100644
index f8322334fb6a0cea38c4d1981862ba673fd1b100..0e08512ce94435ca90a2344eefc761fa4fcdeb18 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -173,10 +173,14 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -173,14 +173,26 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
// 2. _removes_ are impossible at this stage in the tick
final LevelChunk[] raw = entityTickingChunks.getRawDataUnchecked();
final int size = entityTickingChunks.size(); foliaProfiler.addCounter(ca.spottedleaf.leafprofiler.LProfilerRegistry.RANDOM_CHUNK_TICK_COUNT, (long)size); // Folia - profiler
@@ -20,10 +20,23 @@ index 6dc5b1a8bdba998e11bcdf352bcc0fc7161a484c..753b36a7b1c2627540c62bea78565b88
+ // Luminol end
- java.util.Objects.checkFromToIndex(0, size, raw.length);
+ this.level.getServer().moonrise$executeMidTickTasks(); // Luminol - Fix chunk iteration self modification - try executing mid-tick tasks for once chunk system task parsing
+ java.util.Objects.checkFromToIndex(0, size, rawCopy.length); // Luminol - Fix chunk iteration self modification - use copy of raw array
for (int i = 0; i < size; ++i) {
- world.tickChunk(raw[i], randomTickSpeed);
+ world.tickChunk(rawCopy[i], randomTickSpeed); // Luminol - Fix chunk iteration self modification - use copy of raw array
+ // Luminol start - Fix chunk iteration self modification
+ final LevelChunk chunk = rawCopy[i];
+
+ if (!chunk.getFullStatus().isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
+ continue; // skip chunks which are not entity ticking(probably downgraded from last iteration)
+ }
+ // Luminol end
+ world.tickChunk(chunk, randomTickSpeed); // Luminol - Fix chunk iteration self modification - use copy of raw array
// call mid-tick tasks for chunk system
if ((i & 7) == 0) {
- //((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.level.getServer()).moonrise$executeMidTickTasks(); // Folia - TODO restore this
+ ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.level.getServer()).moonrise$executeMidTickTasks(); // Folia - TODO restore this // Luminol - Fix chunk iteration self modification - restore mid tasks here
continue;
}
}

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Sat, 31 May 2025 16:28:19 +0800
Subject: [PATCH] Fix mispatched entity custom spawning logic
we should use local players as each tickregion will only foreach their own player entities so that we won't come across async accessing world data
diff --git a/net/minecraft/world/entity/npc/CatSpawner.java b/net/minecraft/world/entity/npc/CatSpawner.java
index f5d27988605d48cdf314f28ba332f33f0a314266..39b506dad0601b2d75acb14989f2758132155d1b 100644
--- a/net/minecraft/world/entity/npc/CatSpawner.java
+++ b/net/minecraft/world/entity/npc/CatSpawner.java
@@ -27,7 +27,7 @@ public class CatSpawner implements CustomSpawner {
worldData.catSpawnerNextTick--; // Folia - region threading
if (worldData.catSpawnerNextTick <= 0) { // Folia - region threading
worldData.catSpawnerNextTick = 1200; // Folia - region threading
- Player randomPlayer = level.getRandomPlayer();
+ Player randomPlayer = level.getRandomLocalPlayer(); // Luminol - Fix mispatched entity custom spawning logic - Use local players for only the players in current tickregion
if (randomPlayer != null) {
RandomSource randomSource = level.random;
int i = (8 + randomSource.nextInt(24)) * (randomSource.nextBoolean() ? -1 : 1);
diff --git a/net/minecraft/world/level/levelgen/PhantomSpawner.java b/net/minecraft/world/level/levelgen/PhantomSpawner.java
index a7f56126a26e1fca86c39d8d656b648f5d6bb4ca..4626ee9f4410d8fd683db17b49ef79ab67eeda5f 100644
--- a/net/minecraft/world/level/levelgen/PhantomSpawner.java
+++ b/net/minecraft/world/level/levelgen/PhantomSpawner.java
@@ -40,7 +40,7 @@ public class PhantomSpawner implements CustomSpawner {
worldData.phantomSpawnerNextTick += (spawnAttemptMinSeconds + randomSource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20; // Folia - region threading
// Paper end - Ability to control player's insomnia and phantoms
if (level.getSkyDarken() >= 5 || !level.dimensionType().hasSkyLight()) {
- for (ServerPlayer serverPlayer : level.players()) {
+ for (ServerPlayer serverPlayer : level.getLocalPlayers()) { // Luminol - Fix mispatched entity custom spawning logic - Use local players for only the players in current tickregion
if (!serverPlayer.isSpectator() && (!level.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !serverPlayer.isCreative())) { // Paper - Add phantom creative and insomniac controls
BlockPos blockPos = serverPlayer.blockPosition();
if (!level.dimensionType().hasSkyLight() || blockPos.getY() >= level.getSeaLevel() && level.canSeeSky(blockPos)) {

View File

@@ -1,6 +1,6 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java
@@ -1,0 +_,70 @@
@@ -1,0 +_,121 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.LuminolConfig;
@@ -16,55 +16,106 @@
+import java.util.List;
+
+public class LuminolConfigCommand extends Command {
+ public LuminolConfigCommand(){
+ public LuminolConfigCommand() {
+ super("luminolconfig");
+ this.setPermission("luminol.commands.luminolconfig");
+ this.setDescription("Manage config file");
+ this.setUsage("/luminolconfig");
+ }
+
+ public void wrongUse(CommandSender sender) {
+ sender.sendMessage(
+ Component
+ .text("Wrong use!")
+ .color(TextColor.color(255, 0, 0))
+ );
+ }
+
+ @Override
+ public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args, @Nullable Location location) throws IllegalArgumentException {
+ final List<String> result = new ArrayList<>();
+
+ if (args.length == 1){
+ if (args.length == 1) {
+ result.add("query");
+ result.add("set");
+ result.add("reset");
+ result.add("reload");
+ } else if (args.length == 2 && args[0] != "reload") {
+ result.addAll(LuminolConfig.getAllConfigPaths(args[1]));
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!this.testPermission(sender)){
+ if (!this.testPermission(sender)) {
+ sender.sendMessage(Component
+ .text("No permission to execute this command!")
+ .color(TextColor.color(255,0,0))
+ .color(TextColor.color(255, 0, 0))
+ );
+ }
+
+ if (args.length < 1){
+ sender.sendMessage(
+ Component
+ .text("Wrong use!\n")
+ .color(TextColor.color(255,0,0))
+ );
+ if (args.length < 1) {
+ wrongUse(sender);
+ return true;
+ }
+
+ switch (args[0]){
+ switch (args[0]) {
+ case "reload" -> {
+ LuminolConfig.reloadAsync().thenAccept(nullValue -> sender.sendMessage(
+ Component
+ .text("Reloaded config file!")
+ .color(TextColor.color(0,255,0))
+ .color(TextColor.color(0, 255, 0))
+ ));
+ }
+ case "set" -> {
+ if (args.length == 2 || args.length > 3) {
+ wrongUse(sender);
+ return true;
+ } else if (LuminolConfig.setConfig(args[1], args[2])) {
+ LuminolConfig.reloadAsync().thenAccept(nullValue -> sender.sendMessage(
+ Component
+ .text("Set Config " + args[1] + " to " + args[2] + " successfully!")
+ .color(TextColor.color(0, 255, 0))
+ ));
+ } else {
+ sender.sendMessage(
+ Component
+ .text("Failed to set config " + args[1] + " to " + args[2] + "!")
+ .color(TextColor.color(255, 0, 0))
+ );
+ }
+ }
+ case "reset" -> {
+ if (args.length != 2) {
+ wrongUse(sender);
+ return true;
+ } else {
+ LuminolConfig.resetConfig(args[1]);
+ LuminolConfig.reloadAsync().thenAccept(nullValue -> sender.sendMessage(
+ Component
+ .text("Reset Config " + args[1] + " to " + LuminolConfig.getConfig(args[1]) + " successfully!")
+ .color(TextColor.color(0, 255, 0))
+ ));
+ }
+ }
+ case "query" -> {
+ if (args.length != 2) {
+ wrongUse(sender);
+ return true;
+ } else {
+ sender.sendMessage(
+ Component
+ .text("Config " + args[1] + " is " + LuminolConfig.getConfig(args[1]) + "!")
+ .color(TextColor.color(0, 255, 0))
+ );
+ }
+ }
+
+ default -> sender.sendMessage(
+ Component
+ .text("Unknown action!\n")
+ .color(TextColor.color(255,0,0))
+ .text("Unknown action!")
+ .color(TextColor.color(255, 0, 0))
+ );
+ }
+

View File

@@ -22,28 +22,28 @@
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!testPermission(sender)){
+ if (!testPermission(sender)) {
+ return true;
+ }
+
+ if (!MembarConfig.memoryBarEnabled){
+ sender.sendMessage(Component.text("Membar was already disabled!").color(TextColor.color(255,0,0)));
+ if (!MembarConfig.memoryBarEnabled) {
+ sender.sendMessage(Component.text("Membar was already disabled!").color(TextColor.color(255, 0, 0)));
+ return true;
+ }
+
+ if (!(sender instanceof Player player)){
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255,0,0)));
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255, 0, 0)));
+ return true;
+ }
+
+ if (GlobalServerMemoryBar.isPlayerVisible(player)) {
+ player.sendMessage(Component.text("Disabled mem bar").color(TextColor.color(0,255,0)));
+ GlobalServerMemoryBar.setVisibilityForPlayer(player,false);
+ player.sendMessage(Component.text("Disabled mem bar").color(TextColor.color(0, 255, 0)));
+ GlobalServerMemoryBar.setVisibilityForPlayer(player, false);
+ return true;
+ }
+
+ player.sendMessage(Component.text("Enabled mem bar").color(TextColor.color(0,255,0)));
+ GlobalServerMemoryBar.setVisibilityForPlayer(player,true);
+ player.sendMessage(Component.text("Enabled mem bar").color(TextColor.color(0, 255, 0)));
+ GlobalServerMemoryBar.setVisibilityForPlayer(player, true);
+
+ return true;
+ }

View File

@@ -1,15 +1,12 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java
@@ -1,0 +_,50 @@
@@ -1,0 +_,47 @@
+package me.earthme.luminol.commands;
+
+import me.earthme.luminol.config.modules.misc.TpsBarConfig;
+import me.earthme.luminol.functions.GlobalServerTpsBar;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import net.kyori.adventure.util.RGBLike;
+import org.bukkit.ChatColor;
+import org.bukkit.Color;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
@@ -25,28 +22,28 @@
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
+ if (!testPermission(sender)){
+ if (!testPermission(sender)) {
+ return true;
+ }
+
+ if (!TpsBarConfig.tpsbarEnabled){
+ sender.sendMessage(Component.text("Tpsbar was already disabled!").color(TextColor.color(255,0,0)));
+ if (!TpsBarConfig.tpsbarEnabled) {
+ sender.sendMessage(Component.text("Tpsbar was already disabled!").color(TextColor.color(255, 0, 0)));
+ return true;
+ }
+
+ if (!(sender instanceof Player player)){
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255,0,0)));
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage(Component.text("Only player can use this command!").color(TextColor.color(255, 0, 0)));
+ return true;
+ }
+
+ if (GlobalServerTpsBar.isPlayerVisible(player)) {
+ player.sendMessage(Component.text("Disabled tps bar").color(TextColor.color(0,255,0)));
+ GlobalServerTpsBar.setVisibilityForPlayer(player,false);
+ player.sendMessage(Component.text("Disabled tps bar").color(TextColor.color(0, 255, 0)));
+ GlobalServerTpsBar.setVisibilityForPlayer(player, false);
+ return true;
+ }
+
+ player.sendMessage(Component.text("Enabled tps bar").color(TextColor.color(0,255,0)));
+ GlobalServerTpsBar.setVisibilityForPlayer(player,true);
+ player.sendMessage(Component.text("Enabled tps bar").color(TextColor.color(0, 255, 0)));
+ GlobalServerTpsBar.setVisibilityForPlayer(player, true);
+
+ return true;
+ }

View File

@@ -1,6 +1,6 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/IConfigModule.java
@@ -1,0 +_,22 @@
@@ -1,0 +_,23 @@
+package me.earthme.luminol.config;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
@@ -12,11 +12,12 @@
+
+ String getBaseName();
+
+ default void onLoaded(CommentedFileConfig configInstance) {}
+ default void onLoaded(CommentedFileConfig configInstance) {
+ }
+
+ default <T> T get(String keyName, T defaultValue, @NotNull CommentedFileConfig config){
+ if (!config.contains(keyName)){
+ config.set(keyName,defaultValue);
+ default <T> T get(String keyName, T defaultValue, @NotNull CommentedFileConfig config) {
+ if (!config.contains(keyName)) {
+ config.set(keyName, defaultValue);
+ return defaultValue;
+ }
+

View File

@@ -1,12 +1,17 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/LuminolConfig.java
@@ -1,0 +_,275 @@
@@ -1,0 +_,378 @@
+package me.earthme.luminol.config;
+
+import com.electronwill.nightconfig.core.CommentedConfig;
+import com.electronwill.nightconfig.core.UnmodifiableConfig;
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import io.papermc.paper.threadedregions.RegionizedServer;
+import me.earthme.luminol.commands.LuminolConfigCommand;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.DoNotLoad;
+import me.earthme.luminol.config.flags.HotReloadUnsupported;
+import me.earthme.luminol.config.flags.TransformedConfig;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.bukkit.Bukkit;
@@ -32,12 +37,14 @@
+ private static final File baseConfigFolder = new File("luminol_config");
+ private static final File baseConfigFile = new File(baseConfigFolder, "luminol_global_config.toml");
+ private static final Set<IConfigModule> allInstanced = new HashSet<>();
+ public static boolean alreadyInited = false;
+ private static final Map<String, Object> stagedConfigMap = new HashMap<>();
+ private static final Map<String, Object> defaultvalueMap = new HashMap<>();
+ public static boolean alreadyInit = false;
+ private static CommentedFileConfig configFileInstance;
+
+ public static void setupLatch() {
+ Bukkit.getCommandMap().register("luminolconfig", "luminol", new LuminolConfigCommand());
+ alreadyInited = true;
+ alreadyInit = true;
+ }
+
+ public static void reload() {
@@ -80,7 +87,7 @@
+ baseConfigFile.createNewFile();
+ }
+
+ configFileInstance = CommentedFileConfig.ofConcurrent(baseConfigFile);
+ configFileInstance = CommentedFileConfig.of(baseConfigFile);
+
+ configFileInstance.load();
+
@@ -92,7 +99,7 @@
+ throw new RuntimeException(e);
+ }
+
+ configFileInstance.save();
+ saveConfigs();
+ }
+
+ private static void loadAllModules() throws IllegalAccessException {
@@ -117,7 +124,7 @@
+ for (Field field : fields) {
+ int modifiers = field.getModifiers();
+ if (Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
+ boolean skipLoad = field.getAnnotation(DoNotLoad.class) != null || (alreadyInited && field.getAnnotation(HotReloadUnsupported.class) != null);
+ boolean skipLoad = field.getAnnotation(DoNotLoad.class) != null || (alreadyInit && field.getAnnotation(HotReloadUnsupported.class) != null);
+ ConfigInfo configInfo = field.getAnnotation(ConfigInfo.class);
+
+ if (skipLoad || configInfo == null) {
@@ -128,6 +135,7 @@
+
+ field.setAccessible(true);
+ final Object currentValue = field.get(null);
+ if (!alreadyInit) defaultvalueMap.put(fullConfigKeyName, currentValue);
+ boolean removed = fullConfigKeyName.equals("removed.removed_config.removed");
+
+ if (!configFileInstance.contains(fullConfigKeyName) || removed) {
@@ -175,7 +183,21 @@
+ continue;
+ }
+
+ final Object actuallyValue = configFileInstance.get(fullConfigKeyName);
+ Object actuallyValue;
+ if (stagedConfigMap.containsKey(fullConfigKeyName)) {
+ actuallyValue = stagedConfigMap.get(fullConfigKeyName);
+ if (actuallyValue == null) actuallyValue = defaultvalueMap.get(fullConfigKeyName);
+ stagedConfigMap.remove(fullConfigKeyName);
+ } else {
+ actuallyValue = configFileInstance.get(fullConfigKeyName);
+ }
+ try {
+ actuallyValue = tryTransform(field.get(null).getClass(), actuallyValue);
+ configFileInstance.set(fullConfigKeyName, actuallyValue);
+ } catch (IllegalFormatConversionException e) {
+ resetConfig(fullConfigKeyName);
+ logger.error("Failed to transform config {}, reset to default!", fullConfigKeyName);
+ }
+ field.set(null, actuallyValue);
+ }
+ }
@@ -197,6 +219,87 @@
+ }
+ }
+
+ public static boolean setConfig(String[] keys, Object value) {
+ return setConfig(String.join(".", keys), value);
+ }
+
+ public static boolean setConfig(String key, Object value) {
+ if (configFileInstance.contains(key) && configFileInstance.get(key) != null) {
+ stagedConfigMap.put(key, value);
+ return true;
+ }
+ return false;
+ }
+
+ private static Object tryTransform(Class<?> targetType, Object value) {
+ if (!targetType.isAssignableFrom(value.getClass())) {
+ try {
+ if (targetType == Integer.class) {
+ value = Integer.parseInt(value.toString());
+ } else if (targetType == Double.class) {
+ value = Double.parseDouble(value.toString());
+ } else if (targetType == Boolean.class) {
+ value = Boolean.parseBoolean(value.toString());
+ } else if (targetType == Long.class) {
+ value = Long.parseLong(value.toString());
+ } else if (targetType == Float.class) {
+ value = Float.parseFloat(value.toString());
+ } else if (targetType == String.class) {
+ value = value.toString();
+ }
+ } catch (Exception e) {
+ logger.error("Failed to transform value {}!", value);
+ throw new IllegalFormatConversionException((char) 0, targetType);
+ }
+ }
+ return value;
+ }
+
+ public static void saveConfigs() {
+ configFileInstance.save();
+ }
+
+ public static void resetConfig(String[] keys) {
+ resetConfig(String.join(".", keys));
+ }
+
+ public static void resetConfig(String key) {
+ stagedConfigMap.put(key, null);
+ }
+
+ public static String getConfig(String[] keys) {
+ return getConfig(String.join(".", keys));
+ }
+
+ public static String getConfig(String key) {
+ return configFileInstance.get(key).toString();
+ }
+
+ public static List<String> getAllConfigPaths(String prefix) {
+ List<String> configPaths = getAllConfigPaths();
+ return configPaths.stream().filter(path -> path.startsWith(prefix)).toList();
+ }
+
+ public static List<String> getAllConfigPaths() {
+ List<String> configPaths = new ArrayList<>();
+ getAllConfigPathsRecursive(configFileInstance, "", configPaths);
+ return configPaths;
+ }
+
+ private static void getAllConfigPathsRecursive(CommentedConfig config, String currentPath, List<String> configPaths) {
+ for (CommentedConfig.Entry entry : config.entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ String fullPath = currentPath.isEmpty() ? key : currentPath + "." + key;
+
+ if (value instanceof CommentedConfig) {
+ getAllConfigPathsRecursive((CommentedConfig) value, fullPath, configPaths);
+ } else {
+ configPaths.add(fullPath);
+ }
+ }
+ }
+
+ public static @NotNull Set<Class<?>> getClasses(String pack) {
+ Set<Class<?>> classes = new LinkedHashSet<>();
+ String packageDirName = pack.replace('.', '/');

View File

@@ -1,7 +1,7 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/ConfigInfo.java
+++ b/src/main/java/me/earthme/luminol/config/flags/ConfigInfo.java
@@ -1,0 +_,11 @@
+package me.earthme.luminol.config;
+package me.earthme.luminol.config.flags;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;

View File

@@ -1,7 +1,7 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/DoNotLoad.java
+++ b/src/main/java/me/earthme/luminol/config/flags/DoNotLoad.java
@@ -1,0 +_,8 @@
+package me.earthme.luminol.config;
+package me.earthme.luminol.config.flags;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;

View File

@@ -1,7 +1,7 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java
+++ b/src/main/java/me/earthme/luminol/config/flags/HotReloadUnsupported.java
@@ -1,0 +_,8 @@
+package me.earthme.luminol.config;
+package me.earthme.luminol.config.flags;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;

View File

@@ -1,7 +1,9 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/TransformedConfig.java
@@ -1,0 +_,24 @@
+package me.earthme.luminol.config;
+++ b/src/main/java/me/earthme/luminol/config/flags/TransformedConfig.java
@@ -1,0 +_,26 @@
+package me.earthme.luminol.config.flags;
+
+import me.earthme.luminol.config.DefaultTransformLogic;
+
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
@@ -10,9 +12,9 @@
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(TransformedConfig.List.class)
+public @interface TransformedConfig {
+ String name() default "";
+ String name();
+
+ String[] category() default "";
+ String[] category();
+
+ boolean transform() default true;
+

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class CommandBlockConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enable")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class CommandDataConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enable")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,22 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class CommandTickConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments =

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class DisableAsyncCatcherConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class DisableEntityCatchConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -1,13 +1,15 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/EntityDamageSourceTraceConfig.java
@@ -1,0 +_,22 @@
@@ -1,0 +_,24 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.TransformedConfig;
+
+public class EntityDamageSourceTraceConfig implements IConfigModule {
+ @TransformedConfig(name = "enabled", category = {"experiment", "entity-damage-source-trace"})
+ @ConfigInfo(baseName = "enabled", comments =
+ """
+ Allow trace damage source cross different Region Scheduler.""")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,28 @@
+package me.earthme.luminol.config.modules.experiment;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class RayTrackingEntityTrackerConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,28 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class FoliaEntityMovingFixConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments =

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,25 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class FoliaPOIAccessOffRegionFixConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments =

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,22 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class ForceCleanupEntityBrainMemoryConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled_for_entity", comments = "When enabled, the entity's brain will clean the memory which is typed of entity and not belong to current tickregion")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,22 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class UnsafeTeleportationConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments = "Allow non player entities enter end portals if enabled.\n" +

View File

@@ -3,12 +3,12 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.fixes;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class VanillaRandomSourceConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enable_for_player_entity",comments = "Related with RNG cracks")
+ @ConfigInfo(baseName = "enable_for_player_entity", comments = "Related with RNG cracks")
+ public static boolean useLegacyRandomSourceForPlayers = false;
+
+ @Override

View File

@@ -0,0 +1,28 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/CollisionBehaviorConfig.java
@@ -1,0 +_,25 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class CollisionBehaviorConfig implements IConfigModule {
+ @ConfigInfo(baseName = "mode", comments =
+ """
+ Available Value:
+ VANILLA
+ BLOCK_SHAPE_VANILLA
+ PAPER""")
+ public static String behaviorMode = "PAPER";
+
+ @Override
+ public EnumConfigCategory getCategory() {
+ return EnumConfigCategory.MISC;
+ }
+
+ @Override
+ public String getBaseName() {
+ return "collision_behavior";
+ }
+}

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,27 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class ContainerExpansionConfig implements IConfigModule {
+ @ConfigInfo(baseName = "barrel_rows", comments =

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,23 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class DisableEndCrystalCheckConfig implements IConfigModule {
+ @ConfigInfo(baseName = "disable_end_crystal_check", comments =

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,22 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class DisableHeightmapWarnConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments =

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class DisableMovedWronglyThreshold implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class FoliaWatchogConfig implements IConfigModule {
+ @ConfigInfo(baseName = "tick_region_time_out_ms")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class InorderChatConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -5,10 +5,10 @@
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.commands.MembarCommand;
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.DoNotLoad;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.DoNotLoad;
+import me.earthme.luminol.functions.GlobalServerMemoryBar;
+import org.bukkit.Bukkit;
+
@@ -20,7 +20,7 @@
+ @ConfigInfo(baseName = "format")
+ public static String memBarFormat = "<gray>Memory usage <yellow>:</yellow> <used>MB<yellow>/</yellow><available>MB";
+ @ConfigInfo(baseName = "memory_color_list")
+ public static List<String> memColors = List.of("GREEN","YELLOW","RED","PURPLE");
+ public static List<String> memColors = List.of("GREEN", "YELLOW", "RED", "PURPLE");
+ @ConfigInfo(baseName = "update_interval_ticks")
+ public static int updateInterval = 15;
+
@@ -38,15 +38,15 @@
+ }
+
+ @Override
+ public void onLoaded(CommentedFileConfig configInstance){
+ if (memoryBarEnabled){
+ public void onLoaded(CommentedFileConfig configInstance) {
+ if (memoryBarEnabled) {
+ GlobalServerMemoryBar.init();
+ }else{
+ } else {
+ GlobalServerMemoryBar.cancelBarUpdateTask();
+ }
+
+ if (!inited){
+ Bukkit.getCommandMap().register("membar","luminol",new MembarCommand("membar"));
+ if (!inited) {
+ Bukkit.getCommandMap().register("membar", "luminol", new MembarCommand("membar"));
+ inited = true;
+ }
+ }

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class OfflineModeWarningConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,21 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class PublickeyVerifyConfig implements IConfigModule {
+

View File

@@ -1,31 +1,36 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/RaidChangesConfig.java
@@ -1,0 +_,54 @@
@@ -1,0 +_,61 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.TransformedConfig;
+
+public class RaidChangesConfig implements IConfigModule {
+ @TransformedConfig(name = "allow-bad-omen-trigger-raid", category = {"misc", "revert-raid-changes"})
+ @ConfigInfo(baseName = "allow_bad_omen_trigger_raid", comments =
+ """
+ Allow players with ominous signs to skip a\s
+ 30-second cooldown and trigger attacks directly""")
+ public static boolean trigger = false;
+
+ @TransformedConfig(name = "give-bad-omen-when-kill-patrol-leader", category = {"misc", "revert-raid-changes"})
+ @ConfigInfo(baseName = "give_bad_omen_when_kill_patrol_leader", comments =
+ """
+ Enable players to obtain an ominous omen\s
+ effect when killing the patrol team captain""")
+ public static boolean effect = false;
+
+ @TransformedConfig(name = "bad-omen-infinite", category = {"misc", "revert-raid-changes"})
+ @ConfigInfo(baseName = "bad_omen_infinite", comments =
+ """
+ Enable bad omen effect infinite time
+ --- this config is not old version's function""")
+ public static boolean infinite = false;
+
+ @TransformedConfig(name = "skip-height-check", category = {"misc", "revert-raid-changes"})
+ @ConfigInfo(baseName = "skip_height_check", comments =
+ """
+ Disable y <= 96 check.
@@ -33,12 +38,14 @@
+ and always behavior of enabled""")
+ public static boolean heightCheck = false;
+
+ @TransformedConfig(name = "skip-self-raid-check", category = {"misc", "revert-raid-changes"})
+ @ConfigInfo(baseName = "skip_self_raid_check", comments =
+ """
+ Disable raid self check\s
+ --- this config is not old version's function""")
+ public static boolean selfCheck = false;
+
+ @TransformedConfig(name = "revert-274911", category = {"misc", "revert-raid-changes"})
+ @ConfigInfo(baseName = "revert_274911", comments =
+ """
+ Revert Old raid's find spawn position logic

View File

@@ -5,10 +5,10 @@
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.commands.RegionBarCommand;
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.DoNotLoad;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.DoNotLoad;
+import me.earthme.luminol.functions.GlobalServerRegionBar;
+import org.bukkit.Bukkit;
+

View File

@@ -1,11 +1,15 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java
@@ -1,0 +_,59 @@
@@ -1,0 +_,63 @@
+package me.earthme.luminol.config.modules.misc;
+
+import abomination.LinearRegionFile;
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.config.*;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.DoNotLoad;
+import me.earthme.luminol.config.flags.HotReloadUnsupported;
+import me.earthme.luminol.utils.EnumRegionFormat;
+import net.minecraft.server.MinecraftServer;
+

View File

@@ -3,14 +3,14 @@
@@ -1,0 +_,22 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class SecureSeedConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled", comments = """
+ Once you enable secure seed, all ores and structures are generated with 1024-bit seed
+ instead of using 64-bit seed in vanilla, made seed cracker become impossible.""")
+ Once you enable secure seed, all ores and structures are generated with 1024-bit seed
+ instead of using 64-bit seed in vanilla, made seed cracker become impossible.""")
+ public static boolean enabled = false;
+
+ @Override

View File

@@ -4,9 +4,9 @@
+package me.earthme.luminol.config.modules.misc;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import org.apache.logging.log4j.Level;
+
+public class SentryConfig implements IConfigModule {

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,23 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class ServerModNameConfig implements IConfigModule {
+ @ConfigInfo(baseName = "name")

View File

@@ -1,11 +1,14 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
@@ -1,0 +_,51 @@
@@ -1,0 +_,54 @@
+package me.earthme.luminol.config.modules.misc;
+
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import me.earthme.luminol.commands.TpsBarCommand;
+import me.earthme.luminol.config.*;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.DoNotLoad;
+import me.earthme.luminol.functions.GlobalServerTpsBar;
+import org.bukkit.Bukkit;
+
@@ -17,11 +20,11 @@
+ @ConfigInfo(baseName = "format")
+ public static String tpsBarFormat = "<gray>TPS<yellow>:</yellow> <tps> MSPT<yellow>:</yellow> <mspt> Ping<yellow>:</yellow> <ping>ms ChunkHot<yellow>:</yellow> <chunkhot>";
+ @ConfigInfo(baseName = "tps_color_list")
+ public static List<String> tpsColors = List.of("GREEN","YELLOW","RED","PURPLE");
+ public static List<String> tpsColors = List.of("GREEN", "YELLOW", "RED", "PURPLE");
+ @ConfigInfo(baseName = "ping_color_list")
+ public static List<String> pingColors = List.of("GREEN","YELLOW","RED","PURPLE");
+ public static List<String> pingColors = List.of("GREEN", "YELLOW", "RED", "PURPLE");
+ @ConfigInfo(baseName = "chunkhot_color_list")
+ public static List<String> chunkHotColors = List.of("GREEN","YELLOW","RED","PURPLE");
+ public static List<String> chunkHotColors = List.of("GREEN", "YELLOW", "RED", "PURPLE");
+ @ConfigInfo(baseName = "update_interval_ticks")
+ public static int updateInterval = 15;
+
@@ -39,15 +42,15 @@
+ }
+
+ @Override
+ public void onLoaded(CommentedFileConfig configInstance){
+ if (tpsbarEnabled){
+ public void onLoaded(CommentedFileConfig configInstance) {
+ if (tpsbarEnabled) {
+ GlobalServerTpsBar.init();
+ }else{
+ } else {
+ GlobalServerTpsBar.cancelBarUpdateTask();
+ }
+
+ if (!inited){
+ Bukkit.getCommandMap().register("tpsbar","luminol",new TpsBarCommand("tpsbar"));
+ if (!inited) {
+ Bukkit.getCommandMap().register("tpsbar", "luminol", new TpsBarCommand("tpsbar"));
+ inited = true;
+ }
+ }

View File

@@ -1,18 +1,20 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/AllowTripwireDupe.java
@@ -1,0 +_,27 @@
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/TripwireBehaviorConfig.java
@@ -1,0 +_,29 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.TransformedConfig;
+
+public class AllowTripwireDupe implements IConfigModule {
+public class TripwireBehaviorConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")
+ public static boolean enabled = false;
+ @TransformedConfig(name = "behavior-mode", category = {"misc", "tripwire_dupe"})
+ @ConfigInfo(baseName = "behavior_mode", comments =
+ """
+ Allowed Value:
+ Available Value:
+ VANILLA20
+ VANILLA21
+ MIXED""")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.misc;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class UsernameCheckConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class EntityGoalSelectorInactiveTickConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class GaleVariableEntityWakeupConfig implements IConfigModule {
+ @ConfigInfo(baseName = "entity_wakeup_duration_ratio_standard_deviation")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,24 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class LobotomizeVillageConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,22 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class PetalReduceSensorWorkConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,22 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class ProjectileChunkReduceConfig implements IConfigModule {
+ @ConfigInfo(baseName = "max-loads-per-tick")

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class PurpurAlternativeKeepaliveConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -6,10 +6,10 @@
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
+import com.mojang.logging.LogUtils;
+import gg.pufferfish.pufferfish.simd.SIMDDetection;
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.DoNotLoad;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.DoNotLoad;
+import org.slf4j.Logger;
+
+public class SIMDConfig implements IConfigModule {
@@ -30,7 +30,7 @@
+
+ @Override
+ public void onLoaded(CommentedFileConfig configInstance) {
+ if (!enabled){
+ if (!enabled) {
+ return;
+ }
+

View File

@@ -3,9 +3,9 @@
@@ -1,0 +_,20 @@
+package me.earthme.luminol.config.modules.optimizations;
+
+import me.earthme.luminol.config.ConfigInfo;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+
+public class SuffocationOptimizationConfig implements IConfigModule {
+ @ConfigInfo(baseName = "enabled")

View File

@@ -1,9 +1,13 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/config/modules/removed/RemovedConfig.java
@@ -1,0 +_,22 @@
@@ -1,0 +_,26 @@
+package me.earthme.luminol.config.modules.removed;
+
+import me.earthme.luminol.config.*;
+import me.earthme.luminol.config.EnumConfigCategory;
+import me.earthme.luminol.config.IConfigModule;
+import me.earthme.luminol.config.flags.ConfigInfo;
+import me.earthme.luminol.config.flags.DoNotLoad;
+import me.earthme.luminol.config.flags.TransformedConfig;
+
+public class RemovedConfig implements IConfigModule {
+ @TransformedConfig(name = "example", category = {"removed", "example"}, transform = false)

View File

@@ -26,24 +26,24 @@
+ protected static final NullPlugin NULL_PLUGIN = new NullPlugin();
+ protected static final Map<UUID, BossBar> uuid2Bossbars = Maps.newConcurrentMap();
+ protected static final Map<UUID, ScheduledTask> scheduledTasks = new HashMap<>();
+ protected static volatile ScheduledTask scannerTask = null;
+ private static final Logger logger = LogUtils.getLogger();
+ protected static volatile ScheduledTask scannerTask = null;
+
+ public static void init(){
+ public static void init() {
+ cancelBarUpdateTask();
+
+ scannerTask = Bukkit.getGlobalRegionScheduler().runAtFixedRate(NULL_PLUGIN, unused -> {
+ try {
+ update();
+ }catch (Exception e){
+ } catch (Exception e) {
+ logger.error(e.getLocalizedMessage());
+ }
+ }, 1, MembarConfig.updateInterval);
+ }
+
+
+ public static void cancelBarUpdateTask(){
+ if (scannerTask == null || scannerTask.isCancelled()){
+ public static void cancelBarUpdateTask() {
+ if (scannerTask == null || scannerTask.isCancelled()) {
+ return;
+ }
+
@@ -56,20 +56,20 @@
+ }
+ }
+
+ public static boolean isPlayerVisible(Player player){
+ public static boolean isPlayerVisible(Player player) {
+ return ((CraftPlayer) player).getHandle().isMemBarVisible;
+ }
+
+ public static void setVisibilityForPlayer(Player target,boolean canSee){
+ public static void setVisibilityForPlayer(Player target, boolean canSee) {
+ ((CraftPlayer) target).getHandle().isMemBarVisible = canSee;
+ }
+
+ private static void update(){
+ private static void update() {
+ doUpdate();
+ cleanUp();
+ }
+
+ private static void cleanUp(){
+ private static void cleanUp() {
+ final List<UUID> toCleanUp = new ArrayList<>();
+
+ for (Map.Entry<UUID, ScheduledTask> toCheck : scheduledTasks.entrySet()) {
@@ -83,7 +83,7 @@
+ }
+ }
+
+ private static void doUpdate(){
+ private static void doUpdate() {
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ scheduledTasks.computeIfAbsent(player.getUniqueId(), unused -> createBossBarForPlayer(player));
+ }
@@ -110,7 +110,7 @@
+
+ BossBar targetBossbar = uuid2Bossbars.computeIfAbsent(
+ playerUUID,
+ (unused1) -> BossBar.bossBar(Component.text(""),0.0F, BossBar.Color.valueOf(MembarConfig.memColors.get(3)), BossBar.Overlay.NOTCHED_20)
+ (unused1) -> BossBar.bossBar(Component.text(""), 0.0F, BossBar.Color.valueOf(MembarConfig.memColors.get(3)), BossBar.Overlay.NOTCHED_20)
+ );
+
+ apiPlayer.showBossBar(targetBossbar);
@@ -125,47 +125,47 @@
+ }, 1, MembarConfig.updateInterval);
+ }
+
+ private static void updateMembar(@NotNull BossBar bar, long used, long xmx){
+ private static void updateMembar(@NotNull BossBar bar, long used, long xmx) {
+ double percent = Math.max(Math.min((float) used / xmx, 1.0F), 0.0F);
+ bar.name(MiniMessage.miniMessage().deserialize(
+ MembarConfig.memBarFormat,
+ Placeholder.component("used", getMemoryComponent(used,xmx)),
+ Placeholder.component("available",getMaxMemComponent(xmx))
+ Placeholder.component("used", getMemoryComponent(used, xmx)),
+ Placeholder.component("available", getMaxMemComponent(xmx))
+ ));
+ bar.color(barColorFromMemory(percent));
+ bar.progress((float) percent);
+ }
+
+ private static @NotNull Component getMaxMemComponent(double max){
+ private static @NotNull Component getMaxMemComponent(double max) {
+ final BossBar.Color colorBukkit = BossBar.Color.GREEN;
+ final String colorString = colorBukkit.name();
+
+ final String content = "<%s><text></%s>";
+ final String replaced = String.format(content,colorString,colorString);
+ final String replaced = String.format(content, colorString, colorString);
+
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", max / (1024 * 1024))));
+ return MiniMessage.miniMessage().deserialize(replaced, Placeholder.parsed("text", String.format("%.2f", max / (1024 * 1024))));
+ }
+
+ private static @NotNull Component getMemoryComponent(long used,long max){
+ private static @NotNull Component getMemoryComponent(long used, long max) {
+ final BossBar.Color colorBukkit = barColorFromMemory(Math.max(Math.min((float) used / max, 1.0F), 0.0F));
+ final String colorString = colorBukkit.name();
+
+ final String content = "<%s><text></%s>";
+ final String replaced = String.format(content,colorString,colorString);
+ final String replaced = String.format(content, colorString, colorString);
+
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", (double)used / (1024 * 1024))));
+ return MiniMessage.miniMessage().deserialize(replaced, Placeholder.parsed("text", String.format("%.2f", (double) used / (1024 * 1024))));
+ }
+
+ private static BossBar.Color barColorFromMemory(double memPercent){
+ if (memPercent == -1){
+ private static BossBar.Color barColorFromMemory(double memPercent) {
+ if (memPercent == -1) {
+ return BossBar.Color.valueOf(MembarConfig.memColors.get(3));
+ }
+
+ if (memPercent <= 50){
+ if (memPercent <= 50) {
+ return BossBar.Color.valueOf(MembarConfig.memColors.getFirst());
+ }
+
+ if (memPercent <= 70){
+ if (memPercent <= 70) {
+ return BossBar.Color.valueOf(MembarConfig.memColors.get(1));
+ }
+

View File

@@ -1,11 +1,14 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/functions/GlobalServerRegionBar.java
@@ -1,0 +_,184 @@
@@ -1,0 +_,185 @@
+package me.earthme.luminol.functions;
+
+import com.google.common.collect.Maps;
+import com.mojang.logging.LogUtils;
+import io.papermc.paper.threadedregions.*;
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
+import io.papermc.paper.threadedregions.TickData;
+import io.papermc.paper.threadedregions.TickRegionScheduler;
+import io.papermc.paper.threadedregions.TickRegions;
+import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
+import me.earthme.luminol.config.modules.misc.RegionBarConfig;
+import me.earthme.luminol.utils.NullPlugin;
@@ -26,11 +29,9 @@
+ protected static final NullPlugin NULL_PLUGIN = new NullPlugin();
+ protected static final Map<UUID, BossBar> uuid2Bossbars = Maps.newConcurrentMap();
+ protected static final Map<UUID, ScheduledTask> scheduledTasks = new HashMap<>();
+
+ protected static volatile ScheduledTask scannerTask = null;
+ private static final Logger logger = LogUtils.getLogger();
+
+ private static final ThreadLocal<DecimalFormat> ONE_DECIMAL_PLACES = ThreadLocal.withInitial(() -> new DecimalFormat("#,##0.0"));
+ protected static volatile ScheduledTask scannerTask = null;
+
+ public static void init() {
+ cancelBarUpdateTask();

View File

@@ -1,6 +1,6 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
@@ -1,0 +_,241 @@
@@ -1,0 +_,240 @@
+package me.earthme.luminol.functions;
+
+import com.google.common.collect.Maps;
@@ -28,25 +28,24 @@
+ protected static final NullPlugin NULL_PLUGIN = new NullPlugin();
+ protected static final Map<UUID, BossBar> uuid2Bossbars = Maps.newConcurrentMap();
+ protected static final Map<UUID, ScheduledTask> scheduledTasks = new HashMap<>();
+
+ protected static volatile ScheduledTask scannerTask = null;
+ private static final Logger logger = LogUtils.getLogger();
+ protected static volatile ScheduledTask scannerTask = null;
+
+ public static void init(){
+ public static void init() {
+ cancelBarUpdateTask();
+
+ scannerTask = Bukkit.getGlobalRegionScheduler().runAtFixedRate(NULL_PLUGIN, unused -> {
+ try {
+ update();
+ cleanUp();
+ }catch (Exception e){
+ } catch (Exception e) {
+ logger.error(e.getLocalizedMessage());
+ }
+ }, 1, TpsBarConfig.updateInterval);
+ }
+
+ public static void cancelBarUpdateTask(){
+ if (scannerTask == null || scannerTask.isCancelled()){
+ public static void cancelBarUpdateTask() {
+ if (scannerTask == null || scannerTask.isCancelled()) {
+ return;
+ }
+
@@ -59,15 +58,15 @@
+ }
+ }
+
+ public static boolean isPlayerVisible(Player player){
+ public static boolean isPlayerVisible(Player player) {
+ return ((CraftPlayer) player).getHandle().isTpsBarVisible;
+ }
+
+ public static void setVisibilityForPlayer(Player target,boolean canSee){
+ public static void setVisibilityForPlayer(Player target, boolean canSee) {
+ ((CraftPlayer) target).getHandle().isTpsBarVisible = canSee;
+ }
+
+ private static void update(){
+ private static void update() {
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ scheduledTasks.computeIfAbsent(player.getUniqueId(), unused -> createBossBarForPlayer(player));
+ }
@@ -106,12 +105,12 @@
+
+ BossBar targetBossbar = uuid2Bossbars.computeIfAbsent(
+ playerUUID,
+ unused -> BossBar.bossBar(Component.text(""),0.0F, BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3)), BossBar.Overlay.NOTCHED_20)
+ unused -> BossBar.bossBar(Component.text(""), 0.0F, BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3)), BossBar.Overlay.NOTCHED_20)
+ );
+
+ apiPlayer.showBossBar(targetBossbar);
+
+ if (reportData != null){
+ if (reportData != null) {
+ final TickData.SegmentData tpsData = reportData.tpsData().segmentAll();
+ final double mspt = reportData.timePerTickData().segmentAll().average() / 1.0E6;
+
@@ -126,116 +125,116 @@
+ }, 1, TpsBarConfig.updateInterval);
+ }
+
+ private static void updateTpsBar(double tps, double mspt, @NotNull BossBar bar, @NotNull Player player){
+ private static void updateTpsBar(double tps, double mspt, @NotNull BossBar bar, @NotNull Player player) {
+ bar.name(MiniMessage.miniMessage().deserialize(
+ TpsBarConfig.tpsBarFormat,
+ Placeholder.component("tps",getTpsComponent(tps)),
+ Placeholder.component("mspt",getMsptComponent(mspt)),
+ Placeholder.component("ping",getPingComponent(player.getPing())),
+ Placeholder.component("chunkhot",getChunkHotComponent(player.getNearbyChunkHot()))
+ Placeholder.component("tps", getTpsComponent(tps)),
+ Placeholder.component("mspt", getMsptComponent(mspt)),
+ Placeholder.component("ping", getPingComponent(player.getPing())),
+ Placeholder.component("chunkhot", getChunkHotComponent(player.getNearbyChunkHot()))
+ ));
+ bar.color(barColorFromTps(tps));
+ bar.progress((float) Math.min((float)1,Math.max(mspt / 50,0)));
+ bar.progress((float) Math.min((float) 1, Math.max(mspt / 50, 0)));
+ }
+
+ private static @NotNull Component getPingComponent(int ping){
+ private static @NotNull Component getPingComponent(int ping) {
+ final BossBar.Color colorBukkit = barColorFromPing(ping);
+ final String colorString = colorBukkit.name();
+
+ final String content = "<%s><text></%s>";
+ final String replaced = String.format(content,colorString,colorString);
+ final String replaced = String.format(content, colorString, colorString);
+
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.valueOf(ping)));
+ return MiniMessage.miniMessage().deserialize(replaced, Placeholder.parsed("text", String.valueOf(ping)));
+ }
+
+ private static BossBar.Color barColorFromPing(int ping){
+ if (ping == -1){
+ private static BossBar.Color barColorFromPing(int ping) {
+ if (ping == -1) {
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(3));
+ }
+
+ if (ping <= 80){
+ if (ping <= 80) {
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(0));
+ }
+
+ if (ping <= 160){
+ if (ping <= 160) {
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(1));
+ }
+
+ return BossBar.Color.valueOf(TpsBarConfig.pingColors.get(2));
+ }
+
+ private static @NotNull Component getMsptComponent(double mspt){
+ private static @NotNull Component getMsptComponent(double mspt) {
+ final BossBar.Color colorBukkit = barColorFromMspt(mspt);
+ final String colorString = colorBukkit.name();
+
+ final String content = "<%s><text></%s>";
+ final String replaced = String.format(content,colorString,colorString);
+ final String replaced = String.format(content, colorString, colorString);
+
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", mspt)));
+ return MiniMessage.miniMessage().deserialize(replaced, Placeholder.parsed("text", String.format("%.2f", mspt)));
+ }
+
+ private static @NotNull Component getChunkHotComponent(long chunkHot){
+ private static @NotNull Component getChunkHotComponent(long chunkHot) {
+ final BossBar.Color colorBukkit = barColorFromChunkHot(chunkHot);
+ final String colorString = colorBukkit.name();
+
+ final String content = "<%s><text></%s>";
+ final String replaced = String.format(content,colorString,colorString);
+ final String replaced = String.format(content, colorString, colorString);
+
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.valueOf(chunkHot)));
+ return MiniMessage.miniMessage().deserialize(replaced, Placeholder.parsed("text", String.valueOf(chunkHot)));
+ }
+
+ private static BossBar.Color barColorFromChunkHot(long chunkHot){
+ if (chunkHot == -1){
+ private static BossBar.Color barColorFromChunkHot(long chunkHot) {
+ if (chunkHot == -1) {
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(3));
+ }
+
+ if (chunkHot <= 300000L){
+ if (chunkHot <= 300000L) {
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(0));
+ }
+
+ if (chunkHot <= 500000L){
+ if (chunkHot <= 500000L) {
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(1));
+ }
+
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(2));
+ }
+
+ private static BossBar.Color barColorFromMspt(double mspt){
+ if (mspt == -1){
+ private static BossBar.Color barColorFromMspt(double mspt) {
+ if (mspt == -1) {
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3));
+ }
+
+ if (mspt <= 25){
+ if (mspt <= 25) {
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(0));
+ }
+
+ if (mspt <= 50){
+ if (mspt <= 50) {
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(1));
+ }
+
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(2));
+ }
+
+ private static @NotNull Component getTpsComponent(double tps){
+ private static @NotNull Component getTpsComponent(double tps) {
+ final BossBar.Color colorBukkit = barColorFromTps(tps);
+ final String colorString = colorBukkit.name();
+
+ final String content = "<%s><text></%s>";
+ final String replaced = String.format(content,colorString,colorString);
+ final String replaced = String.format(content, colorString, colorString);
+
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", tps)));
+ return MiniMessage.miniMessage().deserialize(replaced, Placeholder.parsed("text", String.format("%.2f", tps)));
+ }
+
+ private static BossBar.Color barColorFromTps(double tps){
+ if (tps == -1){
+ private static BossBar.Color barColorFromTps(double tps) {
+ if (tps == -1) {
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3));
+ }
+
+ if (tps >= 18){
+ if (tps >= 18) {
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(0));
+ }
+
+ if (tps >= 15){
+ if (tps >= 15) {
+ return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(1));
+ }
+

View File

@@ -9,8 +9,8 @@
+import org.jetbrains.annotations.Nullable;
+
+public enum EnumRegionFormat {
+ MCA("mca", "mca" , (info) -> new RegionFile(info.info(), info.filePath(), info.folder(), info.sync())),
+ LINEAR_V2("linear_v2", "linear" ,(info) -> new LinearRegionFile(info.info(), info.filePath(), info.folder(), info.sync(), RegionFormatConfig.linearCompressionLevel));
+ MCA("mca", "mca", (info) -> new RegionFile(info.info(), info.filePath(), info.folder(), info.sync())),
+ LINEAR_V2("linear_v2", "linear", (info) -> new LinearRegionFile(info.info(), info.filePath(), info.folder(), info.sync(), RegionFormatConfig.linearCompressionLevel));
+
+ private final String name;
+ private final String argument;

View File

@@ -3,27 +3,26 @@
@@ -1,0 +_,152 @@
+package me.earthme.luminol.utils;
+
+import io.papermc.paper.plugin.configuration.PluginMeta;
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
+import org.bukkit.Server;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.generator.BiomeProvider;
+import org.bukkit.generator.ChunkGenerator;
+import org.bukkit.plugin.*;
+import org.bukkit.plugin.PluginBase;
+import org.bukkit.plugin.PluginDescriptionFile;
+import org.bukkit.plugin.PluginLoader;
+import org.bukkit.plugin.PluginLogger;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class NullPlugin extends PluginBase {
+ private boolean enabled = true;
+
+public class NullPlugin extends PluginBase {
+ private final String pluginName;
+ private boolean enabled = true;
+ private PluginDescriptionFile pdf;
+
+ public NullPlugin() {
@@ -31,10 +30,6 @@
+ pdf = new PluginDescriptionFile(pluginName, "1.0", "nms");
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public File getDataFolder() {
+ throw new UnsupportedOperationException("Not supported.");
@@ -44,17 +39,18 @@
+ public PluginDescriptionFile getDescription() {
+ return pdf;
+ }
+
+ // Paper start
+ @Override
+ public io.papermc.paper.plugin.configuration.PluginMeta getPluginMeta() {
+ return pdf;
+ }
+ // Paper end
+
+ @Override
+ public FileConfiguration getConfig() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+ // Paper end
+
+ @Override
+ public InputStream getResource(String filename) {
@@ -101,6 +97,10 @@
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public void onDisable() {
+ throw new UnsupportedOperationException("Not supported.");

View File

@@ -1,10 +1,11 @@
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/utils/RegionCreatorInfo.java
@@ -1,0 +_,7 @@
@@ -1,0 +_,8 @@
+package me.earthme.luminol.utils;
+
+import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
+
+import java.nio.file.Path;
+
+public record RegionCreatorInfo (RegionStorageInfo info, Path filePath, Path folder, boolean sync) {}
+public record RegionCreatorInfo(RegionStorageInfo info, Path filePath, Path folder, boolean sync) {
+}