Compare commits
21 Commits
1.21.4-1fe
...
1.21.4-85f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85ffaa1156 | ||
|
|
6c48c27b7d | ||
|
|
41770b069e | ||
|
|
d4c1790f94 | ||
|
|
4346983b7d | ||
|
|
720e02e944 | ||
|
|
f035a3bd8e | ||
|
|
365a5252a9 | ||
|
|
5746a0e01c | ||
|
|
8bce97d0bb | ||
|
|
8817720b5a | ||
|
|
525b5ccfba | ||
|
|
821c69804d | ||
|
|
cc840886f3 | ||
|
|
70257fa22b | ||
|
|
40242ad8de | ||
|
|
08cf5d6179 | ||
|
|
88eb84f82d | ||
|
|
19745cf033 | ||
|
|
9ba08a6ce6 | ||
|
|
2274af4415 |
4
.github/workflows/build_1.21.4.yml
vendored
4
.github/workflows/build_1.21.4.yml
vendored
@@ -31,6 +31,7 @@ jobs:
|
||||
- name: CreateJar
|
||||
run: ./gradlew createMojmapPaperclipJar
|
||||
- name: Publish to repo
|
||||
if: github.event_name != 'pull_request'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
export MAVEN_REPO_USER=${{ secrets.MAVEN_REPO_USER }}
|
||||
@@ -42,9 +43,10 @@ jobs:
|
||||
name: "${{ env.project_id_b }} CI Artifacts"
|
||||
path: "luminol-server/build/libs/*.jar"
|
||||
- name: SetENV
|
||||
if: github.event_name != 'pull_request'
|
||||
run: sh scripts/SetENV.sh
|
||||
- name: Create Release
|
||||
if: "!contains(github.event.commits[0].message, '[release skip]')"
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: ncipollo/release-action@v1.14.0
|
||||
with:
|
||||
tag: ${{ env.tag }}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,9 +10,8 @@ build
|
||||
/luminol-api/build.gradle.kts
|
||||
/folia-server/build.gradle.kts
|
||||
/folia-server/src/minecraft
|
||||
/paper-server
|
||||
/folia-api/build.gradle.kts
|
||||
/paper-server
|
||||
/paper-api
|
||||
/paper-api-generator
|
||||
|
||||
.idea/
|
||||
|
||||
52
Jenkinsfile
vendored
Normal file
52
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
tools {
|
||||
jdk 'jdk23'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Configure git') {
|
||||
steps {
|
||||
script {
|
||||
sh 'git config user.name "luminolmc"'
|
||||
sh 'git config user.email "luminolmc@noreply.github.com"'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Apply patches') {
|
||||
steps {
|
||||
script {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew applyAllPatches'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build paperclip jar') {
|
||||
steps {
|
||||
script {
|
||||
sh './gradlew createMojmapPaperclipJar'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Upload artifacts') {
|
||||
steps {
|
||||
script {
|
||||
archiveArtifacts(
|
||||
artifacts: "luminol-server/build/libs/*.jar",
|
||||
allowEmptyArchive: false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
要构建一个paperclip jar,你需要运行以下命令。你可以在build/libs中找到jar(注意:需要`JDK21`)
|
||||
|
||||
```shell
|
||||
./gradlew applyPatches && ./gradlew createMojmapPaperclipJar
|
||||
./gradlew applyAllPatches && ./gradlew createMojmapPaperclipJar
|
||||
```
|
||||
|
||||
## 使用API
|
||||
|
||||
@@ -25,7 +25,7 @@ Any versions are available in the [release](https://github.com/LuminolMC/Luminol
|
||||
To build a paperclip jar, you need to run the following command. You can find the jar in build/libs(Note: JDK21 is needed)
|
||||
|
||||
```shell
|
||||
./gradlew applyPatches && ./gradlew createMojmapPaperclipJar
|
||||
./gradlew applyAllPatches && ./gradlew createMojmapPaperclipJar
|
||||
```
|
||||
|
||||
## Using API
|
||||
|
||||
@@ -2,7 +2,7 @@ group = me.earthme.luminol
|
||||
version=1.21.4-R0.1-SNAPSHOT
|
||||
mcVersion=1.21.4
|
||||
|
||||
foliaRef=3af04d9c6a98d24032bf8c99ad5446b0f381e320
|
||||
foliaRef=c2e3759112b527d71b129170bd7713058d3b38b6
|
||||
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.caching=true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Wed, 29 Jan 2025 09:50:53 +0800
|
||||
Date: Tue, 11 Feb 2025 09:16:49 +0800
|
||||
Subject: [PATCH] KioCG Chunk API
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ index d434277342b2db19f98e032d3a316b27d728b840..e188353ad193f6203533790ae52fafc0
|
||||
+ long getChunkHotAvg(); // KioCG
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index dd043851687283f48af899d069d732425c794afd..ac5b7d030cbe3aae908fb2a0130cdf04d4924c18 100644
|
||||
index 0081dd53b6a81ce7892e58d61f9f8a6718e30775..28fbd8df491a4c562de7530e88706e9c88460483 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -3928,4 +3928,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
@@ -3902,4 +3902,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @return the result of this method, holding leftovers and spawned items.
|
||||
*/
|
||||
@NotNull PlayerGiveResult give(@NotNull Collection<@NotNull ItemStack> items, boolean dropIfFull);
|
||||
PlayerGiveResult give(Collection<ItemStack> items, boolean dropIfFull);
|
||||
+
|
||||
+ long getNearbyChunkHot(); // KioCG
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ Subject: [PATCH] Pufferfish SIMD Utilities
|
||||
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f00c008c03e2533f568085838cf13cb9b5b32cd9
|
||||
index 0000000000000000000000000000000000000000..856de1331b15542c00e01990f471fa5152722c11
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDChecker.java
|
||||
@@ -0,0 +1,39 @@
|
||||
@@ -0,0 +1,35 @@
|
||||
+package gg.pufferfish.pufferfish.simd;
|
||||
+
|
||||
+import jdk.incubator.vector.FloatVector;
|
||||
@@ -26,24 +26,20 @@ index 0000000000000000000000000000000000000000..f00c008c03e2533f568085838cf13cb9
|
||||
+ @Deprecated
|
||||
+ public static boolean canEnable(Logger logger) {
|
||||
+ try {
|
||||
+ if (SIMDDetection.getJavaVersion() < 17 || SIMDDetection.getJavaVersion() > 21) {
|
||||
+ SIMDDetection.testRun = true;
|
||||
+
|
||||
+ VectorSpecies<Integer> ISPEC = IntVector.SPECIES_PREFERRED;
|
||||
+ VectorSpecies<Float> FSPEC = FloatVector.SPECIES_PREFERRED;
|
||||
+
|
||||
+ logger.info("Max SIMD vector size on this system is {} bits (int)", ISPEC.vectorBitSize());
|
||||
+ logger.info("Max SIMD vector size on this system is " + FSPEC.vectorBitSize() + " bits (float)");
|
||||
+
|
||||
+ if (ISPEC.elementSize() < 2 || FSPEC.elementSize() < 2) {
|
||||
+ logger.warn("SIMD is not properly supported on this system!");
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ SIMDDetection.testRun = true;
|
||||
+
|
||||
+ VectorSpecies<Integer> ISPEC = IntVector.SPECIES_PREFERRED;
|
||||
+ VectorSpecies<Float> FSPEC = FloatVector.SPECIES_PREFERRED;
|
||||
+
|
||||
+ logger.info("Max SIMD vector size on this system is {} bits (int)", ISPEC.vectorBitSize());
|
||||
+ logger.info("Max SIMD vector size on this system is " + FSPEC.vectorBitSize() + " bits (float)");
|
||||
+
|
||||
+ if (ISPEC.elementSize() < 2 || FSPEC.elementSize() < 2) {
|
||||
+ logger.warn("SIMD is not properly supported on this system!");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ } catch (NoClassDefFoundError | Exception ignored) {} // Basically, we don't do anything. This lets us detect if it's not functional and disable it.
|
||||
+ return false;
|
||||
+ }
|
||||
@@ -51,10 +47,10 @@ index 0000000000000000000000000000000000000000..f00c008c03e2533f568085838cf13cb9
|
||||
+}
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..cd953435a6179eaae7c9cc250a791cae26c5567b
|
||||
index 0000000000000000000000000000000000000000..0a64cd0e88083ac4af6674ad0fb07b771109c737
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/SIMDDetection.java
|
||||
@@ -0,0 +1,35 @@
|
||||
@@ -0,0 +1,34 @@
|
||||
+package gg.pufferfish.pufferfish.simd;
|
||||
+
|
||||
+import org.slf4j.Logger;
|
||||
@@ -63,7 +59,6 @@ index 0000000000000000000000000000000000000000..cd953435a6179eaae7c9cc250a791cae
|
||||
+public class SIMDDetection {
|
||||
+
|
||||
+ public static boolean isEnabled = false;
|
||||
+ public static boolean versionLimited = false;
|
||||
+ public static boolean testRun = false;
|
||||
+
|
||||
+ @Deprecated
|
||||
@@ -90,3 +85,118 @@ index 0000000000000000000000000000000000000000..cd953435a6179eaae7c9cc250a791cae
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/simd/VectorMapPalette.java b/src/main/java/gg/pufferfish/pufferfish/simd/VectorMapPalette.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c26dcaaa2e85882730c854099df80d69eec70f33
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/simd/VectorMapPalette.java
|
||||
@@ -0,0 +1,84 @@
|
||||
+package gg.pufferfish.pufferfish.simd;
|
||||
+
|
||||
+import jdk.incubator.vector.FloatVector;
|
||||
+import jdk.incubator.vector.IntVector;
|
||||
+import jdk.incubator.vector.VectorMask;
|
||||
+import jdk.incubator.vector.VectorSpecies;
|
||||
+import org.bukkit.map.MapPalette;
|
||||
+
|
||||
+import java.awt.*;
|
||||
+
|
||||
+@Deprecated
|
||||
+public class VectorMapPalette {
|
||||
+
|
||||
+ private static final VectorSpecies<Integer> I_SPEC = IntVector.SPECIES_PREFERRED;
|
||||
+ private static final VectorSpecies<Float> F_SPEC = FloatVector.SPECIES_PREFERRED;
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public static void matchColorVectorized(int[] in, byte[] out) {
|
||||
+ int speciesLength = I_SPEC.length();
|
||||
+ int i;
|
||||
+ for (i = 0; i < in.length - speciesLength; i += speciesLength) {
|
||||
+ float[] redsArr = new float[speciesLength];
|
||||
+ float[] bluesArr = new float[speciesLength];
|
||||
+ float[] greensArr = new float[speciesLength];
|
||||
+ int[] alphasArr = new int[speciesLength];
|
||||
+
|
||||
+ for (int j = 0; j < speciesLength; j++) {
|
||||
+ alphasArr[j] = (in[i + j] >> 24) & 0xFF;
|
||||
+ redsArr[j] = (in[i + j] >> 16) & 0xFF;
|
||||
+ greensArr[j] = (in[i + j] >> 8) & 0xFF;
|
||||
+ bluesArr[j] = (in[i + j] >> 0) & 0xFF;
|
||||
+ }
|
||||
+
|
||||
+ IntVector alphas = IntVector.fromArray(I_SPEC, alphasArr, 0);
|
||||
+ FloatVector reds = FloatVector.fromArray(F_SPEC, redsArr, 0);
|
||||
+ FloatVector greens = FloatVector.fromArray(F_SPEC, greensArr, 0);
|
||||
+ FloatVector blues = FloatVector.fromArray(F_SPEC, bluesArr, 0);
|
||||
+ IntVector resultIndex = IntVector.zero(I_SPEC);
|
||||
+ VectorMask<Integer> modificationMask = VectorMask.fromLong(I_SPEC, 0xffffffff);
|
||||
+
|
||||
+ modificationMask = modificationMask.and(alphas.lt(128).not());
|
||||
+ FloatVector bestDistances = FloatVector.broadcast(F_SPEC, Float.MAX_VALUE);
|
||||
+
|
||||
+ for (int c = 4; c < MapPalette.colors.length; c++) {
|
||||
+ // We're using 32-bit floats here because it's 2x faster and nobody will know the difference.
|
||||
+ // For correctness, the original algorithm uses 64-bit floats instead. Completely unnecessary.
|
||||
+ FloatVector compReds = FloatVector.broadcast(F_SPEC, MapPalette.colors[c].getRed());
|
||||
+ FloatVector compGreens = FloatVector.broadcast(F_SPEC, MapPalette.colors[c].getGreen());
|
||||
+ FloatVector compBlues = FloatVector.broadcast(F_SPEC, MapPalette.colors[c].getBlue());
|
||||
+
|
||||
+ FloatVector rMean = reds.add(compReds).div(2.0f);
|
||||
+ FloatVector rDiff = reds.sub(compReds);
|
||||
+ FloatVector gDiff = greens.sub(compGreens);
|
||||
+ FloatVector bDiff = blues.sub(compBlues);
|
||||
+
|
||||
+ FloatVector weightR = rMean.div(256.0f).add(2);
|
||||
+ FloatVector weightG = FloatVector.broadcast(F_SPEC, 4.0f);
|
||||
+ FloatVector weightB = FloatVector.broadcast(F_SPEC, 255.0f).sub(rMean).div(256.0f).add(2.0f);
|
||||
+
|
||||
+ FloatVector distance = weightR.mul(rDiff).mul(rDiff).add(weightG.mul(gDiff).mul(gDiff)).add(weightB.mul(bDiff).mul(bDiff));
|
||||
+
|
||||
+ // Now we compare to the best distance we've found.
|
||||
+ // This mask contains a "1" if better, and a "0" otherwise.
|
||||
+ VectorMask<Float> bestDistanceMask = distance.lt(bestDistances);
|
||||
+ bestDistances = bestDistances.blend(distance, bestDistanceMask); // Update the best distances
|
||||
+
|
||||
+ // Update the result array
|
||||
+ // We also AND with the modification mask because we don't want to interfere if the alpha value isn't large enough.
|
||||
+ resultIndex = resultIndex.blend(c, bestDistanceMask.cast(I_SPEC).and(modificationMask)); // Update the results
|
||||
+ }
|
||||
+
|
||||
+ for (int j = 0; j < speciesLength; j++) {
|
||||
+ int index = resultIndex.lane(j);
|
||||
+ out[i + j] = (byte) (index < 128 ? index : -129 + (index - 127));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // For the final ones, fall back to the regular method
|
||||
+ for (; i < in.length; i++) {
|
||||
+ out[i] = MapPalette.matchColor(new Color(in[i], true));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/map/MapPalette.java b/src/main/java/org/bukkit/map/MapPalette.java
|
||||
index 6995f9cc08d162e3adcd3a28f6bfa6d329661999..83ea70a16b4090a8c628784f2807cd16e7065103 100644
|
||||
--- a/src/main/java/org/bukkit/map/MapPalette.java
|
||||
+++ b/src/main/java/org/bukkit/map/MapPalette.java
|
||||
@@ -45,7 +45,7 @@ public final class MapPalette {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
- static final Color[] colors = {
|
||||
+ public static final Color[] colors = { // Luminol - package-private -> public
|
||||
c(0, 0, 0, 0), c(0, 0, 0, 0), c(0, 0, 0, 0), c(0, 0, 0, 0),
|
||||
c(89, 125, 39), c(109, 153, 48), c(127, 178, 56), c(67, 94, 29),
|
||||
c(174, 164, 115), c(213, 201, 140), c(247, 233, 163), c(130, 123, 86),
|
||||
@@ -216,9 +216,11 @@ public final class MapPalette {
|
||||
temp.getRGB(0, 0, temp.getWidth(), temp.getHeight(), pixels, 0, temp.getWidth());
|
||||
|
||||
byte[] result = new byte[temp.getWidth() * temp.getHeight()];
|
||||
+ if ((mapColorCache != null && mapColorCache.isCached()) || !gg.pufferfish.pufferfish.simd.SIMDDetection.isEnabled) { // Luminol - Pufferfish - vectorized map color conversion
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
result[i] = matchColor(new Color(pixels[i], true));
|
||||
}
|
||||
+ } else gg.pufferfish.pufferfish.simd.VectorMapPalette.matchColorVectorized(pixels, result); // Luminol - Pufferfish - vectorized map color conversion
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,10 +186,10 @@ index 0000000000000000000000000000000000000000..ecde4462b08d701b8bff9f26902f1775
|
||||
+ RegionStats getRegionStats();
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 8784842d14bbbe7dbde181e86782a0955be66924..f998f6f0d3017767aa4dde45a7e8aea5dd36fe99 100644
|
||||
index 2729f71ac5525b7669fb7cc8719a75e5ce8d1dfc..9020f0781b399484e2acf0ad139b0b364e1c7a8f 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -4407,4 +4407,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
@@ -4409,4 +4409,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
implementation("ca.spottedleaf:concurrentutil:0.0.3")
|
||||
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
|
||||
implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21
|
||||
@@ -200,6 +_,13 @@
|
||||
@@ -200,26 +_,33 @@
|
||||
implementation("me.lucko:spark-paper:1.10.119-SNAPSHOT")
|
||||
}
|
||||
|
||||
@@ -81,7 +81,13 @@
|
||||
tasks.jar {
|
||||
manifest {
|
||||
val git = Git(rootProject.layout.projectDirectory.path)
|
||||
@@ -212,14 +_,14 @@
|
||||
val mcVersion = rootProject.providers.gradleProperty("mcVersion").get()
|
||||
val build = System.getenv("BUILD_NUMBER") ?: null
|
||||
- val buildTime = if (build != null) Instant.now() else Instant.EPOCH
|
||||
+ val buildTime = Instant.now() // We don't have ci yet
|
||||
val gitHash = git.exec(providers, "rev-parse", "--short=7", "HEAD").get().trim()
|
||||
val implementationVersion = "$mcVersion-${build ?: "DEV"}-$gitHash"
|
||||
val date = git.exec(providers, "show", "-s", "--format=%ci", gitHash).get().trim()
|
||||
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim()
|
||||
attributes(
|
||||
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:15:52 +0800
|
||||
Subject: [PATCH] Add luminol config framework
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
|
||||
index 9aa664537cc37e44db46d5a2a64ae3116938c681..8d6a6534a134e99e5ee2652d7b0c858d538e69bd 100644
|
||||
--- a/net/minecraft/server/Main.java
|
||||
+++ b/net/minecraft/server/Main.java
|
||||
@@ -108,6 +108,7 @@ public class Main {
|
||||
JvmProfiler.INSTANCE.start(Environment.SERVER);
|
||||
}
|
||||
|
||||
+ me.earthme.luminol.config.LuminolConfig.preLoadConfig(); // Luminol - Luminol config
|
||||
io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper
|
||||
Bootstrap.bootStrap();
|
||||
Bootstrap.validate();
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 341e400f789e0eda29827e2c45c483a470d2e982..8f348d140ab98e23ee0debe4bacac51fee49c35e 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -212,6 +212,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
|
||||
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
||||
// Paper end - initialize global and world-defaults configuration
|
||||
+ me.earthme.luminol.config.LuminolConfig.finalizeLoadConfig(); //Luminol - load config file
|
||||
+ me.earthme.luminol.config.LuminolConfig.setupLatch(); //Luminol - load config file
|
||||
this.server.spark.enableEarlyIfRequested(); // Paper - spark
|
||||
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
|
||||
if (this.convertOldUsers()) {
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] Add config for vanilla random
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 597520a680bc1a54055b99f93724682a4d940458..4cfc228a60a147409b8afc4cb138ce6437a9b667 100644
|
||||
index 1e59c21d26baf50fd74bc99c04dbea0faede446a..26637b397b06c14445740a733d378a38a85e1875 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -255,7 +255,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 11:29:49 +0800
|
||||
Subject: [PATCH] KioCG Chunk API and display of chunkhot in tpsbar
|
||||
Date: Sun, 12 Jan 2025 10:27:31 +0800
|
||||
Subject: [PATCH] Add tpsbar with chunkhot membar and regionbar
|
||||
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
|
||||
@@ -17,10 +17,10 @@ index 8d67b4629c69d3039b199aaad45533d1acde114e..f7bfeca4b11b9860241d5eb80b6df420
|
||||
((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
|
||||
}
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index ff71466ec0848d16121e351e30c31bb419af8b99..330af9f4de1c72387326816065350e71fe546efe 100644
|
||||
index 46375fa81b36b89b79c22f0a7ac6d610ab1183d4..f2124edb487b1d5f6bdc7fa086814f870724363a 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1666,7 +1666,44 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1665,7 +1665,44 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Folia end - region threading
|
||||
//this.tickCount++; // Folia - region threading
|
||||
//this.tickRateManager.tick(); // Folia - region threading
|
||||
@@ -65,11 +65,25 @@ index ff71466ec0848d16121e351e30c31bb419af8b99..330af9f4de1c72387326816065350e71
|
||||
if (false && nanos - this.lastServerStatus >= STATUS_EXPIRE_TIME_NANOS) { // Folia - region threading
|
||||
this.lastServerStatus = nanos;
|
||||
this.status = this.buildServerStatus();
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 8f348d140ab98e23ee0debe4bacac51fee49c35e..c6490516215ad94323174de81771f258cecc7742 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -764,6 +764,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
|
||||
@Override
|
||||
public void stopServer() {
|
||||
+ me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
|
||||
+ me.earthme.luminol.functions.GlobalServerMemoryBar.cancelBarUpdateTask(); //Luminol - Memory bar
|
||||
+ me.earthme.luminol.functions.GlobalServerRegionBar.cancelBarUpdateTask(); //Luminol - Region bar
|
||||
super.stopServer();
|
||||
//Util.shutdownExecutors(); // Paper - Improved watchdog support; moved into super
|
||||
SkullBlockEntity.clear();
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b14d6f62f 100644
|
||||
index 7fb6cfe0484a4cc1e30fd8e344de307a0c734b68..f2d0d8c7577ea5d798b6a2cf8fd6282cead9de94 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1347,6 +1347,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -1339,6 +1339,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
final int timerId = isActive ? entity.getType().tickTimerId : entity.getType().inactiveTickTimerId;
|
||||
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
|
||||
profiler.startTimer(timerId);
|
||||
@@ -78,7 +92,7 @@ index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b
|
||||
try {
|
||||
// Folia end - profiler
|
||||
if (isActive) { // Paper - EAR 2
|
||||
@@ -1364,6 +1366,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -1356,6 +1358,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
} else {entity.inactiveTick();} // Paper - EAR 2
|
||||
profilerFiller.pop();
|
||||
} finally { profiler.stopTimer(timerId); } // Folia - profiler
|
||||
@@ -86,7 +100,7 @@ index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b
|
||||
|
||||
for (Entity entity1 : entity.getPassengers()) {
|
||||
this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
|
||||
@@ -1383,6 +1386,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -1375,6 +1378,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
final int timerId = isActive ? passengerEntity.getType().tickTimerId : passengerEntity.getType().inactiveTickTimerId;
|
||||
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
|
||||
profiler.startTimer(timerId);
|
||||
@@ -95,7 +109,7 @@ index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b
|
||||
try {
|
||||
// Folia end - profiler
|
||||
passengerEntity.setOldPosAndRot();
|
||||
@@ -1416,6 +1421,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -1409,6 +1414,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.tickPassenger(passengerEntity, entity, isActive); // Paper - EAR 2
|
||||
}
|
||||
} finally { profiler.stopTimer(timerId); } // Folia - profiler
|
||||
@@ -104,10 +118,21 @@ index ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8..887a12b0b33a24f77e3dc118688f9e5b
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index f1239f1a7b6b8fd958333df8092359eea7197fc0..9fd3fe181df2ce6dbe695f6463d3940ac4c01167 100644
|
||||
index 423534a1ff02bd0d0f9baacfe2428f45c7d9acb9..9fd3fe181df2ce6dbe695f6463d3940ac4c01167 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1008,7 +1008,34 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -393,7 +393,9 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
|
||||
public @Nullable String clientBrandName = null; // Paper - Brand support
|
||||
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
|
||||
-
|
||||
+ public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
|
||||
+ public volatile boolean isMemBarVisible = false; //Luminol - Memory bar
|
||||
+ public volatile boolean isRegionBarVisible = false; //Luminol - Region bar
|
||||
// Paper start - rewrite chunk system
|
||||
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
||||
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();
|
||||
@@ -1006,8 +1008,35 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
this.trackEnteredOrExitedLavaOnVehicle();
|
||||
this.updatePlayerAttributes();
|
||||
this.advancements.flushDirty(this);
|
||||
@@ -117,8 +142,8 @@ index f1239f1a7b6b8fd958333df8092359eea7197fc0..9fd3fe181df2ce6dbe695f6463d3940a
|
||||
+ this.nearbyChunkHot = this.refreshNearbyChunkHot();
|
||||
+ }
|
||||
+ // KioCG end
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ // KioCG start - ChunkHot
|
||||
+ private volatile long nearbyChunkHot = 0;
|
||||
+
|
||||
@@ -136,12 +161,13 @@ index f1239f1a7b6b8fd958333df8092359eea7197fc0..9fd3fe181df2ce6dbe695f6463d3940a
|
||||
+ }
|
||||
+ }
|
||||
+ return total;
|
||||
}
|
||||
+ }
|
||||
+ // KioCG end
|
||||
+
|
||||
|
||||
+
|
||||
private void updatePlayerAttributes() {
|
||||
AttributeInstance attribute = this.getAttribute(Attributes.BLOCK_INTERACTION_RANGE);
|
||||
if (attribute != null) {
|
||||
diff --git a/net/minecraft/world/entity/AreaEffectCloud.java b/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
index 23b342cc31c7e72ade0e1ccad86a9ccf34380f13..249cb7326c8e4012dcffdb6bbb7bfc1f1eeb7b33 100644
|
||||
--- a/net/minecraft/world/entity/AreaEffectCloud.java
|
||||
@@ -159,10 +185,10 @@ index 23b342cc31c7e72ade0e1ccad86a9ccf34380f13..249cb7326c8e4012dcffdb6bbb7bfc1f
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 5979893976ab8c59a17e306cd91c9a4f5cd3738e..4f0ea00cd601c62926220400c8e3597815dc4d15 100644
|
||||
index 26637b397b06c14445740a733d378a38a85e1875..0a7d6172d42f4b0395aa448b1c1d9fb8eaa4bf7a 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -5967,4 +5967,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -5919,4 +5919,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
return ((ServerLevel) this.level).isPositionEntityTicking(this.blockPosition());
|
||||
}
|
||||
// Paper end - Expose entity id counter
|
||||
@@ -234,10 +260,10 @@ index 6655d06e2011e20e7346dfe57527795269094d8a..48aa6fcb5c16fdbb4ae902cbb72c6b8e
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 7635b16cf82577a4822a5057aa5319d4c23e2168..0e020dfebe06dce4c19beb10c961ea9e8a35a415 100644
|
||||
index e70919757dee4b02384ded3551c8f580d289584a..ae049c5c3593525b991d865fec695c00ad408a59 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1544,6 +1544,13 @@ public abstract class Player extends LivingEntity {
|
||||
@@ -1546,6 +1546,13 @@ public abstract class Player extends LivingEntity {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:27:31 +0800
|
||||
Subject: [PATCH] Add a simple tpsbar
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 8f348d140ab98e23ee0debe4bacac51fee49c35e..852d598fc11a9640a20b093839707c3a5a96e057 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -764,6 +764,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
|
||||
@Override
|
||||
public void stopServer() {
|
||||
+ me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
|
||||
super.stopServer();
|
||||
//Util.shutdownExecutors(); // Paper - Improved watchdog support; moved into super
|
||||
SkullBlockEntity.clear();
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index ca3770e9f77e583dfa6cef8ca884eaf6a43f5ffa..465f20e5f24a8b37fb31393bcedd3807896666c7 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -393,7 +393,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
|
||||
public @Nullable String clientBrandName = null; // Paper - Brand support
|
||||
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
|
||||
-
|
||||
+ public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
|
||||
// Paper start - rewrite chunk system
|
||||
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
||||
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:28:03 +0800
|
||||
Subject: [PATCH] Add a simple membar
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 852d598fc11a9640a20b093839707c3a5a96e057..cc80198a5d5f4e9188ef35944d077200f03ac43b 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -765,6 +765,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
@Override
|
||||
public void stopServer() {
|
||||
me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
|
||||
+ me.earthme.luminol.functions.GlobalServerMemoryBar.cancelBarUpdateTask(); //Luminol - Memory bar
|
||||
super.stopServer();
|
||||
//Util.shutdownExecutors(); // Paper - Improved watchdog support; moved into super
|
||||
SkullBlockEntity.clear();
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 465f20e5f24a8b37fb31393bcedd3807896666c7..b4a4eec6029f1aee5f3b0da6938a9b23db36d5f9 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -394,6 +394,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
public @Nullable String clientBrandName = null; // Paper - Brand support
|
||||
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
|
||||
public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
|
||||
+ public volatile boolean isMemBarVisible = false; //Luminol - Memory bar
|
||||
// Paper start - rewrite chunk system
|
||||
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
||||
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: adabugra <57899270+adabugra@users.noreply.github.com>
|
||||
Date: Fri, 31 Jan 2025 01:21:44 +0300
|
||||
Subject: [PATCH] Add a simple regionbar
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index cc80198a5d5f4e9188ef35944d077200f03ac43b..c6490516215ad94323174de81771f258cecc7742 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -766,6 +766,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
public void stopServer() {
|
||||
me.earthme.luminol.functions.GlobalServerTpsBar.cancelBarUpdateTask(); //Luminol - Tpsbar
|
||||
me.earthme.luminol.functions.GlobalServerMemoryBar.cancelBarUpdateTask(); //Luminol - Memory bar
|
||||
+ me.earthme.luminol.functions.GlobalServerRegionBar.cancelBarUpdateTask(); //Luminol - Region bar
|
||||
super.stopServer();
|
||||
//Util.shutdownExecutors(); // Paper - Improved watchdog support; moved into super
|
||||
SkullBlockEntity.clear();
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index a07e02132bdda2693686440b9932992641cb6957..f1239f1a7b6b8fd958333df8092359eea7197fc0 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -395,6 +395,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
|
||||
public volatile boolean isTpsBarVisible = false; //Luminol - Tps bar
|
||||
public volatile boolean isMemBarVisible = false; //Luminol - Memory bar
|
||||
+ public volatile boolean isRegionBarVisible = false; //Luminol - Region bar
|
||||
// Paper start - rewrite chunk system
|
||||
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
||||
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();
|
||||
@@ -17,16 +17,3 @@ index 41a9cc693183e96c83837692e93b177a521d6789..f4a2d1a2d467808b9cb75fc32765ddc2
|
||||
throw new ProfilePublicKey.ValidationException(INVALID_SIGNATURE, org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PUBLIC_KEY_SIGNATURE); // Paper - kick event causes
|
||||
} else {
|
||||
return new ProfilePublicKey(data);
|
||||
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
index 6a7e5a642e2eaf7d5dffadb81738f7385a38c0af..f16500a50904aade3d984b908b11b8edd9c05ba1 100644
|
||||
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
@@ -215,7 +215,7 @@ public class TripWireHookBlock extends Block {
|
||||
BlockState blockState2 = blockStates[i2];
|
||||
if (blockState2 != null) {
|
||||
BlockState blockState3 = level.getBlockState(blockPos1);
|
||||
- if (blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) {
|
||||
+ if (me.earthme.luminol.config.modules.misc.TripwireConfig.enabled || blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) { // Luminol - Add config for tripwire dupe
|
||||
level.setBlock(blockPos1, blockState2.trySetValue(ATTACHED, Boolean.valueOf(flag2)), 3);
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ index 51c126735ace8fdde89ad97b5cab62f244212db0..c7d4d944eb198ac53a3eeae717a25c7d
|
||||
+ public void moonrise$write(final abomination.IRegionFile regionFile) throws IOException; // Luminol - Configurable region file format
|
||||
}
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 46375fa81b36b89b79c22f0a7ac6d610ab1183d4..c00378ba258647787bb9138e319b0f6a0b00e1ed 100644
|
||||
index f2124edb487b1d5f6bdc7fa086814f870724363a..ed00a29daccfee1d631bef27c0a3a4ae83140018 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -986,10 +986,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Teleport async if entity was moving to another region at once
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index c9730114f1d5dc1ecd6a38dbc7e5e936065dd92b..1868cb351d030d1997b5c81a184657085261c2f3 100644
|
||||
index 0a7d6172d42f4b0395aa448b1c1d9fb8eaa4bf7a..b5a535cbcf592ef210981334128365ff5bc68e92 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -1099,6 +1099,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -1100,6 +1100,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
// Paper end - detailed watchdog information
|
||||
|
||||
@@ -19,7 +19,7 @@ index c9730114f1d5dc1ecd6a38dbc7e5e936065dd92b..1868cb351d030d1997b5c81a18465708
|
||||
public void move(MoverType type, Vec3 movement) {
|
||||
final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
|
||||
// Paper start - detailed watchdog information
|
||||
@@ -1109,6 +1113,32 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -1110,6 +1114,32 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
this.moveStartZ = this.getZ();
|
||||
this.moveVector = movement;
|
||||
}
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] Force disable builtin spark plugin
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index c00378ba258647787bb9138e319b0f6a0b00e1ed..ff71466ec0848d16121e351e30c31bb419af8b99 100644
|
||||
index ed00a29daccfee1d631bef27c0a3a4ae83140018..330af9f4de1c72387326816065350e71fe546efe 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -783,8 +783,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -65,7 +65,7 @@ index c00378ba258647787bb9138e319b0f6a0b00e1ed..ff71466ec0848d16121e351e30c31bb4
|
||||
new com.destroystokyo.paper.event.server.ServerTickStartEvent((int)region.getCurrentTick()).callEvent(); // Paper - Server Tick Events // Folia - region threading
|
||||
// Folia start - region threading
|
||||
if (region != null) {
|
||||
@@ -1706,7 +1707,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1743,7 +1744,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
long remaining = scheduledEnd - endTime; // Folia - region ticking
|
||||
new com.destroystokyo.paper.event.server.ServerTickEndEvent((int)io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick(), ((double)(endTime - startTime) / 1000000D), remaining).callEvent(); // Folia - region ticking
|
||||
// Paper end - Server Tick Events
|
||||
@@ -13,10 +13,10 @@ Related to mojang's bug fix:
|
||||
https://bugs.mojang.com/browse/MC-92875
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index aa4337942b4b9b7dd746b9b9c5a052d626b1e72c..61814607a6c8e4ce8d07645f005ea8d53f624c95 100644
|
||||
index b5a535cbcf592ef210981334128365ff5bc68e92..477b71c94461ab504b3955437d0f7acb312ed33f 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -1675,6 +1675,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -1676,6 +1676,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 11 Feb 2025 13:34:47 +0800
|
||||
Subject: [PATCH] Fix uncorrected death check of folia
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 50af953a4698a3c6e16b840fab764dd733b3fbc9..a9c058238819f3631d94ac306185e909821caf35 100644
|
||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -679,7 +679,7 @@ public abstract class AbstractContainerMenu {
|
||||
}
|
||||
|
||||
private static void dropOrPlaceInInventory(Player player, ItemStack stack) {
|
||||
- boolean flag = player.isRemoved() && player.getRemovalReason() != Entity.RemovalReason.CHANGED_DIMENSION;
|
||||
+ boolean flag = !player.isAlive(); //player.isRemoved() && player.getRemovalReason() != Entity.RemovalReason.CHANGED_DIMENSION; // Luminol - Fix uncorrected death check of folia
|
||||
boolean flag1 = player instanceof ServerPlayer serverPlayer && serverPlayer.hasDisconnected();
|
||||
if (flag || flag1) {
|
||||
player.drop(stack, false);
|
||||
@@ -5,24 +5,16 @@ Subject: [PATCH] Kaiiju Vanilla end portal teleportation
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 61814607a6c8e4ce8d07645f005ea8d53f624c95..5979893976ab8c59a17e306cd91c9a4f5cd3738e 100644
|
||||
index 477b71c94461ab504b3955437d0f7acb312ed33f..35e413b7b2f8465946b2cc8651560c6899898458 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -110,6 +110,7 @@ import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.border.WorldBorder;
|
||||
+import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.entity.EntityAccess;
|
||||
import net.minecraft.world.level.entity.EntityInLevelCallback;
|
||||
import net.minecraft.world.level.gameevent.DynamicGameEventListener;
|
||||
@@ -4280,13 +4281,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -4281,14 +4281,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
targetPos, 16, // load 16 blocks to be safe from block physics
|
||||
ca.spottedleaf.concurrentutil.util.Priority.HIGH,
|
||||
(chunks) -> {
|
||||
- net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, targetPos.below(), true, null);
|
||||
-
|
||||
+ //net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, targetPos.below(), true, null); // Kaiiju - Vanilla end teleportation - moved down
|
||||
|
||||
+ // Kaiiju start - Vanilla end teleportation
|
||||
+ Vec3 finalPos;
|
||||
+ if (this instanceof Player) finalPos = Vec3.atBottomCenterOf(targetPos.below());
|
||||
@@ -32,23 +24,43 @@ index 61814607a6c8e4ce8d07645f005ea8d53f624c95..5979893976ab8c59a17e306cd91c9a4f
|
||||
// on the obsidian, we need to spawn at targetPos.y - 1
|
||||
portalInfoCompletable.complete(
|
||||
new net.minecraft.world.level.portal.TeleportTransition(
|
||||
- destination, Vec3.atBottomCenterOf(targetPos.below()), Vec3.ZERO, 90.0f, 0.0f,
|
||||
+ destination, finalPos, this.getDeltaMovement(), 90.0f, 0.0f, // Kaiiju - Vanilla end teleportation
|
||||
- destination, Vec3.atBottomCenterOf(targetPos.below()), Vec3.ZERO, Direction.WEST.toYRot(), 0.0f,
|
||||
- Relative.union(Relative.DELTA, Set.of(Relative.X_ROT)),
|
||||
+ destination, finalPos, this.getDeltaMovement(), Direction.WEST.toYRot(), 0.0f, // Kaiiju - Vanilla end teleportation
|
||||
+ //Relative.union(Relative.DELTA, Set.of(Relative.X_ROT)), // Kaiiju - Vanilla end teleportation
|
||||
TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET),
|
||||
org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL
|
||||
)
|
||||
@@ -4482,6 +4488,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -4303,11 +4307,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
ca.spottedleaf.concurrentutil.util.Priority.HIGH,
|
||||
(chunks) -> {
|
||||
BlockPos adjustedSpawn = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, spawnPos);
|
||||
-
|
||||
+ // Kaiiju start - Vanilla end teleportation
|
||||
+ Vec3 finalPos;
|
||||
+ if (this instanceof Player) finalPos = Vec3.atBottomCenterOf(adjustedSpawn.below());
|
||||
+ else finalPos = Vec3.atBottomCenterOf(adjustedSpawn);
|
||||
+ // Kaiiju end
|
||||
// done
|
||||
portalInfoCompletable.complete(
|
||||
new net.minecraft.world.level.portal.TeleportTransition(
|
||||
- destination, Vec3.atBottomCenterOf(adjustedSpawn), Vec3.ZERO, 0.0f, 0.0f,
|
||||
+ destination, finalPos, this.getDeltaMovement(), 0.0f, 0.0f, // Kaiiju - Vanilla end teleportation
|
||||
Relative.union(Relative.DELTA, Relative.ROTATION),
|
||||
TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET),
|
||||
org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL
|
||||
@@ -4485,6 +4493,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
if (!this.canPortalAsync(destination, takePassengers)) {
|
||||
return false;
|
||||
}
|
||||
+ // Kaiiju start - sync end platform spawning & entity teleportation
|
||||
+ final java.util.function.Consumer<Entity> tpComplete = type == PortalType.END && destination.getTypeKey() == LevelStem.END ?
|
||||
+ final java.util.function.Consumer<Entity> tpComplete = type == PortalType.END && destination.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END ?
|
||||
+ e -> net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, ServerLevel.END_SPAWN_POINT.below(), true, null) : teleportComplete;
|
||||
+ // Kaiiju end
|
||||
|
||||
Vec3 initialPosition = this.position();
|
||||
ChunkPos initialPositionChunk = new ChunkPos(
|
||||
@@ -4546,9 +4556,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -4549,9 +4561,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
info.postTeleportTransition().onTransition(teleported);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ index c6e487a4c14e6b82533881d01f32349b9ae28728..2c747cb8a724cd25c9d724908f92b320
|
||||
// block ticking
|
||||
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>();
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index d34ad333b6ea3855a24a58fcd80ccf19b2bbf41c..ad121d609bcc1d9b53a1a20d4e25cf9dfa480fb8 100644
|
||||
index f2d0d8c7577ea5d798b6a2cf8fd6282cead9de94..c768279df8551498a61d29630f4374f1054a2d8b 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -808,6 +808,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -18,7 +18,7 @@ index c260741a87513b89a5cc62c543fb9f990f86491e..beb9b3b3cd5ca60bd2cdada937bff8a1
|
||||
}
|
||||
if (entity instanceof final Mob mob && mob.getTarget() != null) {
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index d50aef6307fb854c8d4f66bb622cdafc43dce0ae..b6c820ebdc42edc1f3ce5c18eee5bff2e3822437 100644
|
||||
index 3e31fc5fcc15a139bc8d3eb91e89b0f4e28d7eea..4615c052d4ac75e17bfea39fd0b19cdad35c9ecf 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -2044,6 +2044,20 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] Gale Skip entity move if movement is zero
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 4f0ea00cd601c62926220400c8e3597815dc4d15..a826320496a7a211cc07518adedfec9bdf8728b8 100644
|
||||
index 35e413b7b2f8465946b2cc8651560c6899898458..59dd6ecc3b79b1d6c13eda7b71d6dbbf4ffc1dfe 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -1104,7 +1104,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -23,7 +23,7 @@ index 4f0ea00cd601c62926220400c8e3597815dc4d15..a826320496a7a211cc07518adedfec9b
|
||||
final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
|
||||
// Paper start - detailed watchdog information
|
||||
ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main");
|
||||
@@ -5046,6 +5053,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -5051,6 +5058,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
public final void setBoundingBox(AABB bb) {
|
||||
@@ -62,7 +62,7 @@ index ac06b8a4813716a8d136be5731cbd96113976a7e..82d95005fc67336458b50c47d44ec404
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 887a12b0b33a24f77e3dc118688f9e5b14d6f62f..12f6c929c0168ea5b3242ff7139f1eac8b4e3a4b 100644
|
||||
index c768279df8551498a61d29630f4374f1054a2d8b..31a1e2d9287654418563f4cb97a17bca42d17e64 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -620,6 +620,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -19,7 +19,7 @@ index 9fd3fe181df2ce6dbe695f6463d3940ac4c01167..822d401150d3764004b2570da828b4f6
|
||||
);
|
||||
});
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e8f0644c4 100644
|
||||
index 59dd6ecc3b79b1d6c13eda7b71d6dbbf4ffc1dfe..f26cdc00180f72bea271877b9ef814daf9850916 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -4166,6 +4166,31 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -94,7 +94,7 @@ index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e
|
||||
// need to load chunk for heightmap
|
||||
destination.moonrise$loadChunksAsync(
|
||||
spawnPos, 0,
|
||||
@@ -4357,8 +4404,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -4362,8 +4409,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
|
||||
WorldBorder destinationBorder = destination.getWorldBorder();
|
||||
double dimensionScale = net.minecraft.world.level.dimension.DimensionType.getTeleportationScale(origin.dimensionType(), destination.dimensionType());
|
||||
@@ -114,7 +114,7 @@ index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e
|
||||
ca.spottedleaf.concurrentutil.completable.CallbackCompletable<BlockUtil.FoundRectangle> portalFound
|
||||
= new ca.spottedleaf.concurrentutil.completable.CallbackCompletable<>();
|
||||
|
||||
@@ -4495,9 +4552,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -4500,9 +4557,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
if (!this.canPortalAsync(destination, takePassengers)) {
|
||||
return false;
|
||||
}
|
||||
@@ -128,13 +128,13 @@ index a826320496a7a211cc07518adedfec9bdf8728b8..6f9cfd8c72853d9cb30c9731a96e7f1e
|
||||
+ }
|
||||
+ // Luminol end
|
||||
// Kaiiju start - sync end platform spawning & entity teleportation
|
||||
final java.util.function.Consumer<Entity> tpComplete = type == PortalType.END && destination.getTypeKey() == LevelStem.END ?
|
||||
final java.util.function.Consumer<Entity> tpComplete = type == PortalType.END && destination.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END ?
|
||||
- e -> net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, ServerLevel.END_SPAWN_POINT.below(), true, null) : teleportComplete;
|
||||
+ e -> { if (new me.earthme.luminol.api.portal.EndPlatformCreateEvent().callEvent() && ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(e.level, ServerLevel.END_SPAWN_POINT.below())) net.minecraft.world.level.levelgen.feature.EndPlatformFeature.createEndPlatform(destination, ServerLevel.END_SPAWN_POINT.below(), true, null); } : teleportComplete; // Luminol - Add missing teleportation events & Fix teleportation api threading issue
|
||||
// Kaiiju end
|
||||
|
||||
Vec3 initialPosition = this.position();
|
||||
@@ -4571,6 +4637,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -4576,6 +4642,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
tpComplete.accept(teleported);
|
||||
}
|
||||
// Kaiiju end
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] Leaves Disable moved wrongly threshold
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 8c822dffc114b6aa6ddf2443606a1f9dc9262c45..60d8e9aca76614ca4ed235e96e0e9867a40e8bf5 100644
|
||||
index 1f031366afa973fa3ed027505d149737febd169e..8e98b034f968850c4bbf3c9d6ac468511f3ba06b 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -579,7 +579,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -0,0 +1,37 @@
|
||||
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
|
||||
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
|
||||
index 471b6d49d77e03665ffc269d17ab46f225e3ce1c..c574f9a23868a35ef694e432ba581d2f00e39da7 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 &&
|
||||
@@ -2026,7 +2034,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;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ Subject: [PATCH] Raytracing tracker experiment
|
||||
|
||||
Based on the framework of EntityCulling(((((((
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
||||
index 7eff847790394aecd058e7a61905da86163b4c6e..9099457f55a2829297ac1db8a69a98ff717d9a86 100644
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -20,10 +19,10 @@ index 7eff847790394aecd058e7a61905da86163b4c6e..9099457f55a2829297ac1db8a69a98ff
|
||||
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||
if (rangeY != -1) {
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 6f9cfd8c72853d9cb30c9731a96e7f1e8f0644c4..b1ded501047f75d2e7af775bf8866fd6a5400a91 100644
|
||||
index f26cdc00180f72bea271877b9ef814daf9850916..647510b9fae49b5a4113a35be9909babf54acfcf 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -136,7 +136,7 @@ import net.minecraft.world.scores.ScoreHolder;
|
||||
@@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder;
|
||||
import net.minecraft.world.scores.Team;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -32,7 +31,7 @@ index 6f9cfd8c72853d9cb30c9731a96e7f1e8f0644c4..b1ded501047f75d2e7af775bf8866fd6
|
||||
|
||||
// CraftBukkit start
|
||||
private static final int CURRENT_LEVEL = 2;
|
||||
@@ -6050,4 +6050,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -6055,4 +6055,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
// Paper end - Expose entity id counter
|
||||
|
||||
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
|
||||
@@ -94,7 +93,7 @@ index d9cc1d7e56c37d5ce92544edc10e89dbc89dd15d..39e7689be243b9c99b507d665f659135
|
||||
public EntityType(
|
||||
EntityType.EntityFactory<T> factory,
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 0e020dfebe06dce4c19beb10c961ea9e8a35a415..49f927c20b84e47ed2b0e57beecb3aa746448f5a 100644
|
||||
index ae049c5c3593525b991d865fec695c00ad408a59..ad34d0e1ab16fb269b3cec2842bfc2f2c29b452e 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -210,6 +210,25 @@ public abstract class Player extends LivingEntity {
|
||||
@@ -150,7 +149,7 @@ index 0e020dfebe06dce4c19beb10c961ea9e8a35a415..49f927c20b84e47ed2b0e57beecb3aa7
|
||||
this.noPhysics = this.isSpectator();
|
||||
if (this.isSpectator() || this.isPassenger()) {
|
||||
this.setOnGround(false);
|
||||
@@ -1502,6 +1541,7 @@ public abstract class Player extends LivingEntity {
|
||||
@@ -1504,6 +1543,7 @@ public abstract class Player extends LivingEntity {
|
||||
if (this.containerMenu != null && this.hasContainerOpen()) {
|
||||
this.doCloseContainer();
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Suisuroru <qwertyuiop14077@qq.com>
|
||||
Date: Thu, 20 Feb 2025 01:00:28 +0800
|
||||
Subject: [PATCH] Purpur-Barrels-and-enderchests-6-rows
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 548f7a2b0b020ff7fff27396942cc0bc9e755afe..b977d0b2c754c227b667ce9fdd3ebb934db8e974 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1103,6 +1103,10 @@ public abstract class PlayerList {
|
||||
player.getBukkitEntity().recalculatePermissions(); // CraftBukkit
|
||||
this.server.getCommands().sendCommands(player);
|
||||
} // Paper - Add sendOpLevel API
|
||||
+
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ player.enderChestSlotCount = me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows < 7 && me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows > 0 ? 9 * me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows : 27;
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
}
|
||||
|
||||
public boolean isWhiteListed(GameProfile profile) {
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index ad34d0e1ab16fb269b3cec2842bfc2f2c29b452e..40b91234fd2e4f4f134d309590ea6b605f764e83 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -200,6 +200,7 @@ public abstract class Player extends LivingEntity {
|
||||
private int currentImpulseContextResetGraceTime;
|
||||
public boolean affectsSpawning = true; // Paper - Affects Spawning API
|
||||
public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage
|
||||
+ public int enderChestSlotCount = -1; // Purpur - Barrels and enderchests 6 rows
|
||||
|
||||
// CraftBukkit start
|
||||
public boolean fauxSleeping;
|
||||
diff --git a/net/minecraft/world/inventory/ChestMenu.java b/net/minecraft/world/inventory/ChestMenu.java
|
||||
index 280169afbd637eeb67ddf7eaeb4eecd464a128d5..461705345dd897c8304c884272531af836f8854f 100644
|
||||
--- a/net/minecraft/world/inventory/ChestMenu.java
|
||||
+++ b/net/minecraft/world/inventory/ChestMenu.java
|
||||
@@ -66,10 +66,30 @@ public class ChestMenu extends AbstractContainerMenu {
|
||||
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, 6);
|
||||
}
|
||||
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ public static ChestMenu oneRow(int syncId, Inventory playerInventory, Container inventory) {
|
||||
+ return new ChestMenu(MenuType.GENERIC_9x1, syncId, playerInventory, inventory, 1);
|
||||
+ }
|
||||
+
|
||||
+ public static ChestMenu twoRows(int syncId, Inventory playerInventory, Container inventory) {
|
||||
+ return new ChestMenu(MenuType.GENERIC_9x2, syncId, playerInventory, inventory, 2);
|
||||
+ }
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
+
|
||||
public static ChestMenu threeRows(int containerId, Inventory playerInventory, Container container) {
|
||||
return new ChestMenu(MenuType.GENERIC_9x3, containerId, playerInventory, container, 3);
|
||||
}
|
||||
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ public static ChestMenu fourRows(int syncId, Inventory playerInventory, Container inventory) {
|
||||
+ return new ChestMenu(MenuType.GENERIC_9x4, syncId, playerInventory, inventory, 4);
|
||||
+ }
|
||||
+
|
||||
+ public static ChestMenu fiveRows(int syncId, Inventory playerInventory, Container inventory) {
|
||||
+ return new ChestMenu(MenuType.GENERIC_9x5, syncId, playerInventory, inventory, 5);
|
||||
+ }
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
+
|
||||
public static ChestMenu sixRows(int containerId, Inventory playerInventory, Container container) {
|
||||
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, container, 6);
|
||||
}
|
||||
diff --git a/net/minecraft/world/inventory/PlayerEnderChestContainer.java b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
||||
index a6a359bab2a727f4631b633a8bb370dd40decc75..5fab998cdec92a2bd965e6b48cc6189b195dc86d 100644
|
||||
--- a/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
||||
+++ b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
|
||||
@@ -25,11 +25,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
|
||||
}
|
||||
|
||||
public PlayerEnderChestContainer(Player owner) {
|
||||
- super(27);
|
||||
+ super(me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows < 7 && me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows > 0 ? 9 * me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows : 27);
|
||||
this.owner = owner;
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ @Override
|
||||
+ public int getContainerSize() {
|
||||
+ return owner.enderChestSlotCount < 0 ? super.getContainerSize() : owner.enderChestSlotCount;
|
||||
+ }
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
+
|
||||
public void setActiveChest(EnderChestBlockEntity enderChestBlockEntity) {
|
||||
this.activeChest = enderChestBlockEntity;
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/EnderChestBlock.java b/net/minecraft/world/level/block/EnderChestBlock.java
|
||||
index f5533960708bdbaf2eacefbc7c7c3123b7d26502..bf9801f1370c8d5e6ca459207b221ef2e92dac9e 100644
|
||||
--- a/net/minecraft/world/level/block/EnderChestBlock.java
|
||||
+++ b/net/minecraft/world/level/block/EnderChestBlock.java
|
||||
@@ -85,8 +85,14 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
|
||||
enderChestInventory.setActiveChest(enderChestBlockEntity); // Needs to happen before ChestMenu.threeRows as it is required for opening animations
|
||||
if (level instanceof ServerLevel serverLevel && player.openMenu(
|
||||
new SimpleMenuProvider(
|
||||
- (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE
|
||||
- )
|
||||
+ (containerId, playerInventory, player1) -> switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows) {
|
||||
+ case 6 -> ChestMenu.sixRows(containerId, playerInventory, enderChestInventory);
|
||||
+ case 5 -> ChestMenu.fiveRows(containerId, playerInventory, enderChestInventory);
|
||||
+ case 4 -> ChestMenu.fourRows(containerId, playerInventory, enderChestInventory);
|
||||
+ case 2 -> ChestMenu.twoRows(containerId, playerInventory, enderChestInventory);
|
||||
+ case 1 -> ChestMenu.oneRow(containerId, playerInventory, enderChestInventory);
|
||||
+ default -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory);
|
||||
+ }, CONTAINER_TITLE) // Purpur - Barrels and enderchests 6 rows
|
||||
).isPresent()) {
|
||||
// Paper end - Fix InventoryOpenEvent cancellation - moved up;
|
||||
player.awardStat(Stats.OPEN_ENDERCHEST);
|
||||
diff --git a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
index 0f808855f58281578c2758513787f0f7330c9291..5b6ee21c21686dad86717b87c0033149cefad142 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
@@ -55,7 +55,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
|
||||
this.maxStack = i;
|
||||
}
|
||||
// CraftBukkit end
|
||||
- private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ private NonNullList<ItemStack> items = NonNullList.withSize(switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.barrelRows) {
|
||||
+ case 6 -> 54;
|
||||
+ case 5 -> 45;
|
||||
+ case 4 -> 36;
|
||||
+ case 2 -> 18;
|
||||
+ case 1 -> 9;
|
||||
+ default -> 27;
|
||||
+ }, ItemStack.EMPTY);
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
+
|
||||
public final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
|
||||
@Override
|
||||
protected void onOpen(Level level, BlockPos pos, BlockState state) {
|
||||
@@ -107,7 +117,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
|
||||
|
||||
@Override
|
||||
public int getContainerSize() {
|
||||
- return 27;
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ return switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.barrelRows) {
|
||||
+ case 6 -> 54;
|
||||
+ case 5 -> 45;
|
||||
+ case 4 -> 36;
|
||||
+ case 2 -> 18;
|
||||
+ case 1 -> 9;
|
||||
+ default -> 27;
|
||||
+ };
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,7 +146,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
|
||||
|
||||
@Override
|
||||
protected AbstractContainerMenu createMenu(int id, Inventory player) {
|
||||
- return ChestMenu.threeRows(id, player, this);
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ return switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.barrelRows) {
|
||||
+ case 6 -> ChestMenu.sixRows(id, player, this);
|
||||
+ case 5 -> ChestMenu.fiveRows(id, player, this);
|
||||
+ case 4 -> ChestMenu.fourRows(id, player, this);
|
||||
+ case 2 -> ChestMenu.twoRows(id, player, this);
|
||||
+ case 1 -> ChestMenu.oneRow(id, player, this);
|
||||
+ default -> ChestMenu.threeRows(id, player, this);
|
||||
+ };
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/server/Main.java
|
||||
+++ b/net/minecraft/server/Main.java
|
||||
@@ -108,6 +_,7 @@
|
||||
JvmProfiler.INSTANCE.start(Environment.SERVER);
|
||||
}
|
||||
|
||||
+ me.earthme.luminol.config.LuminolConfig.preLoadConfig(); // Luminol - Luminol config
|
||||
io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper
|
||||
Bootstrap.bootStrap();
|
||||
Bootstrap.validate();
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -212,6 +_,8 @@
|
||||
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
|
||||
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
||||
// Paper end - initialize global and world-defaults configuration
|
||||
+ me.earthme.luminol.config.LuminolConfig.finalizeLoadConfig(); //Luminol - load config file
|
||||
+ me.earthme.luminol.config.LuminolConfig.setupLatch(); //Luminol - load config file
|
||||
this.server.spark.enableEarlyIfRequested(); // Paper - spark
|
||||
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
|
||||
if (this.convertOldUsers()) {
|
||||
@@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:17:53 +0800
|
||||
Date: Tue, 11 Feb 2025 11:58:56 +0800
|
||||
Subject: [PATCH] Add config for server mod name
|
||||
|
||||
|
||||
@@ -17,32 +17,3 @@ index 6ed2114f577ce12d2d493985e798609c7d83f15e..7a5dcf3b7108794b9a224004730eb396
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..94e7c8910e3623163528a844fd7a08b3ffe5826b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+public class ServerModNameConfig implements IConfigModule {
|
||||
+ @ConfigInfo(baseName = "name")
|
||||
+ public static String serverModName = "Luminol";
|
||||
+
|
||||
+ @ConfigInfo(baseName = "vanilla_spoof")
|
||||
+ public static boolean fakeVanilla = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.MISC;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "server_mod_name";
|
||||
+ }
|
||||
+}
|
||||
@@ -1,571 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:15:53 +0800
|
||||
Subject: [PATCH] Add luminol config framework
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java b/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5c8745dffa80cf47e856d04d283937bda86881f8
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java
|
||||
@@ -0,0 +1,70 @@
|
||||
+package me.earthme.luminol.commands;
|
||||
+
|
||||
+import me.earthme.luminol.config.LuminolConfig;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.format.TextColor;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+
|
||||
+public class LuminolConfigCommand extends Command {
|
||||
+ public LuminolConfigCommand(){
|
||||
+ super("luminolconfig");
|
||||
+ this.setPermission("luminol.commands.luminolconfig");
|
||||
+ this.setDescription("Manage config file");
|
||||
+ this.setUsage("/luminolconfig");
|
||||
+ }
|
||||
+
|
||||
+ @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){
|
||||
+ result.add("reload");
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
||||
+ if (!this.testPermission(sender)){
|
||||
+ sender.sendMessage(Component
|
||||
+ .text("No permission to execute this command!")
|
||||
+ .color(TextColor.color(255,0,0))
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ if (args.length < 1){
|
||||
+ sender.sendMessage(
|
||||
+ Component
|
||||
+ .text("Wrong use!\n")
|
||||
+ .color(TextColor.color(255,0,0))
|
||||
+ );
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ switch (args[0]){
|
||||
+ case "reload" -> {
|
||||
+ LuminolConfig.reloadAsync().thenAccept(nullValue -> sender.sendMessage(
|
||||
+ Component
|
||||
+ .text("Reloaded config file!")
|
||||
+ .color(TextColor.color(0,255,0))
|
||||
+ ));
|
||||
+ }
|
||||
+
|
||||
+ default -> sender.sendMessage(
|
||||
+ Component
|
||||
+ .text("Unknown action!\n")
|
||||
+ .color(TextColor.color(255,0,0))
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/ConfigInfo.java b/src/main/java/me/earthme/luminol/config/ConfigInfo.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..01b64c2cf6b437114337626c242e1da3fbdb8ead
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/ConfigInfo.java
|
||||
@@ -0,0 +1,11 @@
|
||||
+package me.earthme.luminol.config;
|
||||
+
|
||||
+import java.lang.annotation.Retention;
|
||||
+import java.lang.annotation.RetentionPolicy;
|
||||
+
|
||||
+@Retention(RetentionPolicy.RUNTIME)
|
||||
+public @interface ConfigInfo {
|
||||
+ String baseName();
|
||||
+
|
||||
+ String comments() default "";
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/DoNotLoad.java b/src/main/java/me/earthme/luminol/config/DoNotLoad.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fffc5eb4be4b78a886f3c340bd60f3a2b0108a7d
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/DoNotLoad.java
|
||||
@@ -0,0 +1,8 @@
|
||||
+package me.earthme.luminol.config;
|
||||
+
|
||||
+import java.lang.annotation.Retention;
|
||||
+import java.lang.annotation.RetentionPolicy;
|
||||
+
|
||||
+@Retention(RetentionPolicy.RUNTIME)
|
||||
+public @interface DoNotLoad {
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/EnumConfigCategory.java b/src/main/java/me/earthme/luminol/config/EnumConfigCategory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7b75405c468d24ed8aea5aa54ae5ac339118bf60
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/EnumConfigCategory.java
|
||||
@@ -0,0 +1,19 @@
|
||||
+package me.earthme.luminol.config;
|
||||
+
|
||||
+public enum EnumConfigCategory {
|
||||
+ OPTIMIZATIONS("optimizations"),
|
||||
+ FIXES("fixes"),
|
||||
+ MISC("misc"),
|
||||
+ GAMEPLAY("gameplay"),
|
||||
+ EXPERIMENT("experiment");
|
||||
+
|
||||
+ private final String baseKeyName;
|
||||
+
|
||||
+ EnumConfigCategory(String baseKeyName) {
|
||||
+ this.baseKeyName = baseKeyName;
|
||||
+ }
|
||||
+
|
||||
+ public String getBaseKeyName() {
|
||||
+ return this.baseKeyName;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java b/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..559c11cb523c7cade34a0abfad15c988f5ad87fe
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/HotReloadUnsupported.java
|
||||
@@ -0,0 +1,8 @@
|
||||
+package me.earthme.luminol.config;
|
||||
+
|
||||
+import java.lang.annotation.Retention;
|
||||
+import java.lang.annotation.RetentionPolicy;
|
||||
+
|
||||
+@Retention(RetentionPolicy.RUNTIME)
|
||||
+public @interface HotReloadUnsupported {
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/IConfigModule.java b/src/main/java/me/earthme/luminol/config/IConfigModule.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9f6896711907ac30fe0c00130207b970007e4bb4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/IConfigModule.java
|
||||
@@ -0,0 +1,22 @@
|
||||
+package me.earthme.luminol.config;
|
||||
+
|
||||
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public interface IConfigModule {
|
||||
+
|
||||
+ EnumConfigCategory getCategory();
|
||||
+
|
||||
+ String getBaseName();
|
||||
+
|
||||
+ default void onLoaded(CommentedFileConfig configInstance) {}
|
||||
+
|
||||
+ default <T> T get(String keyName, T defaultValue, @NotNull CommentedFileConfig config){
|
||||
+ if (!config.contains(keyName)){
|
||||
+ config.set(keyName,defaultValue);
|
||||
+ return defaultValue;
|
||||
+ }
|
||||
+
|
||||
+ return config.get(keyName);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/LuminolConfig.java b/src/main/java/me/earthme/luminol/config/LuminolConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..526b68e184a2f6f9e38cd02995b473a943404141
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/LuminolConfig.java
|
||||
@@ -0,0 +1,226 @@
|
||||
+package me.earthme.luminol.config;
|
||||
+
|
||||
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
||||
+import io.papermc.paper.threadedregions.RegionizedServer;
|
||||
+import me.earthme.luminol.commands.LuminolConfigCommand;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.jetbrains.annotations.Contract;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import java.io.File;
|
||||
+import java.io.IOException;
|
||||
+import java.lang.reflect.Field;
|
||||
+import java.lang.reflect.InvocationTargetException;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+import java.net.JarURLConnection;
|
||||
+import java.net.URL;
|
||||
+import java.net.URLDecoder;
|
||||
+import java.nio.charset.StandardCharsets;
|
||||
+import java.util.*;
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+import java.util.jar.JarEntry;
|
||||
+import java.util.jar.JarFile;
|
||||
+import org.apache.logging.log4j.LogManager;
|
||||
+import org.apache.logging.log4j.Logger;
|
||||
+
|
||||
+public class LuminolConfig {
|
||||
+ public static final Logger logger = LogManager.getLogger();
|
||||
+ 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<>();
|
||||
+ private static CommentedFileConfig configFileInstance;
|
||||
+ public static boolean alreadyInited = false;
|
||||
+
|
||||
+ public static void setupLatch(){
|
||||
+ Bukkit.getCommandMap().register("luminolconfig","luminol",new LuminolConfigCommand());
|
||||
+ alreadyInited = true;
|
||||
+ }
|
||||
+
|
||||
+ public static void reload(){
|
||||
+ RegionizedServer.ensureGlobalTickThread("Reload luminol config off global region thread!");
|
||||
+
|
||||
+ dropAllInstanced();
|
||||
+ try {
|
||||
+ preLoadConfig();
|
||||
+ finalizeLoadConfig();
|
||||
+ }catch (Exception e){
|
||||
+ logger.error(e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Contract(" -> new")
|
||||
+ public static @NotNull CompletableFuture<Void> reloadAsync(){
|
||||
+ return CompletableFuture.runAsync(LuminolConfig::reload,task -> RegionizedServer.getInstance().addTask(() -> {
|
||||
+ try{
|
||||
+ task.run();
|
||||
+ }catch (Exception e){
|
||||
+ logger.error(e);
|
||||
+ }
|
||||
+ }));
|
||||
+ }
|
||||
+
|
||||
+ public static void dropAllInstanced(){
|
||||
+ allInstanced.clear();
|
||||
+ }
|
||||
+
|
||||
+ public static void finalizeLoadConfig() {
|
||||
+ for (IConfigModule module : allInstanced) {
|
||||
+ module.onLoaded(configFileInstance);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static void preLoadConfig() throws IOException {
|
||||
+ baseConfigFolder.mkdirs();
|
||||
+
|
||||
+ if (!baseConfigFile.exists()){
|
||||
+ baseConfigFile.createNewFile();
|
||||
+ }
|
||||
+
|
||||
+ configFileInstance = CommentedFileConfig.ofConcurrent(baseConfigFile);
|
||||
+
|
||||
+ configFileInstance.load();
|
||||
+
|
||||
+ try {
|
||||
+ instanceAllModule();
|
||||
+ loadAllModules();
|
||||
+ }catch (Exception e){
|
||||
+ logger.error("Failed to load config modules!",e);
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+
|
||||
+ configFileInstance.save();
|
||||
+ }
|
||||
+
|
||||
+ private static void loadAllModules() throws IllegalAccessException {
|
||||
+ for (IConfigModule instanced : allInstanced){
|
||||
+ loadForSingle(instanced);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void instanceAllModule() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
|
||||
+ for (Class<?> clazz : getClasses("me.earthme.luminol.config.modules")){
|
||||
+ if (IConfigModule.class.isAssignableFrom(clazz)){
|
||||
+ allInstanced.add((IConfigModule) clazz.getConstructor().newInstance());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void loadForSingle(@NotNull IConfigModule singleConfigModule) throws IllegalAccessException {
|
||||
+ final EnumConfigCategory category = singleConfigModule.getCategory();
|
||||
+
|
||||
+ Field[] fields = singleConfigModule.getClass().getDeclaredFields();
|
||||
+
|
||||
+ 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);
|
||||
+ ConfigInfo configInfo = field.getAnnotation(ConfigInfo.class);
|
||||
+
|
||||
+ if (skipLoad || configInfo == null){
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final String fullConfigKeyName = category.getBaseKeyName() + "." + singleConfigModule.getBaseName() + "." + configInfo.baseName();
|
||||
+
|
||||
+ field.setAccessible(true);
|
||||
+ final Object currentValue = field.get(null);
|
||||
+
|
||||
+ if (!configFileInstance.contains(fullConfigKeyName)){
|
||||
+ if (currentValue == null){
|
||||
+ throw new UnsupportedOperationException("Config " + singleConfigModule.getBaseName() + "tried to add an null default value!");
|
||||
+ }
|
||||
+
|
||||
+ final String comments = configInfo.comments();
|
||||
+
|
||||
+ if (!comments.isBlank()){
|
||||
+ configFileInstance.setComment(fullConfigKeyName,comments);
|
||||
+ }
|
||||
+
|
||||
+ configFileInstance.add(fullConfigKeyName,currentValue);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ final Object actuallyValue = configFileInstance.get(fullConfigKeyName);
|
||||
+ field.set(null,actuallyValue);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static @NotNull Set<Class<?>> getClasses(String pack) {
|
||||
+ Set<Class<?>> classes = new LinkedHashSet<>();
|
||||
+ String packageDirName = pack.replace('.', '/');
|
||||
+ Enumeration<URL> dirs;
|
||||
+
|
||||
+ try {
|
||||
+ dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
|
||||
+ while (dirs.hasMoreElements()) {
|
||||
+ URL url = dirs.nextElement();
|
||||
+ String protocol = url.getProtocol();
|
||||
+ if ("file".equals(protocol)) {
|
||||
+ String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8);
|
||||
+ findClassesInPackageByFile(pack, filePath, classes);
|
||||
+ } else if ("jar".equals(protocol)) {
|
||||
+ JarFile jar;
|
||||
+ try {
|
||||
+ jar = ((JarURLConnection) url.openConnection()).getJarFile();
|
||||
+ Enumeration<JarEntry> entries = jar.entries();
|
||||
+ findClassesInPackageByJar(pack, entries, packageDirName, classes);
|
||||
+ } catch (IOException e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ } catch (IOException e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+
|
||||
+ return classes;
|
||||
+ }
|
||||
+
|
||||
+ private static void findClassesInPackageByFile(String packageName, String packagePath, Set<Class<?>> classes) {
|
||||
+ File dir = new File(packagePath);
|
||||
+
|
||||
+ if (!dir.exists() || !dir.isDirectory()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ File[] dirfiles = dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(".class"));
|
||||
+ if (dirfiles != null) {
|
||||
+ for (File file : dirfiles) {
|
||||
+ if (file.isDirectory()) {
|
||||
+ findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), classes);
|
||||
+ } else {
|
||||
+ String className = file.getName().substring(0, file.getName().length() - 6);
|
||||
+ try {
|
||||
+ classes.add(Class.forName(packageName + '.' + className));
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void findClassesInPackageByJar(String packageName, Enumeration<JarEntry> entries, String packageDirName, Set<Class<?>> classes) {
|
||||
+ while (entries.hasMoreElements()) {
|
||||
+ JarEntry entry = entries.nextElement();
|
||||
+ String name = entry.getName();
|
||||
+ if (name.charAt(0) == '/') {
|
||||
+ name = name.substring(1);
|
||||
+ }
|
||||
+ if (name.startsWith(packageDirName)) {
|
||||
+ int idx = name.lastIndexOf('/');
|
||||
+ if (idx != -1) {
|
||||
+ packageName = name.substring(0, idx).replace('/', '.');
|
||||
+ }
|
||||
+ if (name.endsWith(".class") && !entry.isDirectory()) {
|
||||
+ String className = name.substring(packageName.length() + 1, name.length() - 6);
|
||||
+ try {
|
||||
+ classes.add(Class.forName(packageName + '.' + className));
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ throw new RuntimeException(e);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/utils/NullPlugin.java b/src/main/java/me/earthme/luminol/utils/NullPlugin.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..de94c8e39f0ae0da80d5a79af63413e287f5d190
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/utils/NullPlugin.java
|
||||
@@ -0,0 +1,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.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;
|
||||
+
|
||||
+ private final String pluginName;
|
||||
+ private PluginDescriptionFile pdf;
|
||||
+
|
||||
+ public NullPlugin() {
|
||||
+ this.pluginName = "Minecraft";
|
||||
+ pdf = new PluginDescriptionFile(pluginName, "1.0", "nms");
|
||||
+ }
|
||||
+
|
||||
+ public void setEnabled(boolean enabled) {
|
||||
+ this.enabled = enabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public File getDataFolder() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ 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.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InputStream getResource(String filename) {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void saveConfig() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void saveDefaultConfig() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void saveResource(String resourcePath, boolean replace) {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void reloadConfig() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PluginLogger getLogger() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PluginLoader getPluginLoader() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Server getServer() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isEnabled() {
|
||||
+ return enabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onDisable() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onLoad() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onEnable() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isNaggable() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setNaggable(boolean canNag) {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Nullable BiomeProvider getDefaultBiomeProvider(@NotNull String worldName, @Nullable String id) {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - lifecycle events
|
||||
+ @Override
|
||||
+ public @NotNull io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<org.bukkit.plugin.Plugin> getLifecycleManager() {
|
||||
+ throw new UnsupportedOperationException("Not supported.");
|
||||
+ }
|
||||
+ // Paper end - lifecycle events
|
||||
+}
|
||||
\ No newline at end of file
|
||||
@@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Wed, 29 Jan 2025 09:08:22 +0800
|
||||
Date: Tue, 11 Feb 2025 12:00:30 +0800
|
||||
Subject: [PATCH] Add config to disable async catchers
|
||||
|
||||
|
||||
@@ -79,32 +79,6 @@ index c95769a4e64fabd7acdff6c5f6f349107e1cf5c0..4efa1c057ae6cfdea7889c372bd62dc1
|
||||
final String ex = "Thread failed main thread check: " +
|
||||
reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ);
|
||||
LOGGER.error(ex, new Throwable());
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/DisableAsyncCatcherConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/DisableAsyncCatcherConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..61f653eeca366672ded88c491cf5c59e546e7301
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/DisableAsyncCatcherConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+public class DisableAsyncCatcherConfig implements IConfigModule {
|
||||
+ @ConfigInfo(baseName = "enabled")
|
||||
+ public static boolean enabled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.EXPERIMENT;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "disable_async_catchers";
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
index 50f01faa88c8c658252fade3748f20e48e9c8432..36fa1f83c3286e10cc7c208a2a2f1a718d525ad8 100644
|
||||
--- a/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
@@ -0,0 +1,71 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 11 Feb 2025 11:57:22 +0800
|
||||
Subject: [PATCH] Add tpsbar with chunkhot membar and region bar
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index de8b9048c8395c05b8688bc9d984b8ad680f15b3..f42692cd4f0154705c3d5b030d281cfc333803ed 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -437,4 +437,12 @@ public class CraftChunk implements Chunk {
|
||||
static {
|
||||
Arrays.fill(FULL_LIGHT, (byte) 0xFF);
|
||||
}
|
||||
+
|
||||
+ // KioCG start - ChunkHot
|
||||
+ @Override
|
||||
+ public long getChunkHotAvg() {
|
||||
+ final net.minecraft.world.level.chunk.LevelChunk target = this.worldServer.getChunkIfLoaded(this.x,this.z);
|
||||
+ return target == null ? -1 : target.getChunkHot().getAverage();
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 2d1b672fc152054d7b6abf47f443b87f5a2ea3de..3e4e0dcdd4e2808aef8dd41f159a358f47450f40 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -2404,6 +2404,15 @@ 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
|
||||
+ //Luminol start - Membar
|
||||
+ getHandle().isMemBarVisible = data.getBoolean("membarVisible");
|
||||
+ //Luminol end
|
||||
+ //Luminol start - Regionbar
|
||||
+ getHandle().isRegionBarVisible = data.getBoolean("regionbarVisible");
|
||||
+ //Luminol end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2425,6 +2434,15 @@ 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
|
||||
+ //Luminol start - Membar
|
||||
+ data.putBoolean("membarVisible", handle.isMemBarVisible);
|
||||
+ //Luminol end
|
||||
+ //Luminol start - Regionbar
|
||||
+ data.putBoolean("regionbarVisible", handle.isRegionBarVisible);
|
||||
+ //Luminol end
|
||||
// Paper start - persist for use in offline save data
|
||||
if (!nbttagcompound.contains("Paper")) {
|
||||
nbttagcompound.put("Paper", new CompoundTag());
|
||||
@@ -3611,4 +3629,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
return forwardMovement == backwardMovement ? 0 : forwardMovement ? 1 : -1;
|
||||
}
|
||||
+
|
||||
+ // KioCG start - ChunkHot
|
||||
+ @Override
|
||||
+ public long getNearbyChunkHot() {
|
||||
+ return this.getHandle().getNearbyChunkHot();
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 11 Feb 2025 12:01:39 +0800
|
||||
Subject: [PATCH] Purpur Lobotomize stuck villagers
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
|
||||
index bd515cdfbcc6fb0d17f70150d8b0bab60949db49..b6038fedea6251226b3b3db0f4b7a1f3d2276ab0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
|
||||
@@ -381,4 +381,11 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
|
||||
getHandle().getGossips().gossips.clear();
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public boolean isLobotomized() {
|
||||
+ return getHandle().isLobotomized();
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
||||
@@ -18,10 +18,10 @@ index a0b84535a9d3833d4df692b85b272f145559dd80..c2ba46408b5ad727d7a17f21d47b2898
|
||||
return;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index bcd17eba9798747010ed96903992939a284199df..f9f20e9fd4530d0130046b56c55e798d4ede29d1 100644
|
||||
index 8eecdc662257edeb67d6823c476c635ba906d4dc..0ab41895a447725e6fa22e49c15e4cf3bf87805d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -313,7 +313,7 @@ public final class CraftServer implements Server {
|
||||
@@ -314,7 +314,7 @@ public final class CraftServer implements Server {
|
||||
public static Exception excessiveVelEx; // Paper - Velocity warnings
|
||||
private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper
|
||||
private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes
|
||||
@@ -30,7 +30,7 @@ index bcd17eba9798747010ed96903992939a284199df..f9f20e9fd4530d0130046b56c55e798d
|
||||
|
||||
// Paper start - Folia region threading API
|
||||
private final io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler(); // Folia - region threading
|
||||
@@ -491,7 +491,7 @@ public final class CraftServer implements Server {
|
||||
@@ -492,7 +492,7 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes
|
||||
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
|
||||
@@ -39,7 +39,7 @@ index bcd17eba9798747010ed96903992939a284199df..f9f20e9fd4530d0130046b56c55e798d
|
||||
}
|
||||
|
||||
public boolean getCommandBlockOverride(String command) {
|
||||
@@ -1155,7 +1155,7 @@ public final class CraftServer implements Server {
|
||||
@@ -1156,7 +1156,7 @@ public final class CraftServer implements Server {
|
||||
this.reloadData();
|
||||
org.spigotmc.SpigotConfig.registerCommands(); // Spigot
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
|
||||
@@ -48,7 +48,7 @@ index bcd17eba9798747010ed96903992939a284199df..f9f20e9fd4530d0130046b56c55e798d
|
||||
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
|
||||
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
|
||||
|
||||
@@ -1184,7 +1184,7 @@ public final class CraftServer implements Server {
|
||||
@@ -1185,7 +1185,7 @@ public final class CraftServer implements Server {
|
||||
this.loadPlugins();
|
||||
this.enablePlugins(PluginLoadOrder.STARTUP);
|
||||
this.enablePlugins(PluginLoadOrder.POSTWORLD);
|
||||
@@ -1,14 +1,14 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 15:35:44 +0800
|
||||
Date: Tue, 11 Feb 2025 11:46:26 +0800
|
||||
Subject: [PATCH] SparklyPaper Optimize canSee checks
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 84304fc8c26a6e1e3515b131a2ee3357262efcc3..e3fe81a1d91f60c6696070751c5220ec1868390a 100644
|
||||
index 3e4e0dcdd4e2808aef8dd41f159a358f47450f40..450350e66ae42f234bfd3016da1434e3194259e2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -213,7 +213,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
@@ -214,7 +214,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
private boolean hasPlayedBefore = false;
|
||||
private final ConversationTracker conversationTracker = new ConversationTracker();
|
||||
private final Set<String> channels = new HashSet<String>();
|
||||
@@ -17,7 +17,7 @@ index 84304fc8c26a6e1e3515b131a2ee3357262efcc3..e3fe81a1d91f60c6696070751c5220ec
|
||||
private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player
|
||||
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
|
||||
private int hash = 0;
|
||||
@@ -2267,9 +2267,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
@@ -2268,9 +2268,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public boolean canSee(org.bukkit.entity.Entity entity) {
|
||||
@@ -1,58 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:29:45 +0800
|
||||
Subject: [PATCH] Add config for offline mode warning
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/OfflineModeWarningConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/OfflineModeWarningConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..502b93c7bda9e8577a1901a8777b7cf9b9bdc36b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/OfflineModeWarningConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+public class OfflineModeWarningConfig implements IConfigModule {
|
||||
+ @ConfigInfo(baseName = "enabled")
|
||||
+ public static boolean enabled = true;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.MISC;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "warn_on_offline_mode";
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/UsernameCheckConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/UsernameCheckConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c7e4724cc4ab8d911bcaf0106c098b266c843bb1
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/UsernameCheckConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+public class UsernameCheckConfig implements IConfigModule {
|
||||
+ @ConfigInfo(baseName = "enabled")
|
||||
+ public static boolean enabled = true;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.MISC;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "username_checks";
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 11 Feb 2025 12:03:38 +0800
|
||||
Subject: [PATCH] Leaf Secure seed and matter seed command
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index f42692cd4f0154705c3d5b030d281cfc333803ed..39cc976f65f826a00e2e637c139f9134c5e74715 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -206,7 +206,12 @@ public class CraftChunk implements Chunk {
|
||||
@Override
|
||||
public boolean isSlimeChunk() {
|
||||
// 987234911L is deterimined in EntitySlime when seeing if a slime can spawn in a chunk
|
||||
- return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ boolean isSlimeChunk = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
|
||||
+ ? worldServer.getChunk(this.getX(), this.getZ()).isSlimeChunk()
|
||||
+ : WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
|
||||
+ return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0ab41895a447725e6fa22e49c15e4cf3bf87805d..33a0ef0bf3338631f61c8a6da5e3ff4209bb0b21 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1423,7 +1423,11 @@ public final class CraftServer implements Server {
|
||||
registryAccess = levelDataAndDimensions.dimensions().dimensionsRegistryAccess();
|
||||
} else {
|
||||
LevelSettings levelSettings;
|
||||
- WorldOptions worldOptions = new WorldOptions(creator.seed(), creator.generateStructures(), false);
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ WorldOptions worldOptions = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
|
||||
+ ? new WorldOptions(creator.seed(), su.plo.matter.Globals.createRandomWorldSeed(), creator.generateStructures(), false)
|
||||
+ : new WorldOptions(creator.seed(), creator.generateStructures(), false);
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
WorldDimensions worldDimensions;
|
||||
|
||||
DedicatedServerProperties.WorldDimensionData properties = new DedicatedServerProperties.WorldDimensionData(GsonHelper.parse((creator.generatorSettings().isEmpty()) ? "{}" : creator.generatorSettings()), creator.type().name().toLowerCase(Locale.ROOT));
|
||||
@@ -0,0 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 11 Feb 2025 11:46:44 +0800
|
||||
Subject: [PATCH] Tick regions api
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 82d26889661a944e057be0c450fb5a296122ea8e..4f320a91fb8abe21cbb7b01fdc34330def5b2448 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -2517,4 +2517,11 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
return this.adventure$pointers;
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Luminol start - Tick regions api
|
||||
+ @Override
|
||||
+ public me.earthme.luminol.api.ThreadedRegionizer getThreadedRegionizer() {
|
||||
+ return new me.earthme.luminol.api.impl.ThreadedRegionizerImpl(this.world);
|
||||
+ }
|
||||
+ // Luminol end
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:31:09 +0800
|
||||
Subject: [PATCH] Add config to verify signature only in online-mode
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/PublickeyVerifyConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/PublickeyVerifyConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e45ce3abf49684c911678abcefd69586246cc0e3
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/PublickeyVerifyConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+public class PublickeyVerifyConfig implements IConfigModule {
|
||||
+
|
||||
+ @ConfigInfo(baseName = "enabled")
|
||||
+ public static boolean enabled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.MISC;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "verify_publickey_only_in_online_mode";
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/TripwireConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/TripwireConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8def8aad908f5e6b828d7d9179bfe1962c39f9f7
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/TripwireConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+public class TripwireConfig implements IConfigModule {
|
||||
+ @ConfigInfo(baseName = "enabled")
|
||||
+ public static boolean enabled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.MISC;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "tripwire_dupe";
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Suisuroru <qwertyuiop14077@qq.com>
|
||||
Date: Thu, 20 Feb 2025 01:00:29 +0800
|
||||
Subject: [PATCH] Purpur-Barrels-and-enderchests-6-rows
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||
index 1ce328bed5cf3d087a3f7dc9236153381d758493..20f2b9945eaa58e05b417d9cca7c30dd0496cf72 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||
@@ -145,9 +145,26 @@ public class CraftContainer extends AbstractContainerMenu {
|
||||
case PLAYER:
|
||||
case CHEST:
|
||||
case ENDER_CHEST:
|
||||
- case BARREL:
|
||||
- this.delegate = new ChestMenu(net.minecraft.world.inventory.MenuType.GENERIC_9x3, windowId, bottom, top, top.getContainerSize() / 9);
|
||||
+ // Purpur start - Barrels and enderchests 6 rows
|
||||
+ this.delegate = new ChestMenu(switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.enderchestRows) {
|
||||
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
|
||||
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
|
||||
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
|
||||
+ case 2 -> net.minecraft.world.inventory.MenuType.GENERIC_9x2;
|
||||
+ case 1 -> net.minecraft.world.inventory.MenuType.GENERIC_9x1;
|
||||
+ default -> net.minecraft.world.inventory.MenuType.GENERIC_9x3;
|
||||
+ }, windowId, bottom, top, top.getContainerSize() / 9);
|
||||
break;
|
||||
+ case BARREL:
|
||||
+ this.delegate = new ChestMenu(switch (me.earthme.luminol.config.modules.misc.ContainerExpansionConfig.barrelRows) {
|
||||
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
|
||||
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
|
||||
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
|
||||
+ case 2 -> net.minecraft.world.inventory.MenuType.GENERIC_9x2;
|
||||
+ case 1 -> net.minecraft.world.inventory.MenuType.GENERIC_9x1;
|
||||
+ default -> net.minecraft.world.inventory.MenuType.GENERIC_9x3;
|
||||
+ }, windowId, bottom, top, top.getContainerSize() / 9);
|
||||
+ // Purpur end - Barrels and enderchests 6 rows
|
||||
case DISPENSER:
|
||||
case DROPPER:
|
||||
this.delegate = new DispenserMenu(windowId, bottom, top);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
index c6159c70f7a37b9bffe268b91905ce848d1d2927..1ae08daecb7f072e0afaae327bad64e43c3ae027 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
@@ -84,7 +84,7 @@ public class CraftInventory implements Inventory {
|
||||
|
||||
@Override
|
||||
public void setContents(ItemStack[] items) {
|
||||
- Preconditions.checkArgument(items.length <= this.getSize(), "Invalid inventory size (%s); expected %s or less", items.length, this.getSize());
|
||||
+ // Preconditions.checkArgument(items.length <= this.getSize(), "Invalid inventory size (%s); expected %s or less", items.length, this.getSize()); // Purpur - Barrels and enderchests 6 rows
|
||||
|
||||
for (int i = 0; i < this.getSize(); i++) {
|
||||
if (i >= items.length) {
|
||||
@@ -1,40 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Wed, 29 Jan 2025 14:57:27 +0800
|
||||
Subject: [PATCH] Skip collision check if the block is not belong to current
|
||||
tick region
|
||||
|
||||
A temporary fix of these issues:
|
||||
https://github.com/PaperMC/Folia/issues/311
|
||||
|
||||
Due to that mojang won't ignore the blocks the entity passed by, and sometimes the old position may not be updated and it points to a block that we don't own it, and it will access it during applyEffectsFromBlocks.So the best way to fix that is to skip the collision check of that block because it was already not owned by us and it's not necessary to check it
|
||||
|
||||
Related to mojang's bug fix:
|
||||
https://bugs.mojang.com/browse/MC-92875
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaOldPositionIssueFixConfig.java b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaOldPositionIssueFixConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7294792d934e7374dcf335135dda739702fdcc62
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/fixes/FoliaOldPositionIssueFixConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+public class FoliaOldPositionIssueFixConfig implements IConfigModule {
|
||||
+ @ConfigInfo(baseName = "enabled")
|
||||
+ public static boolean enabled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.FIXES;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "folia.fix_old_position_issue";
|
||||
+ }
|
||||
+}
|
||||
@@ -1,201 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Wed, 29 Jan 2025 09:12:07 +0800
|
||||
Subject: [PATCH] KioCG Chunk API and display of chunkhot in tpsbar
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/kiocg/ChunkHot.java b/src/main/java/com/kiocg/ChunkHot.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..53b4397997bc9b9b9d88e48304b37a2590161906
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/kiocg/ChunkHot.java
|
||||
@@ -0,0 +1,90 @@
|
||||
+package com.kiocg;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+
|
||||
+public class ChunkHot {
|
||||
+ // 热度统计总区间数量
|
||||
+ private static final int TIMES_LENGTH = 10;
|
||||
+ // 当前统计区间下标
|
||||
+ private int index = -1;
|
||||
+
|
||||
+ // 热度统计区间
|
||||
+ private final long[] times = new long[TIMES_LENGTH];
|
||||
+ // 存放临时的区间数值
|
||||
+ // 用于修正正在统计的当前区间热度没有计入总值的问题
|
||||
+ private long temp;
|
||||
+ // 所有区间的热度总值
|
||||
+ private long total;
|
||||
+
|
||||
+ // 用于每个具体统计的计算
|
||||
+ private long nanos;
|
||||
+ // 当前统计是否进行中
|
||||
+ private volatile boolean started = false;
|
||||
+
|
||||
+ /**
|
||||
+ * 更新区间下标
|
||||
+ */
|
||||
+ public void nextTick() {
|
||||
+ this.index = ++this.index % TIMES_LENGTH;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 开始统计一个新区间
|
||||
+ */
|
||||
+ public void start() {
|
||||
+ started = true;
|
||||
+ temp = times[this.index];
|
||||
+ times[this.index] = 0L;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isStarted(){
|
||||
+ return this.started;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 结束当前区间的统计
|
||||
+ * 将统计值更新入热度总值
|
||||
+ */
|
||||
+ public void stop() {
|
||||
+ started = false;
|
||||
+ total -= temp;
|
||||
+ total += times[this.index];
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 开始一个具体统计
|
||||
+ */
|
||||
+ public void startTicking() {
|
||||
+ if (!started) return;
|
||||
+ nanos = System.nanoTime();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 结束一个具体统计
|
||||
+ * 将统计值计入当前热度区间
|
||||
+ */
|
||||
+ public void stopTickingAndCount() {
|
||||
+ if (!started) return;
|
||||
+ // 定义一个具体统计的最大值为 1,000,000
|
||||
+ // 有时候某个具体统计的计算值会在某1刻飙升,可能是由于保存数据到磁盘?
|
||||
+ times[this.index] += Math.min(System.nanoTime() - nanos, 1000000L);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 清空统计 (当区块卸载时)
|
||||
+ */
|
||||
+ public void clear() {
|
||||
+ started = false;
|
||||
+ Arrays.fill(times, 0L);
|
||||
+ temp = 0L;
|
||||
+ total = 0L;
|
||||
+ nanos = 0L;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return 获取区块热度平均值
|
||||
+ */
|
||||
+ public long getAverage() {
|
||||
+ return total / ((long) TIMES_LENGTH * 20L);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
|
||||
index aafb2f5052c7c8e5971a47308253badb3027093c..9fe7ac7ba83bbcc9a2a851a5cace47641323f4d2 100644
|
||||
--- a/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/TpsBarConfig.java
|
||||
@@ -12,11 +12,13 @@ public class TpsBarConfig implements IConfigModule {
|
||||
@ConfigInfo(baseName = "enabled")
|
||||
public static boolean tpsbarEnabled = false;
|
||||
@ConfigInfo(baseName = "format")
|
||||
- public static String tpsBarFormat = "<gray>TPS<yellow>:</yellow> <tps> MSPT<yellow>:</yellow> <mspt> Ping<yellow>:</yellow> <ping>ms";
|
||||
+ 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");
|
||||
@ConfigInfo(baseName = "ping_color_list")
|
||||
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");
|
||||
@ConfigInfo(baseName = "update_interval_ticks")
|
||||
public static int updateInterval = 15;
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
|
||||
index de2f03d6e771c09e8da2da454b7ec4a16c0a17ab..0b7347e8fdf995900221ee4aa4e97a4d260c6f9f 100644
|
||||
--- a/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
|
||||
+++ b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
|
||||
@@ -128,7 +128,8 @@ public class GlobalServerTpsBar {
|
||||
TpsBarConfig.tpsBarFormat,
|
||||
Placeholder.component("tps",getTpsComponent(tps)),
|
||||
Placeholder.component("mspt",getMsptComponent(mspt)),
|
||||
- Placeholder.component("ping",getPingComponent(player.getPing()))
|
||||
+ 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)));
|
||||
@@ -170,6 +171,32 @@ public class GlobalServerTpsBar {
|
||||
return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.format("%.2f", mspt)));
|
||||
}
|
||||
|
||||
+ 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);
|
||||
+
|
||||
+ return MiniMessage.miniMessage().deserialize(replaced,Placeholder.parsed("text", String.valueOf(chunkHot)));
|
||||
+ }
|
||||
+
|
||||
+ private static BossBar.Color barColorFromChunkHot(long chunkHot){
|
||||
+ if (chunkHot == -1){
|
||||
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(3));
|
||||
+ }
|
||||
+
|
||||
+ if (chunkHot <= 300000L){
|
||||
+ return BossBar.Color.valueOf(TpsBarConfig.chunkHotColors.get(0));
|
||||
+ }
|
||||
+
|
||||
+ 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){
|
||||
return BossBar.Color.valueOf(TpsBarConfig.tpsColors.get(3));
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index de8b9048c8395c05b8688bc9d984b8ad680f15b3..f42692cd4f0154705c3d5b030d281cfc333803ed 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -437,4 +437,12 @@ public class CraftChunk implements Chunk {
|
||||
static {
|
||||
Arrays.fill(FULL_LIGHT, (byte) 0xFF);
|
||||
}
|
||||
+
|
||||
+ // KioCG start - ChunkHot
|
||||
+ @Override
|
||||
+ public long getChunkHotAvg() {
|
||||
+ final net.minecraft.world.level.chunk.LevelChunk target = this.worldServer.getChunkIfLoaded(this.x,this.z);
|
||||
+ return target == null ? -1 : target.getChunkHot().getAverage();
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 03a9f4d8e83f53326c30f00286efd1ddaaac84d2..84304fc8c26a6e1e3515b131a2ee3357262efcc3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -3611,4 +3611,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
handle.containerMenu.broadcastChanges();
|
||||
return new PaperPlayerGiveResult(leftovers.build(), drops.build());
|
||||
}
|
||||
+
|
||||
+ // KioCG start - ChunkHot
|
||||
+ @Override
|
||||
+ public long getNearbyChunkHot() {
|
||||
+ return this.getHandle().getNearbyChunkHot();
|
||||
+ }
|
||||
+ // KioCG end
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Thu, 30 Jan 2025 08:42:31 +0800
|
||||
Subject: [PATCH] Purpur Lobotomize stuck villagers
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/LobotomizeVillageConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/LobotomizeVillageConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3b30546a26634361cd6eb2dbf08af9e2608a060f
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/LobotomizeVillageConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+public class LobotomizeVillageConfig implements IConfigModule {
|
||||
+ @ConfigInfo(baseName = "enabled")
|
||||
+ public static boolean villagerLobotomizeEnabled = false;
|
||||
+ @ConfigInfo(baseName = "check_interval")
|
||||
+ public static int villagerLobotomizeCheckInterval = 100;
|
||||
+ @ConfigInfo(baseName = "wait_until_trade_locked")
|
||||
+ public static boolean villagerLobotomizeWaitUntilTradeLocked = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.OPTIMIZATIONS;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "lobotomize_villager";
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
|
||||
index bd515cdfbcc6fb0d17f70150d8b0bab60949db49..b6038fedea6251226b3b3db0f4b7a1f3d2276ab0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
|
||||
@@ -381,4 +381,11 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
|
||||
getHandle().getGossips().gossips.clear();
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public boolean isLobotomized() {
|
||||
+ return getHandle().isLobotomized();
|
||||
+ }
|
||||
+ // Purpur end
|
||||
}
|
||||
@@ -1,413 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Tue, 28 Jan 2025 18:56:59 +0800
|
||||
Subject: [PATCH] Leaf Secure seed and matter seed command
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/SecureSeedConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/SecureSeedConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..923e6dee55b765e46737ee145c32b767558c0132
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/SecureSeedConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+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.""")
|
||||
+ public static boolean enabled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.MISC;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "secure_seed";
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index f42692cd4f0154705c3d5b030d281cfc333803ed..39cc976f65f826a00e2e637c139f9134c5e74715 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -206,7 +206,12 @@ public class CraftChunk implements Chunk {
|
||||
@Override
|
||||
public boolean isSlimeChunk() {
|
||||
// 987234911L is deterimined in EntitySlime when seeing if a slime can spawn in a chunk
|
||||
- return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ boolean isSlimeChunk = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
|
||||
+ ? worldServer.getChunk(this.getX(), this.getZ()).isSlimeChunk()
|
||||
+ : WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
|
||||
+ return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || isSlimeChunk;
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index f9f20e9fd4530d0130046b56c55e798d4ede29d1..d34502a826b1582dd13c6983ed1060373837353f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1422,7 +1422,11 @@ public final class CraftServer implements Server {
|
||||
registryAccess = levelDataAndDimensions.dimensions().dimensionsRegistryAccess();
|
||||
} else {
|
||||
LevelSettings levelSettings;
|
||||
- WorldOptions worldOptions = new WorldOptions(creator.seed(), creator.generateStructures(), false);
|
||||
+ // Leaf start - Matter - Secure Seed
|
||||
+ WorldOptions worldOptions = me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled
|
||||
+ ? new WorldOptions(creator.seed(), su.plo.matter.Globals.createRandomWorldSeed(), creator.generateStructures(), false)
|
||||
+ : new WorldOptions(creator.seed(), creator.generateStructures(), false);
|
||||
+ // Leaf end - Matter - Secure Seed
|
||||
WorldDimensions worldDimensions;
|
||||
|
||||
DedicatedServerProperties.WorldDimensionData properties = new DedicatedServerProperties.WorldDimensionData(GsonHelper.parse((creator.generatorSettings().isEmpty()) ? "{}" : creator.generatorSettings()), creator.type().name().toLowerCase(Locale.ROOT));
|
||||
diff --git a/src/main/java/su/plo/matter/Globals.java b/src/main/java/su/plo/matter/Globals.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3cb89c197ca82c7f86c821fd96f6342428fff5d3
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/su/plo/matter/Globals.java
|
||||
@@ -0,0 +1,94 @@
|
||||
+package su.plo.matter;
|
||||
+
|
||||
+import com.google.common.collect.Iterables;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+
|
||||
+import java.math.BigInteger;
|
||||
+import java.security.SecureRandom;
|
||||
+import java.util.Optional;
|
||||
+
|
||||
+public class Globals {
|
||||
+ public static final int WORLD_SEED_LONGS = 16;
|
||||
+ public static final int WORLD_SEED_BITS = WORLD_SEED_LONGS * 64;
|
||||
+
|
||||
+ public static final long[] worldSeed = new long[WORLD_SEED_LONGS];
|
||||
+ public static final ThreadLocal<Integer> dimension = ThreadLocal.withInitial(() -> 0);
|
||||
+
|
||||
+ public enum Salt {
|
||||
+ UNDEFINED,
|
||||
+ BASTION_FEATURE,
|
||||
+ WOODLAND_MANSION_FEATURE,
|
||||
+ MINESHAFT_FEATURE,
|
||||
+ BURIED_TREASURE_FEATURE,
|
||||
+ NETHER_FORTRESS_FEATURE,
|
||||
+ PILLAGER_OUTPOST_FEATURE,
|
||||
+ GEODE_FEATURE,
|
||||
+ NETHER_FOSSIL_FEATURE,
|
||||
+ OCEAN_MONUMENT_FEATURE,
|
||||
+ RUINED_PORTAL_FEATURE,
|
||||
+ POTENTIONAL_FEATURE,
|
||||
+ GENERATE_FEATURE,
|
||||
+ JIGSAW_PLACEMENT,
|
||||
+ STRONGHOLDS,
|
||||
+ POPULATION,
|
||||
+ DECORATION,
|
||||
+ SLIME_CHUNK
|
||||
+ }
|
||||
+
|
||||
+ public static void setupGlobals(ServerLevel world) {
|
||||
+ if (!me.earthme.luminol.config.modules.misc.SecureSeedConfig.enabled) return;
|
||||
+
|
||||
+ long[] seed = world.getServer().getWorldData().worldGenOptions().featureSeed();
|
||||
+ System.arraycopy(seed, 0, worldSeed, 0, WORLD_SEED_LONGS);
|
||||
+ int worldIndex = Iterables.indexOf(world.getServer().levelKeys(), it -> it == world.dimension());
|
||||
+ if (worldIndex == -1)
|
||||
+ worldIndex = world.getServer().levelKeys().size(); // if we are in world construction it may not have been added to the map yet
|
||||
+ dimension.set(worldIndex);
|
||||
+ }
|
||||
+
|
||||
+ public static long[] createRandomWorldSeed() {
|
||||
+ long[] seed = new long[WORLD_SEED_LONGS];
|
||||
+ SecureRandom rand = new SecureRandom();
|
||||
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
|
||||
+ seed[i] = rand.nextLong();
|
||||
+ }
|
||||
+ return seed;
|
||||
+ }
|
||||
+
|
||||
+ // 1024-bit string -> 16 * 64 long[]
|
||||
+ public static Optional<long[]> parseSeed(String seedStr) {
|
||||
+ if (seedStr.isEmpty()) return Optional.empty();
|
||||
+
|
||||
+ if (seedStr.length() != WORLD_SEED_BITS) {
|
||||
+ throw new IllegalArgumentException("Secure seed length must be " + WORLD_SEED_BITS + "-bit but found " + seedStr.length() + "-bit.");
|
||||
+ }
|
||||
+
|
||||
+ long[] seed = new long[WORLD_SEED_LONGS];
|
||||
+
|
||||
+ for (int i = 0; i < WORLD_SEED_LONGS; i++) {
|
||||
+ int start = i * 64;
|
||||
+ int end = start + 64;
|
||||
+ String seedSection = seedStr.substring(start, end);
|
||||
+
|
||||
+ BigInteger seedInDecimal = new BigInteger(seedSection, 2);
|
||||
+ seed[i] = seedInDecimal.longValue();
|
||||
+ }
|
||||
+
|
||||
+ return Optional.of(seed);
|
||||
+ }
|
||||
+
|
||||
+ // 16 * 64 long[] -> 1024-bit string
|
||||
+ public static String seedToString(long[] seed) {
|
||||
+ StringBuilder sb = new StringBuilder();
|
||||
+
|
||||
+ for (long longV : seed) {
|
||||
+ // Convert to 64-bit binary string per long
|
||||
+ // Use format to keep 64-bit length, and use 0 to complete space
|
||||
+ String binaryStr = String.format("%64s", Long.toBinaryString(longV)).replace(' ', '0');
|
||||
+
|
||||
+ sb.append(binaryStr);
|
||||
+ }
|
||||
+
|
||||
+ return sb.toString();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/su/plo/matter/Hashing.java b/src/main/java/su/plo/matter/Hashing.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ec7a57c6af5d5f4fd27a643d253c2ecce90c01ac
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/su/plo/matter/Hashing.java
|
||||
@@ -0,0 +1,73 @@
|
||||
+package su.plo.matter;
|
||||
+
|
||||
+public class Hashing {
|
||||
+ // https://en.wikipedia.org/wiki/BLAKE_(hash_function)
|
||||
+ // https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/digests/Blake2bDigest.java
|
||||
+
|
||||
+ private final static long[] blake2b_IV = {
|
||||
+ 0x6a09e667f3bcc908L, 0xbb67ae8584caa73bL, 0x3c6ef372fe94f82bL,
|
||||
+ 0xa54ff53a5f1d36f1L, 0x510e527fade682d1L, 0x9b05688c2b3e6c1fL,
|
||||
+ 0x1f83d9abfb41bd6bL, 0x5be0cd19137e2179L
|
||||
+ };
|
||||
+
|
||||
+ private final static byte[][] blake2b_sigma = {
|
||||
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
+ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
+ {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
|
||||
+ {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
|
||||
+ {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
|
||||
+ {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
|
||||
+ {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
|
||||
+ {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
|
||||
+ {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
|
||||
+ {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
|
||||
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
+ {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}
|
||||
+ };
|
||||
+
|
||||
+ public static long[] hashWorldSeed(long[] worldSeed) {
|
||||
+ long[] result = blake2b_IV.clone();
|
||||
+ result[0] ^= 0x01010040;
|
||||
+ hash(worldSeed, result, new long[16], 0, false);
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ public static void hash(long[] message, long[] chainValue, long[] internalState, long messageOffset, boolean isFinal) {
|
||||
+ assert message.length == 16;
|
||||
+ assert chainValue.length == 8;
|
||||
+ assert internalState.length == 16;
|
||||
+
|
||||
+ System.arraycopy(chainValue, 0, internalState, 0, chainValue.length);
|
||||
+ System.arraycopy(blake2b_IV, 0, internalState, chainValue.length, 4);
|
||||
+ internalState[12] = messageOffset ^ blake2b_IV[4];
|
||||
+ internalState[13] = blake2b_IV[5];
|
||||
+ if (isFinal) internalState[14] = ~blake2b_IV[6];
|
||||
+ internalState[15] = blake2b_IV[7];
|
||||
+
|
||||
+ for (int round = 0; round < 12; round++) {
|
||||
+ G(message[blake2b_sigma[round][0]], message[blake2b_sigma[round][1]], 0, 4, 8, 12, internalState);
|
||||
+ G(message[blake2b_sigma[round][2]], message[blake2b_sigma[round][3]], 1, 5, 9, 13, internalState);
|
||||
+ G(message[blake2b_sigma[round][4]], message[blake2b_sigma[round][5]], 2, 6, 10, 14, internalState);
|
||||
+ G(message[blake2b_sigma[round][6]], message[blake2b_sigma[round][7]], 3, 7, 11, 15, internalState);
|
||||
+ G(message[blake2b_sigma[round][8]], message[blake2b_sigma[round][9]], 0, 5, 10, 15, internalState);
|
||||
+ G(message[blake2b_sigma[round][10]], message[blake2b_sigma[round][11]], 1, 6, 11, 12, internalState);
|
||||
+ G(message[blake2b_sigma[round][12]], message[blake2b_sigma[round][13]], 2, 7, 8, 13, internalState);
|
||||
+ G(message[blake2b_sigma[round][14]], message[blake2b_sigma[round][15]], 3, 4, 9, 14, internalState);
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < 8; i++) {
|
||||
+ chainValue[i] ^= internalState[i] ^ internalState[i + 8];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void G(long m1, long m2, int posA, int posB, int posC, int posD, long[] internalState) {
|
||||
+ internalState[posA] = internalState[posA] + internalState[posB] + m1;
|
||||
+ internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 32);
|
||||
+ internalState[posC] = internalState[posC] + internalState[posD];
|
||||
+ internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 24); // replaces 25 of BLAKE
|
||||
+ internalState[posA] = internalState[posA] + internalState[posB] + m2;
|
||||
+ internalState[posD] = Long.rotateRight(internalState[posD] ^ internalState[posA], 16);
|
||||
+ internalState[posC] = internalState[posC] + internalState[posD];
|
||||
+ internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/su/plo/matter/WorldgenCryptoRandom.java b/src/main/java/su/plo/matter/WorldgenCryptoRandom.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fab359afe44c573b8b315115810ddefd85b4d22b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/su/plo/matter/WorldgenCryptoRandom.java
|
||||
@@ -0,0 +1,159 @@
|
||||
+package su.plo.matter;
|
||||
+
|
||||
+import net.minecraft.util.Mth;
|
||||
+import net.minecraft.util.RandomSource;
|
||||
+import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
||||
+import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+
|
||||
+public class WorldgenCryptoRandom extends WorldgenRandom {
|
||||
+ // hash the world seed to guard against badly chosen world seeds
|
||||
+ private static final long[] HASHED_ZERO_SEED = Hashing.hashWorldSeed(new long[Globals.WORLD_SEED_LONGS]);
|
||||
+ private static final ThreadLocal<long[]> LAST_SEEN_WORLD_SEED = ThreadLocal.withInitial(() -> new long[Globals.WORLD_SEED_LONGS]);
|
||||
+ private static final ThreadLocal<long[]> HASHED_WORLD_SEED = ThreadLocal.withInitial(() -> HASHED_ZERO_SEED);
|
||||
+
|
||||
+ private final long[] worldSeed = new long[Globals.WORLD_SEED_LONGS];
|
||||
+ private final long[] randomBits = new long[8];
|
||||
+ private int randomBitIndex;
|
||||
+ private static final int MAX_RANDOM_BIT_INDEX = 64 * 8;
|
||||
+ private static final int LOG2_MAX_RANDOM_BIT_INDEX = 9;
|
||||
+ private long counter;
|
||||
+ private final long[] message = new long[16];
|
||||
+ private final long[] cachedInternalState = new long[16];
|
||||
+
|
||||
+ public WorldgenCryptoRandom(int x, int z, Globals.Salt typeSalt, long salt) {
|
||||
+ super(new LegacyRandomSource(0L));
|
||||
+ if (typeSalt != null) {
|
||||
+ this.setSecureSeed(x, z, typeSalt, salt);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void setSecureSeed(int x, int z, Globals.Salt typeSalt, long salt) {
|
||||
+ System.arraycopy(Globals.worldSeed, 0, this.worldSeed, 0, Globals.WORLD_SEED_LONGS);
|
||||
+ message[0] = ((long) x << 32) | ((long) z & 0xffffffffL);
|
||||
+ message[1] = ((long) Globals.dimension.get() << 32) | ((long) salt & 0xffffffffL);
|
||||
+ message[2] = typeSalt.ordinal();
|
||||
+ message[3] = counter = 0;
|
||||
+ randomBitIndex = MAX_RANDOM_BIT_INDEX;
|
||||
+ }
|
||||
+
|
||||
+ private long[] getHashedWorldSeed() {
|
||||
+ if (!Arrays.equals(worldSeed, LAST_SEEN_WORLD_SEED.get())) {
|
||||
+ HASHED_WORLD_SEED.set(Hashing.hashWorldSeed(worldSeed));
|
||||
+ System.arraycopy(worldSeed, 0, LAST_SEEN_WORLD_SEED.get(), 0, Globals.WORLD_SEED_LONGS);
|
||||
+ }
|
||||
+ return HASHED_WORLD_SEED.get();
|
||||
+ }
|
||||
+
|
||||
+ private void moreRandomBits() {
|
||||
+ message[3] = counter++;
|
||||
+ System.arraycopy(getHashedWorldSeed(), 0, randomBits, 0, 8);
|
||||
+ Hashing.hash(message, randomBits, cachedInternalState, 64, true);
|
||||
+ }
|
||||
+
|
||||
+ private long getBits(int count) {
|
||||
+ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) {
|
||||
+ moreRandomBits();
|
||||
+ randomBitIndex -= MAX_RANDOM_BIT_INDEX;
|
||||
+ }
|
||||
+
|
||||
+ int alignment = randomBitIndex & 63;
|
||||
+ if ((randomBitIndex >>> 6) == ((randomBitIndex + count) >>> 6)) {
|
||||
+ long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << count) - 1);
|
||||
+ randomBitIndex += count;
|
||||
+ return result;
|
||||
+ } else {
|
||||
+ long result = (randomBits[randomBitIndex >>> 6] >>> alignment) & ((1L << (64 - alignment)) - 1);
|
||||
+ randomBitIndex += count;
|
||||
+ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX) {
|
||||
+ moreRandomBits();
|
||||
+ randomBitIndex -= MAX_RANDOM_BIT_INDEX;
|
||||
+ }
|
||||
+ alignment = randomBitIndex & 63;
|
||||
+ result <<= alignment;
|
||||
+ result |= (randomBits[randomBitIndex >>> 6] >>> (64 - alignment)) & ((1L << alignment) - 1);
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull RandomSource fork() {
|
||||
+ WorldgenCryptoRandom fork = new WorldgenCryptoRandom(0, 0, null, 0);
|
||||
+
|
||||
+ System.arraycopy(Globals.worldSeed, 0, fork.worldSeed, 0, Globals.WORLD_SEED_LONGS);
|
||||
+ fork.message[0] = this.message[0];
|
||||
+ fork.message[1] = this.message[1];
|
||||
+ fork.message[2] = this.message[2];
|
||||
+ fork.message[3] = this.message[3];
|
||||
+ fork.randomBitIndex = this.randomBitIndex;
|
||||
+ fork.counter = this.counter;
|
||||
+ fork.nextLong();
|
||||
+
|
||||
+ return fork;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int next(int bits) {
|
||||
+ return (int) getBits(bits);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void consumeCount(int count) {
|
||||
+ randomBitIndex += count;
|
||||
+ if (randomBitIndex >= MAX_RANDOM_BIT_INDEX * 2) {
|
||||
+ randomBitIndex -= MAX_RANDOM_BIT_INDEX;
|
||||
+ counter += randomBitIndex >>> LOG2_MAX_RANDOM_BIT_INDEX;
|
||||
+ randomBitIndex &= MAX_RANDOM_BIT_INDEX - 1;
|
||||
+ randomBitIndex += MAX_RANDOM_BIT_INDEX;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int nextInt(int bound) {
|
||||
+ int bits = Mth.ceillog2(bound);
|
||||
+ int result;
|
||||
+ do {
|
||||
+ result = (int) getBits(bits);
|
||||
+ } while (result >= bound);
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long nextLong() {
|
||||
+ return getBits(64);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double nextDouble() {
|
||||
+ return getBits(53) * 0x1.0p-53;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long setDecorationSeed(long worldSeed, int blockX, int blockZ) {
|
||||
+ setSecureSeed(blockX, blockZ, Globals.Salt.POPULATION, 0);
|
||||
+ return ((long) blockX << 32) | ((long) blockZ & 0xffffffffL);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setFeatureSeed(long populationSeed, int index, int step) {
|
||||
+ setSecureSeed((int) (populationSeed >> 32), (int) populationSeed, Globals.Salt.DECORATION, index + 10000L * step);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLargeFeatureSeed(long worldSeed, int chunkX, int chunkZ) {
|
||||
+ super.setLargeFeatureSeed(worldSeed, chunkX, chunkZ);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLargeFeatureWithSalt(long worldSeed, int regionX, int regionZ, int salt) {
|
||||
+ super.setLargeFeatureWithSalt(worldSeed, regionX, regionZ, salt);
|
||||
+ }
|
||||
+
|
||||
+ public static RandomSource seedSlimeChunk(int chunkX, int chunkZ) {
|
||||
+ return new WorldgenCryptoRandom(chunkX, chunkZ, Globals.Salt.SLIME_CHUNK, 0);
|
||||
+ }
|
||||
+}
|
||||
@@ -1,203 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Mon, 27 Jan 2025 13:01:56 +0800
|
||||
Subject: [PATCH] Tick regions api
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/impl/RegionStatsImpl.java b/src/main/java/me/earthme/luminol/api/impl/RegionStatsImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..30d4e7b6a433974c5047148f35973eb31c82d424
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/impl/RegionStatsImpl.java
|
||||
@@ -0,0 +1,27 @@
|
||||
+package me.earthme.luminol.api.impl;
|
||||
+
|
||||
+import io.papermc.paper.threadedregions.TickRegions;
|
||||
+import me.earthme.luminol.api.RegionStats;
|
||||
+
|
||||
+public class RegionStatsImpl implements RegionStats {
|
||||
+ private final TickRegions.RegionStats internal;
|
||||
+
|
||||
+ public RegionStatsImpl(TickRegions.RegionStats internal) {
|
||||
+ this.internal = internal;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getEntityCount() {
|
||||
+ return this.internal.getEntityCount();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getPlayerCount() {
|
||||
+ return this.internal.getPlayerCount();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getChunkCount() {
|
||||
+ return this.internal.getChunkCount();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionImpl.java b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a1380abacf7bc0fe106982d9b4cd7bbc44e4e375
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionImpl.java
|
||||
@@ -0,0 +1,47 @@
|
||||
+package me.earthme.luminol.api.impl;
|
||||
+
|
||||
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
|
||||
+import io.papermc.paper.threadedregions.TickRegions;
|
||||
+import me.earthme.luminol.api.ThreadedRegion;
|
||||
+import me.earthme.luminol.api.TickRegionData;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.World;
|
||||
+
|
||||
+import javax.annotation.Nullable;
|
||||
+
|
||||
+public class ThreadedRegionImpl implements ThreadedRegion {
|
||||
+ private final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> internal;
|
||||
+
|
||||
+ public ThreadedRegionImpl(ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> internal) {
|
||||
+ this.internal = internal;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public Location getCenterChunkPos() {
|
||||
+ final ChunkPos centerChunkPos = this.internal.getCenterChunk();
|
||||
+
|
||||
+ if (centerChunkPos == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return new Location(this.internal.regioniser.world.getWorld(), centerChunkPos.getMiddleBlockX(), 0, centerChunkPos.getMiddleBlockZ());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double getDeadSectionPercent() {
|
||||
+ return this.internal.getDeadSectionPercent();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public TickRegionData getTickRegionData() {
|
||||
+ return new TickRegionDataImpl(this.internal.getData());
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public World getWorld() {
|
||||
+ return this.internal.regioniser.world.getWorld();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionizerImpl.java b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionizerImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..203ba60216febd8c19315afd89140d5400213f67
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionizerImpl.java
|
||||
@@ -0,0 +1,53 @@
|
||||
+package me.earthme.luminol.api.impl;
|
||||
+
|
||||
+import io.papermc.paper.threadedregions.TickRegions;
|
||||
+import me.earthme.luminol.api.ThreadedRegion;
|
||||
+import me.earthme.luminol.api.ThreadedRegionizer;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Collection;
|
||||
+import java.util.List;
|
||||
+
|
||||
+public class ThreadedRegionizerImpl implements ThreadedRegionizer {
|
||||
+ private final ServerLevel internal;
|
||||
+
|
||||
+ public ThreadedRegionizerImpl(ServerLevel internal) {
|
||||
+ this.internal = internal;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Collection<ThreadedRegion> getAllRegions() {
|
||||
+ final List<ThreadedRegion> ret = new ArrayList<>();
|
||||
+
|
||||
+ this.internal.regioniser.computeForAllRegions(region -> {
|
||||
+ final ThreadedRegion wrapped = new ThreadedRegionImpl(region);
|
||||
+
|
||||
+ ret.add(wrapped);
|
||||
+ });
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ThreadedRegion getAtSynchronized(int chunkX, int chunkZ) {
|
||||
+ final io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> got = this.internal.regioniser.getRegionAtSynchronised(chunkX, chunkZ);
|
||||
+
|
||||
+ if (got == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return new ThreadedRegionImpl(got);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ThreadedRegion getAtUnSynchronized(int chunkX, int chunkZ) {
|
||||
+ final io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> got = this.internal.regioniser.getRegionAtUnsynchronised(chunkX, chunkZ);
|
||||
+
|
||||
+ if (got == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return new ThreadedRegionImpl(got);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/api/impl/TickRegionDataImpl.java b/src/main/java/me/earthme/luminol/api/impl/TickRegionDataImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..cf51350ccabeda97e9eff41ccd30c58e836fe041
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/impl/TickRegionDataImpl.java
|
||||
@@ -0,0 +1,30 @@
|
||||
+package me.earthme.luminol.api.impl;
|
||||
+
|
||||
+import io.papermc.paper.threadedregions.TickRegions;
|
||||
+import me.earthme.luminol.api.RegionStats;
|
||||
+import me.earthme.luminol.api.TickRegionData;
|
||||
+import org.bukkit.World;
|
||||
+
|
||||
+public class TickRegionDataImpl implements TickRegionData {
|
||||
+ private final TickRegions.TickRegionData internal;
|
||||
+
|
||||
+ public TickRegionDataImpl(TickRegions.TickRegionData internal) {
|
||||
+ this.internal = internal;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public World getWorld() {
|
||||
+ return this.internal.world.getWorld();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getCurrentTickCount() {
|
||||
+ return this.internal.getCurrentTick();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RegionStats getRegionStats() {
|
||||
+ return new RegionStatsImpl(this.internal.getRegionStats());
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index d7973737809177b577ce029d146325194eb0831e..57944f3f12417e5727b47caad3e9d03b4720b298 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -2544,4 +2544,11 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
return this.adventure$pointers;
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Luminol start - Tick regions api
|
||||
+ @Override
|
||||
+ public me.earthme.luminol.api.ThreadedRegionizer getThreadedRegionizer() {
|
||||
+ return new me.earthme.luminol.api.impl.ThreadedRegionizerImpl(this.world);
|
||||
+ }
|
||||
+ // Luminol end
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/abomination/IRegionFile.java
|
||||
@@ -1,0 +_,39 @@
|
||||
+package abomination;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+
|
||||
+import java.io.DataInputStream;
|
||||
+import java.io.DataOutputStream;
|
||||
+import java.io.IOException;
|
||||
+import java.nio.ByteBuffer;
|
||||
+import java.nio.file.Path;
|
||||
+
|
||||
+public interface IRegionFile extends ChunkSystemRegionFile, AutoCloseable {
|
||||
+ Path getPath();
|
||||
+
|
||||
+ DataInputStream getChunkDataInputStream(ChunkPos pos) throws IOException;
|
||||
+
|
||||
+ boolean doesChunkExist(ChunkPos pos) throws Exception;
|
||||
+
|
||||
+ DataOutputStream getChunkDataOutputStream(ChunkPos pos) throws IOException;
|
||||
+
|
||||
+ void flush() throws IOException;
|
||||
+
|
||||
+ void clear(ChunkPos pos) throws IOException;
|
||||
+
|
||||
+ boolean hasChunk(ChunkPos pos);
|
||||
+
|
||||
+ void close() throws IOException;
|
||||
+
|
||||
+ void write(ChunkPos pos, ByteBuffer buf) throws IOException;
|
||||
+
|
||||
+ CompoundTag getOversizedData(int x, int z) throws IOException;
|
||||
+
|
||||
+ boolean isOversized(int x, int z);
|
||||
+
|
||||
+ boolean recalculateHeader() throws IOException;
|
||||
+
|
||||
+ void setOversized(int x, int z, boolean oversized) throws IOException;
|
||||
+}
|
||||
@@ -1,61 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 10:49:22 +0800
|
||||
Subject: [PATCH] Add configurable region format framework & linear v2 region
|
||||
format support
|
||||
|
||||
|
||||
diff --git a/src/main/java/abomination/IRegionFile.java b/src/main/java/abomination/IRegionFile.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fda43a34c89d75e3036f14da3c6efcf157189b22
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/abomination/IRegionFile.java
|
||||
@@ -0,0 +1,39 @@
|
||||
+package abomination;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+
|
||||
+import java.io.DataInputStream;
|
||||
+import java.io.DataOutputStream;
|
||||
+import java.io.IOException;
|
||||
+import java.nio.ByteBuffer;
|
||||
+import java.nio.file.Path;
|
||||
+
|
||||
+public interface IRegionFile extends ChunkSystemRegionFile, AutoCloseable {
|
||||
+ Path getPath();
|
||||
+
|
||||
+ DataInputStream getChunkDataInputStream(ChunkPos pos) throws IOException;
|
||||
+
|
||||
+ boolean doesChunkExist(ChunkPos pos) throws Exception;
|
||||
+
|
||||
+ DataOutputStream getChunkDataOutputStream(ChunkPos pos) throws IOException;
|
||||
+
|
||||
+ void flush() throws IOException;
|
||||
+
|
||||
+ void clear(ChunkPos pos) throws IOException;
|
||||
+
|
||||
+ boolean hasChunk(ChunkPos pos);
|
||||
+
|
||||
+ void close() throws IOException;
|
||||
+
|
||||
+ void write(ChunkPos pos, ByteBuffer buf) throws IOException;
|
||||
+
|
||||
+ CompoundTag getOversizedData(int x, int z) throws IOException;
|
||||
+
|
||||
+ boolean isOversized(int x, int z);
|
||||
+
|
||||
+ boolean recalculateHeader() throws IOException;
|
||||
+
|
||||
+ void setOversized(int x, int z, boolean oversized) throws IOException;
|
||||
+}
|
||||
diff --git a/src/main/java/abomination/LinearRegionFile.java b/src/main/java/abomination/LinearRegionFile.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bb0fcf5f47b5ae3d86e1d0572f951236afdcd017
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/abomination/LinearRegionFile.java
|
||||
@@ -0,0 +1,622 @@
|
||||
@@ -1,0 +_,622 @@
|
||||
+package abomination;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
|
||||
@@ -678,142 +623,3 @@ index 0000000000000000000000000000000000000000..bb0fcf5f47b5ae3d86e1d0572f951236
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..eb689b6b79143ffaf1eadcba84feca0c632d1407
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java
|
||||
@@ -0,0 +1,59 @@
|
||||
+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.utils.EnumRegionFormat;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+
|
||||
+public class RegionFormatConfig implements IConfigModule {
|
||||
+ @HotReloadUnsupported
|
||||
+ @ConfigInfo(baseName = "format")
|
||||
+ public static String format = "MCA";
|
||||
+ @HotReloadUnsupported
|
||||
+ @ConfigInfo(baseName = "linear_compression_level")
|
||||
+ public static int linearCompressionLevel = 1;
|
||||
+ @HotReloadUnsupported
|
||||
+ @ConfigInfo(baseName = "linear_io_thread_count")
|
||||
+ public static int linearIoThreadCount = 6;
|
||||
+ @HotReloadUnsupported
|
||||
+ @ConfigInfo(baseName = "linear_io_flush_delay_ms")
|
||||
+ public static int linearIoFlushDelayMs = 100;
|
||||
+ @HotReloadUnsupported
|
||||
+ @ConfigInfo(baseName = "linear_use_virtual_thread")
|
||||
+ public static boolean linearUseVirtualThread = true;
|
||||
+
|
||||
+ @DoNotLoad
|
||||
+ public static EnumRegionFormat regionFormat;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.MISC;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "region_format";
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onLoaded(CommentedFileConfig configInstance) {
|
||||
+ regionFormat = EnumRegionFormat.fromString(format.toUpperCase());
|
||||
+
|
||||
+ if (regionFormat == null) {
|
||||
+ throw new RuntimeException("Invalid region format: " + format);
|
||||
+ }
|
||||
+
|
||||
+ if (regionFormat == EnumRegionFormat.LINEAR_V2) {
|
||||
+ if (RegionFormatConfig.linearCompressionLevel > 23 || RegionFormatConfig.linearCompressionLevel < 1) {
|
||||
+ MinecraftServer.LOGGER.error("Linear region compression level should be between 1 and 22 in config: {}", RegionFormatConfig.linearCompressionLevel);
|
||||
+ MinecraftServer.LOGGER.error("Falling back to compression level 1.");
|
||||
+ RegionFormatConfig.linearCompressionLevel = 1;
|
||||
+ }
|
||||
+
|
||||
+ LinearRegionFile.SAVE_DELAY_MS = linearIoFlushDelayMs;
|
||||
+ LinearRegionFile.SAVE_THREAD_MAX_COUNT = linearIoThreadCount;
|
||||
+ LinearRegionFile.USE_VIRTUAL_THREAD = linearUseVirtualThread;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/utils/EnumRegionFormat.java b/src/main/java/me/earthme/luminol/utils/EnumRegionFormat.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..73b4f9b5f608322839cf1e37fbf1d3a147247c60
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/utils/EnumRegionFormat.java
|
||||
@@ -0,0 +1,40 @@
|
||||
+package me.earthme.luminol.utils;
|
||||
+
|
||||
+import abomination.LinearRegionFile;
|
||||
+import me.earthme.luminol.config.modules.misc.RegionFormatConfig;
|
||||
+import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||
+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));
|
||||
+
|
||||
+ private final String name;
|
||||
+ private final String argument;
|
||||
+ private final IRegionCreateFunction creator;
|
||||
+
|
||||
+ EnumRegionFormat(String name, String argument, IRegionCreateFunction creator) {
|
||||
+ this.name = name;
|
||||
+ this.argument = argument;
|
||||
+ this.creator = creator;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public static EnumRegionFormat fromString(String string) {
|
||||
+ for (EnumRegionFormat format : values()) {
|
||||
+ if (format.name.equalsIgnoreCase(string)) {
|
||||
+ return format;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ public IRegionCreateFunction getCreator() {
|
||||
+ return this.creator;
|
||||
+ }
|
||||
+
|
||||
+ public String getArgument() {
|
||||
+ return this.argument;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/utils/IRegionCreateFunction.java b/src/main/java/me/earthme/luminol/utils/IRegionCreateFunction.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fb87ef13803122aa5a2e7f0c578de359140d4f31
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/utils/IRegionCreateFunction.java
|
||||
@@ -0,0 +1,9 @@
|
||||
+package me.earthme.luminol.utils;
|
||||
+
|
||||
+import abomination.IRegionFile;
|
||||
+
|
||||
+import java.io.IOException;
|
||||
+
|
||||
+public interface IRegionCreateFunction {
|
||||
+ IRegionFile create(RegionCreatorInfo info) throws IOException;
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/utils/RegionCreatorInfo.java b/src/main/java/me/earthme/luminol/utils/RegionCreatorInfo.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5af068489646ed70330d8c6242ec88f536c4c289
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/utils/RegionCreatorInfo.java
|
||||
@@ -0,0 +1,7 @@
|
||||
+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) {}
|
||||
@@ -0,0 +1,93 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/kiocg/ChunkHot.java
|
||||
@@ -1,0 +_,90 @@
|
||||
+package com.kiocg;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+
|
||||
+public class ChunkHot {
|
||||
+ // 热度统计总区间数量
|
||||
+ private static final int TIMES_LENGTH = 10;
|
||||
+ // 当前统计区间下标
|
||||
+ private int index = -1;
|
||||
+
|
||||
+ // 热度统计区间
|
||||
+ private final long[] times = new long[TIMES_LENGTH];
|
||||
+ // 存放临时的区间数值
|
||||
+ // 用于修正正在统计的当前区间热度没有计入总值的问题
|
||||
+ private long temp;
|
||||
+ // 所有区间的热度总值
|
||||
+ private long total;
|
||||
+
|
||||
+ // 用于每个具体统计的计算
|
||||
+ private long nanos;
|
||||
+ // 当前统计是否进行中
|
||||
+ private volatile boolean started = false;
|
||||
+
|
||||
+ /**
|
||||
+ * 更新区间下标
|
||||
+ */
|
||||
+ public void nextTick() {
|
||||
+ this.index = ++this.index % TIMES_LENGTH;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 开始统计一个新区间
|
||||
+ */
|
||||
+ public void start() {
|
||||
+ started = true;
|
||||
+ temp = times[this.index];
|
||||
+ times[this.index] = 0L;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isStarted(){
|
||||
+ return this.started;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 结束当前区间的统计
|
||||
+ * 将统计值更新入热度总值
|
||||
+ */
|
||||
+ public void stop() {
|
||||
+ started = false;
|
||||
+ total -= temp;
|
||||
+ total += times[this.index];
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 开始一个具体统计
|
||||
+ */
|
||||
+ public void startTicking() {
|
||||
+ if (!started) return;
|
||||
+ nanos = System.nanoTime();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 结束一个具体统计
|
||||
+ * 将统计值计入当前热度区间
|
||||
+ */
|
||||
+ public void stopTickingAndCount() {
|
||||
+ if (!started) return;
|
||||
+ // 定义一个具体统计的最大值为 1,000,000
|
||||
+ // 有时候某个具体统计的计算值会在某1刻飙升,可能是由于保存数据到磁盘?
|
||||
+ times[this.index] += Math.min(System.nanoTime() - nanos, 1000000L);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * 清空统计 (当区块卸载时)
|
||||
+ */
|
||||
+ public void clear() {
|
||||
+ started = false;
|
||||
+ Arrays.fill(times, 0L);
|
||||
+ temp = 0L;
|
||||
+ total = 0L;
|
||||
+ nanos = 0L;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return 获取区块热度平均值
|
||||
+ */
|
||||
+ public long getAverage() {
|
||||
+ return total / ((long) TIMES_LENGTH * 20L);
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,37 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java
|
||||
@@ -1,0 +_,34 @@
|
||||
+package com.logisticscraft.occlusionculling;
|
||||
+
|
||||
+import com.logisticscraft.occlusionculling.util.Vec3d;
|
||||
+
|
||||
+public interface DataProvider {
|
||||
+
|
||||
+ /**
|
||||
+ * Prepares the requested chunk. Returns true if the chunk is ready, false when
|
||||
+ * not loaded. Should not reload the chunk when the x and y are the same as the
|
||||
+ * last request!
|
||||
+ *
|
||||
+ * @param chunkX
|
||||
+ * @param chunkZ
|
||||
+ * @return
|
||||
+ */
|
||||
+ boolean prepareChunk(int chunkX, int chunkZ);
|
||||
+
|
||||
+ /**
|
||||
+ * Location is inside the chunk.
|
||||
+ *
|
||||
+ * @param x
|
||||
+ * @param y
|
||||
+ * @param z
|
||||
+ * @return
|
||||
+ */
|
||||
+ boolean isOpaqueFullCube(int x, int y, int z);
|
||||
+
|
||||
+ default void cleanup() {
|
||||
+ }
|
||||
+
|
||||
+ default void checkingPosition(Vec3d[] targetPoints, int size, Vec3d viewerPosition) {
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -1,57 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Wed, 5 Feb 2025 15:22:21 +0800
|
||||
Subject: [PATCH] Raytracing tracker experiment
|
||||
|
||||
Based on the framework of EntityCulling(((((((
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java b/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5ab4600554e8dcb2a2ddc22dd1c1015c89ba5b82
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package com.logisticscraft.occlusionculling;
|
||||
+
|
||||
+import com.logisticscraft.occlusionculling.util.Vec3d;
|
||||
+
|
||||
+public interface DataProvider {
|
||||
+
|
||||
+ /**
|
||||
+ * Prepares the requested chunk. Returns true if the chunk is ready, false when
|
||||
+ * not loaded. Should not reload the chunk when the x and y are the same as the
|
||||
+ * last request!
|
||||
+ *
|
||||
+ * @param chunkX
|
||||
+ * @param chunkZ
|
||||
+ * @return
|
||||
+ */
|
||||
+ boolean prepareChunk(int chunkX, int chunkZ);
|
||||
+
|
||||
+ /**
|
||||
+ * Location is inside the chunk.
|
||||
+ *
|
||||
+ * @param x
|
||||
+ * @param y
|
||||
+ * @param z
|
||||
+ * @return
|
||||
+ */
|
||||
+ boolean isOpaqueFullCube(int x, int y, int z);
|
||||
+
|
||||
+ default void cleanup() {
|
||||
+ }
|
||||
+
|
||||
+ default void checkingPosition(Vec3d[] targetPoints, int size, Vec3d viewerPosition) {
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java b/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..30efa77d8ed337e9f044c41a10c6ecfd5ec162e2
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java
|
||||
@@ -0,0 +1,515 @@
|
||||
@@ -1,0 +_,515 @@
|
||||
+package com.logisticscraft.occlusionculling;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
@@ -567,477 +516,3 @@ index 0000000000000000000000000000000000000000..30efa77d8ed337e9f044c41a10c6ecfd
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java b/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..08f0ddb343c12ac781ee33f1a7da1462573405b9
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java
|
||||
@@ -0,0 +1,57 @@
|
||||
+package com.logisticscraft.occlusionculling.cache;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+
|
||||
+public class ArrayOcclusionCache implements OcclusionCache {
|
||||
+
|
||||
+ private final int reachX2;
|
||||
+ private final byte[] cache;
|
||||
+ private int positionKey;
|
||||
+ private int entry;
|
||||
+ private int offset;
|
||||
+
|
||||
+ public ArrayOcclusionCache(int reach) {
|
||||
+ this.reachX2 = reach * 2;
|
||||
+ this.cache = new byte[(reachX2 * reachX2 * reachX2) / 4];
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetCache() {
|
||||
+ Arrays.fill(cache, (byte) 0);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setVisible(int x, int y, int z) {
|
||||
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
|
||||
+ entry = positionKey / 4;
|
||||
+ offset = (positionKey % 4) * 2;
|
||||
+ cache[entry] |= 1 << offset;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHidden(int x, int y, int z) {
|
||||
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
|
||||
+ entry = positionKey / 4;
|
||||
+ offset = (positionKey % 4) * 2;
|
||||
+ cache[entry] |= 1 << offset + 1;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getState(int x, int y, int z) {
|
||||
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
|
||||
+ entry = positionKey / 4;
|
||||
+ offset = (positionKey % 4) * 2;
|
||||
+ return cache[entry] >> offset & 3;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLastVisible() {
|
||||
+ cache[entry] |= 1 << offset;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLastHidden() {
|
||||
+ cache[entry] |= 1 << offset + 1;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java b/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2a2e5620fb2b1a71fbca2068fc049bfa89a47737
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package com.logisticscraft.occlusionculling.cache;
|
||||
+
|
||||
+public interface OcclusionCache {
|
||||
+
|
||||
+ void resetCache();
|
||||
+
|
||||
+ void setVisible(int x, int y, int z);
|
||||
+
|
||||
+ void setHidden(int x, int y, int z);
|
||||
+
|
||||
+ int getState(int x, int y, int z);
|
||||
+
|
||||
+ void setLastHidden();
|
||||
+
|
||||
+ void setLastVisible();
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java b/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fb28265631b079eb5da8ae3a7ecca6e343f8c0b6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java
|
||||
@@ -0,0 +1,25 @@
|
||||
+package com.logisticscraft.occlusionculling.util;
|
||||
+
|
||||
+/**
|
||||
+ * Contains MathHelper methods
|
||||
+ */
|
||||
+public final class MathUtilities {
|
||||
+
|
||||
+ private MathUtilities() {
|
||||
+ }
|
||||
+
|
||||
+ public static int floor(double d) {
|
||||
+ int i = (int) d;
|
||||
+ return d < (double) i ? i - 1 : i;
|
||||
+ }
|
||||
+
|
||||
+ public static int fastFloor(double d) {
|
||||
+ return (int) (d + 1024.0) - 1024;
|
||||
+ }
|
||||
+
|
||||
+ public static int ceil(double d) {
|
||||
+ int i = (int) d;
|
||||
+ return d > (double) i ? i + 1 : i;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java b/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7e3cb9e11f65af0627164c8dbd6aad3e5690d36c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java
|
||||
@@ -0,0 +1,87 @@
|
||||
+package com.logisticscraft.occlusionculling.util;
|
||||
+
|
||||
+public class Vec3d {
|
||||
+
|
||||
+ public double x;
|
||||
+ public double y;
|
||||
+ public double z;
|
||||
+
|
||||
+ public Vec3d(double x, double y, double z) {
|
||||
+ this.x = x;
|
||||
+ this.y = y;
|
||||
+ this.z = z;
|
||||
+ }
|
||||
+
|
||||
+ public double getX() {
|
||||
+ return x;
|
||||
+ }
|
||||
+
|
||||
+ public double getY() {
|
||||
+ return y;
|
||||
+ }
|
||||
+
|
||||
+ public double getZ() {
|
||||
+ return z;
|
||||
+ }
|
||||
+
|
||||
+ public void set(double x, double y, double z) {
|
||||
+ this.x = x;
|
||||
+ this.y = y;
|
||||
+ this.z = z;
|
||||
+ }
|
||||
+
|
||||
+ public void setAdd(Vec3d vec, double x, double y, double z) {
|
||||
+ this.x = vec.x + x;
|
||||
+ this.y = vec.y + y;
|
||||
+ this.z = vec.z + z;
|
||||
+ }
|
||||
+
|
||||
+ public Vec3d div(Vec3d rayDir) {
|
||||
+ this.x /= rayDir.x;
|
||||
+ this.z /= rayDir.z;
|
||||
+ this.y /= rayDir.y;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ public Vec3d normalize() {
|
||||
+ double mag = Math.sqrt(x*x+y*y+z*z);
|
||||
+ this.x /= mag;
|
||||
+ this.y /= mag;
|
||||
+ this.z /= mag;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ public boolean equals(Object other) {
|
||||
+ if (this == other) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (!(other instanceof Vec3d)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ Vec3d vec3d = (Vec3d) other;
|
||||
+ if (Double.compare(vec3d.x, x) != 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (Double.compare(vec3d.y, y) != 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return Double.compare(vec3d.z, z) == 0;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ long l = Double.doubleToLongBits(x);
|
||||
+ int i = (int) (l ^ l >>> 32);
|
||||
+ l = Double.doubleToLongBits(y);
|
||||
+ i = 31 * i + (int) (l ^ l >>> 32);
|
||||
+ l = Double.doubleToLongBits(z);
|
||||
+ i = 31 * i + (int) (l ^ l >>> 32);
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "(" + x + ", " + y + ", " + z + ")";
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/dev/tr7zw/entityculling/CullTask.java b/src/main/java/dev/tr7zw/entityculling/CullTask.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..57e36d4a2c770a3d2ae72a78e69802dd119e6999
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/tr7zw/entityculling/CullTask.java
|
||||
@@ -0,0 +1,152 @@
|
||||
+package dev.tr7zw.entityculling;
|
||||
+
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+import java.util.concurrent.Executor;
|
||||
+import java.util.concurrent.Executors;
|
||||
+import java.util.concurrent.TimeUnit;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||
+import com.logisticscraft.occlusionculling.OcclusionCullingInstance;
|
||||
+import com.logisticscraft.occlusionculling.util.Vec3d;
|
||||
+
|
||||
+import dev.tr7zw.entityculling.versionless.access.Cullable;
|
||||
+import me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.entity.decoration.ArmorStand;
|
||||
+import net.minecraft.world.entity.player.Player;
|
||||
+import net.minecraft.world.phys.AABB;
|
||||
+import net.minecraft.world.phys.Vec3;
|
||||
+
|
||||
+public class CullTask implements Runnable {
|
||||
+
|
||||
+ private volatile boolean requestCull = false;
|
||||
+ private volatile boolean scheduleNext = true;
|
||||
+ private volatile boolean inited = false;
|
||||
+
|
||||
+ private final OcclusionCullingInstance culling;
|
||||
+ private final Player checkTarget;
|
||||
+
|
||||
+ private final int hitboxLimit;
|
||||
+
|
||||
+ public long lastCheckedTime = 0;
|
||||
+
|
||||
+ // reused preallocated vars
|
||||
+ private final Vec3d lastPos = new Vec3d(0, 0, 0);
|
||||
+ private final Vec3d aabbMin = new Vec3d(0, 0, 0);
|
||||
+ private final Vec3d aabbMax = new Vec3d(0, 0, 0);
|
||||
+
|
||||
+ private static final Executor backgroundWorker = Executors.newCachedThreadPool(task -> {
|
||||
+ final TickThread worker = new TickThread("EntityCulling") {
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ task.run();
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ worker.setDaemon(true);
|
||||
+
|
||||
+ return worker;
|
||||
+ });
|
||||
+
|
||||
+ private final Executor worker;
|
||||
+
|
||||
+ public CullTask(
|
||||
+ OcclusionCullingInstance culling,
|
||||
+ Player checkTarget,
|
||||
+ int hitboxLimit,
|
||||
+ long checkIntervalMs
|
||||
+ ) {
|
||||
+ this.culling = culling;
|
||||
+ this.checkTarget = checkTarget;
|
||||
+ this.hitboxLimit = hitboxLimit;
|
||||
+ this.worker = CompletableFuture.delayedExecutor(checkIntervalMs, TimeUnit.MILLISECONDS, backgroundWorker);
|
||||
+ }
|
||||
+
|
||||
+ public void requestCullSignal() {
|
||||
+ this.requestCull = true;
|
||||
+ }
|
||||
+
|
||||
+ public void signalStop() {
|
||||
+ this.scheduleNext = false;
|
||||
+ }
|
||||
+
|
||||
+ public void setup() {
|
||||
+ if (!this.inited)
|
||||
+ this.inited = true;
|
||||
+ else
|
||||
+ return;
|
||||
+ this.worker.execute(this);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ try {
|
||||
+ if (this.checkTarget.tickCount > 10) {
|
||||
+ // getEyePosition can use a fixed delta as its debug only anyway
|
||||
+ Vec3 cameraMC = this.checkTarget.getEyePosition(0);
|
||||
+ if (requestCull || !(cameraMC.x == lastPos.x && cameraMC.y == lastPos.y && cameraMC.z == lastPos.z)) {
|
||||
+ long start = System.currentTimeMillis();
|
||||
+
|
||||
+ requestCull = false;
|
||||
+
|
||||
+ lastPos.set(cameraMC.x, cameraMC.y, cameraMC.z);
|
||||
+ culling.resetCache();
|
||||
+
|
||||
+ cullEntities(cameraMC, lastPos);
|
||||
+
|
||||
+ lastCheckedTime = (System.currentTimeMillis() - start);
|
||||
+ }
|
||||
+ }
|
||||
+ }finally {
|
||||
+ if (this.scheduleNext) {
|
||||
+ this.worker.execute(this);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void cullEntities(Vec3 cameraMC, Vec3d camera) {
|
||||
+ for (Entity entity : this.checkTarget.level().getEntities().getAll()) {
|
||||
+ if (!(entity instanceof Cullable cullable)) {
|
||||
+ continue; // Not sure how this could happen outside from mixin screwing up the inject into
|
||||
+ // Entity
|
||||
+ }
|
||||
+
|
||||
+ if (entity.getType().skipRaytracningCheck) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!cullable.isForcedVisible()) {
|
||||
+ if (entity.isCurrentlyGlowing() || isSkippableArmorstand(entity)) {
|
||||
+ cullable.setCulled(false);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!entity.position().closerThan(cameraMC, me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance)) {
|
||||
+ cullable.setCulled(false); // If your entity view distance is larger than tracingDistance just
|
||||
+ // render it
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ AABB boundingBox = entity.getBoundingBox();
|
||||
+ if (boundingBox.getXsize() > hitboxLimit || boundingBox.getYsize() > hitboxLimit
|
||||
+ || boundingBox.getZsize() > hitboxLimit) {
|
||||
+ cullable.setCulled(false); // To big to bother to cull
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ aabbMin.set(boundingBox.minX, boundingBox.minY, boundingBox.minZ);
|
||||
+ aabbMax.set(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ);
|
||||
+
|
||||
+ boolean visible = culling.isAABBVisible(aabbMin, aabbMax, camera);
|
||||
+
|
||||
+ cullable.setCulled(!visible);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private boolean isSkippableArmorstand(Entity entity) {
|
||||
+ if (!RayTrackingEntityTrackerConfig.skipMarkerArmorStands)
|
||||
+ return false;
|
||||
+ return entity instanceof ArmorStand && entity.isInvisible();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/dev/tr7zw/entityculling/DefaultChunkDataProvider.java b/src/main/java/dev/tr7zw/entityculling/DefaultChunkDataProvider.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..aadf7cdc4a28ecf92853e147fa115d43c89f6fe8
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/tr7zw/entityculling/DefaultChunkDataProvider.java
|
||||
@@ -0,0 +1,43 @@
|
||||
+package dev.tr7zw.entityculling;
|
||||
+
|
||||
+import com.logisticscraft.occlusionculling.DataProvider;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.Blocks;
|
||||
+import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
+import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
+
|
||||
+public class DefaultChunkDataProvider implements DataProvider {
|
||||
+ private final Level level;
|
||||
+
|
||||
+ public DefaultChunkDataProvider(Level level) {
|
||||
+ this.level = level;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean prepareChunk(int chunkX, int chunkZ) {
|
||||
+ return this.level.getChunkIfLoaded(chunkX, chunkZ) != null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isOpaqueFullCube(int x, int y, int z) {
|
||||
+ BlockPos pos = new BlockPos(x, y, z);
|
||||
+
|
||||
+ final ChunkAccess access = this.level.getChunkIfLoaded(pos);
|
||||
+ if (access == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (this.level.isOutsideBuildHeight(pos)) {
|
||||
+ return Blocks.VOID_AIR.defaultBlockState().isSolidRender();
|
||||
+ } else {
|
||||
+ return access.getBlockState(pos).isSolidRender();// 好孩子不要学坏叔叔这样绕过异步拦截()
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void cleanup() {
|
||||
+ DataProvider.super.cleanup();
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/dev/tr7zw/entityculling/versionless/access/Cullable.java b/src/main/java/dev/tr7zw/entityculling/versionless/access/Cullable.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..948e8e934793532704161e0a129ebf86355ba5a8
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/tr7zw/entityculling/versionless/access/Cullable.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package dev.tr7zw.entityculling.versionless.access;
|
||||
+
|
||||
+public interface Cullable {
|
||||
+
|
||||
+ public void setTimeout();
|
||||
+
|
||||
+ public boolean isForcedVisible();
|
||||
+
|
||||
+ public void setCulled(boolean value);
|
||||
+
|
||||
+ public boolean isCulled();
|
||||
+
|
||||
+ public void setOutOfCamera(boolean value);
|
||||
+
|
||||
+ public boolean isOutOfCamera();
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/RayTrackingEntityTrackerConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/RayTrackingEntityTrackerConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1e3e6a500c9eb26a06f5441f9e542dc9b1ad0cf4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/RayTrackingEntityTrackerConfig.java
|
||||
@@ -0,0 +1,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;
|
||||
+
|
||||
+public class RayTrackingEntityTrackerConfig implements IConfigModule {
|
||||
+ @ConfigInfo(baseName = "enabled")
|
||||
+ public static boolean enabled = false;
|
||||
+ @ConfigInfo(baseName = "skip_marker_armor_stands")
|
||||
+ public static boolean skipMarkerArmorStands = true;
|
||||
+ @ConfigInfo(baseName = "check_interval_ms")
|
||||
+ public static int checkIntervalMs = 10;
|
||||
+ @ConfigInfo(baseName = "tracing_distance")
|
||||
+ public static int tracingDistance = 48;
|
||||
+ @ConfigInfo(baseName = "hitbox_limit")
|
||||
+ public static int hitboxLimit = 50;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.EXPERIMENT;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "ray_tracking_entity_tracker";
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,60 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java
|
||||
@@ -1,0 +_,57 @@
|
||||
+package com.logisticscraft.occlusionculling.cache;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+
|
||||
+public class ArrayOcclusionCache implements OcclusionCache {
|
||||
+
|
||||
+ private final int reachX2;
|
||||
+ private final byte[] cache;
|
||||
+ private int positionKey;
|
||||
+ private int entry;
|
||||
+ private int offset;
|
||||
+
|
||||
+ public ArrayOcclusionCache(int reach) {
|
||||
+ this.reachX2 = reach * 2;
|
||||
+ this.cache = new byte[(reachX2 * reachX2 * reachX2) / 4];
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetCache() {
|
||||
+ Arrays.fill(cache, (byte) 0);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setVisible(int x, int y, int z) {
|
||||
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
|
||||
+ entry = positionKey / 4;
|
||||
+ offset = (positionKey % 4) * 2;
|
||||
+ cache[entry] |= 1 << offset;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHidden(int x, int y, int z) {
|
||||
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
|
||||
+ entry = positionKey / 4;
|
||||
+ offset = (positionKey % 4) * 2;
|
||||
+ cache[entry] |= 1 << offset + 1;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getState(int x, int y, int z) {
|
||||
+ positionKey = x + y * reachX2 + z * reachX2 * reachX2;
|
||||
+ entry = positionKey / 4;
|
||||
+ offset = (positionKey % 4) * 2;
|
||||
+ return cache[entry] >> offset & 3;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLastVisible() {
|
||||
+ cache[entry] |= 1 << offset;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLastHidden() {
|
||||
+ cache[entry] |= 1 << offset + 1;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -0,0 +1,20 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java
|
||||
@@ -1,0 +_,17 @@
|
||||
+package com.logisticscraft.occlusionculling.cache;
|
||||
+
|
||||
+public interface OcclusionCache {
|
||||
+
|
||||
+ void resetCache();
|
||||
+
|
||||
+ void setVisible(int x, int y, int z);
|
||||
+
|
||||
+ void setHidden(int x, int y, int z);
|
||||
+
|
||||
+ int getState(int x, int y, int z);
|
||||
+
|
||||
+ void setLastHidden();
|
||||
+
|
||||
+ void setLastVisible();
|
||||
+
|
||||
+}
|
||||
@@ -0,0 +1,28 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java
|
||||
@@ -1,0 +_,25 @@
|
||||
+package com.logisticscraft.occlusionculling.util;
|
||||
+
|
||||
+/**
|
||||
+ * Contains MathHelper methods
|
||||
+ */
|
||||
+public final class MathUtilities {
|
||||
+
|
||||
+ private MathUtilities() {
|
||||
+ }
|
||||
+
|
||||
+ public static int floor(double d) {
|
||||
+ int i = (int) d;
|
||||
+ return d < (double) i ? i - 1 : i;
|
||||
+ }
|
||||
+
|
||||
+ public static int fastFloor(double d) {
|
||||
+ return (int) (d + 1024.0) - 1024;
|
||||
+ }
|
||||
+
|
||||
+ public static int ceil(double d) {
|
||||
+ int i = (int) d;
|
||||
+ return d > (double) i ? i + 1 : i;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -0,0 +1,90 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java
|
||||
@@ -1,0 +_,87 @@
|
||||
+package com.logisticscraft.occlusionculling.util;
|
||||
+
|
||||
+public class Vec3d {
|
||||
+
|
||||
+ public double x;
|
||||
+ public double y;
|
||||
+ public double z;
|
||||
+
|
||||
+ public Vec3d(double x, double y, double z) {
|
||||
+ this.x = x;
|
||||
+ this.y = y;
|
||||
+ this.z = z;
|
||||
+ }
|
||||
+
|
||||
+ public double getX() {
|
||||
+ return x;
|
||||
+ }
|
||||
+
|
||||
+ public double getY() {
|
||||
+ return y;
|
||||
+ }
|
||||
+
|
||||
+ public double getZ() {
|
||||
+ return z;
|
||||
+ }
|
||||
+
|
||||
+ public void set(double x, double y, double z) {
|
||||
+ this.x = x;
|
||||
+ this.y = y;
|
||||
+ this.z = z;
|
||||
+ }
|
||||
+
|
||||
+ public void setAdd(Vec3d vec, double x, double y, double z) {
|
||||
+ this.x = vec.x + x;
|
||||
+ this.y = vec.y + y;
|
||||
+ this.z = vec.z + z;
|
||||
+ }
|
||||
+
|
||||
+ public Vec3d div(Vec3d rayDir) {
|
||||
+ this.x /= rayDir.x;
|
||||
+ this.z /= rayDir.z;
|
||||
+ this.y /= rayDir.y;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ public Vec3d normalize() {
|
||||
+ double mag = Math.sqrt(x*x+y*y+z*z);
|
||||
+ this.x /= mag;
|
||||
+ this.y /= mag;
|
||||
+ this.z /= mag;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ public boolean equals(Object other) {
|
||||
+ if (this == other) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (!(other instanceof Vec3d)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ Vec3d vec3d = (Vec3d) other;
|
||||
+ if (Double.compare(vec3d.x, x) != 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (Double.compare(vec3d.y, y) != 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return Double.compare(vec3d.z, z) == 0;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ long l = Double.doubleToLongBits(x);
|
||||
+ int i = (int) (l ^ l >>> 32);
|
||||
+ l = Double.doubleToLongBits(y);
|
||||
+ i = 31 * i + (int) (l ^ l >>> 32);
|
||||
+ l = Double.doubleToLongBits(z);
|
||||
+ i = 31 * i + (int) (l ^ l >>> 32);
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "(" + x + ", " + y + ", " + z + ")";
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -1,15 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 11:07:09 +0800
|
||||
Subject: [PATCH] Kaiiju Entity tick and removal limiter
|
||||
|
||||
|
||||
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityLimits.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityLimits.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..40e80fc685a42bbaeea3e6e64754121178cc7d22
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityLimits.java
|
||||
@@ -0,0 +1,141 @@
|
||||
@@ -1,0 +_,141 @@
|
||||
+package dev.kaiijumc.kaiiju;
|
||||
+
|
||||
+import java.io.File;
|
||||
@@ -151,122 +142,3 @@ index 0000000000000000000000000000000000000000..40e80fc685a42bbaeea3e6e647541211
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityThrottler.java b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityThrottler.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..eb690efacf083e4ff3e321578b12c534e6a40196
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityThrottler.java
|
||||
@@ -0,0 +1,84 @@
|
||||
+package dev.kaiijumc.kaiiju;
|
||||
+
|
||||
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import io.papermc.paper.threadedregions.RegionizedWorldData;
|
||||
+
|
||||
+public class KaiijuEntityThrottler {
|
||||
+ private static class TickInfo {
|
||||
+ int currentTick;
|
||||
+ int continueFrom;
|
||||
+ int toTick;
|
||||
+ int toRemove;
|
||||
+ }
|
||||
+
|
||||
+ public static class EntityThrottlerReturn {
|
||||
+ public boolean skip;
|
||||
+ public boolean remove;
|
||||
+ }
|
||||
+
|
||||
+ private final Object2ObjectOpenHashMap<KaiijuEntityLimits.EntityLimit, TickInfo> entityLimitTickInfoMap = new Object2ObjectOpenHashMap<>();
|
||||
+
|
||||
+ public void tickLimiterStart() {
|
||||
+ for (TickInfo tickInfo : entityLimitTickInfoMap.values()) {
|
||||
+ tickInfo.currentTick = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public EntityThrottlerReturn tickLimiterShouldSkip(Entity entity) {
|
||||
+ EntityThrottlerReturn retVal = new EntityThrottlerReturn();
|
||||
+ if (entity.isRemoved()) return retVal;
|
||||
+ KaiijuEntityLimits.EntityLimit entityLimit = KaiijuEntityLimits.getEntityLimit(entity);
|
||||
+
|
||||
+ if (entityLimit != null) {
|
||||
+ TickInfo tickInfo = entityLimitTickInfoMap.computeIfAbsent(entityLimit, el -> {
|
||||
+ TickInfo newTickInfo = new TickInfo();
|
||||
+ newTickInfo.toTick = entityLimit.limit();
|
||||
+ return newTickInfo;
|
||||
+ });
|
||||
+
|
||||
+ tickInfo.currentTick++;
|
||||
+ if (tickInfo.currentTick <= tickInfo.toRemove && entityLimit.removal() > 0) {
|
||||
+ retVal.skip = false;
|
||||
+ retVal.remove = true;
|
||||
+ return retVal;
|
||||
+ }
|
||||
+
|
||||
+ if (tickInfo.currentTick < tickInfo.continueFrom) {
|
||||
+ retVal.skip = true;
|
||||
+ return retVal;
|
||||
+ }
|
||||
+ if (tickInfo.currentTick - tickInfo.continueFrom < tickInfo.toTick) {
|
||||
+ retVal.skip = false;
|
||||
+ return retVal;
|
||||
+ }
|
||||
+ retVal.skip = true;
|
||||
+ return retVal;
|
||||
+ } else {
|
||||
+ retVal.skip = false;
|
||||
+ return retVal;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void tickLimiterFinish(RegionizedWorldData regionizedWorldData) {
|
||||
+ for (var entry : entityLimitTickInfoMap.entrySet()) {
|
||||
+ KaiijuEntityLimits.EntityLimit entityLimit = entry.getKey();
|
||||
+ TickInfo tickInfo = entry.getValue();
|
||||
+
|
||||
+ int additionals = 0;
|
||||
+ int nextContinueFrom = tickInfo.continueFrom + tickInfo.toTick;
|
||||
+ if (nextContinueFrom >= tickInfo.currentTick) {
|
||||
+ additionals = entityLimit.limit() - (tickInfo.currentTick - tickInfo.continueFrom);
|
||||
+ nextContinueFrom = 0;
|
||||
+ }
|
||||
+ tickInfo.continueFrom = nextContinueFrom;
|
||||
+ tickInfo.toTick = entityLimit.limit() + additionals;
|
||||
+
|
||||
+ if (tickInfo.toRemove == 0 && tickInfo.currentTick > entityLimit.removal()) {
|
||||
+ tickInfo.toRemove = tickInfo.currentTick - entityLimit.removal();
|
||||
+ } else if (tickInfo.toRemove != 0) {
|
||||
+ tickInfo.toRemove = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/KaiijuEntityLimiterConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/KaiijuEntityLimiterConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..038d9ab60cfac7e40e7c0c0644fa0a0d035eac01
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/KaiijuEntityLimiterConfig.java
|
||||
@@ -0,0 +1,23 @@
|
||||
+package me.earthme.luminol.config.modules.misc;
|
||||
+
|
||||
+import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
||||
+import dev.kaiijumc.kaiiju.KaiijuEntityLimits;
|
||||
+import me.earthme.luminol.config.EnumConfigCategory;
|
||||
+import me.earthme.luminol.config.IConfigModule;
|
||||
+
|
||||
+public class KaiijuEntityLimiterConfig implements IConfigModule {
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.MISC;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "kaiiju_entity_limiter";
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onLoaded(CommentedFileConfig configInstance) {
|
||||
+ KaiijuEntityLimits.init();
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,87 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/kaiijumc/kaiiju/KaiijuEntityThrottler.java
|
||||
@@ -1,0 +_,84 @@
|
||||
+package dev.kaiijumc.kaiiju;
|
||||
+
|
||||
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import io.papermc.paper.threadedregions.RegionizedWorldData;
|
||||
+
|
||||
+public class KaiijuEntityThrottler {
|
||||
+ private static class TickInfo {
|
||||
+ int currentTick;
|
||||
+ int continueFrom;
|
||||
+ int toTick;
|
||||
+ int toRemove;
|
||||
+ }
|
||||
+
|
||||
+ public static class EntityThrottlerReturn {
|
||||
+ public boolean skip;
|
||||
+ public boolean remove;
|
||||
+ }
|
||||
+
|
||||
+ private final Object2ObjectOpenHashMap<KaiijuEntityLimits.EntityLimit, TickInfo> entityLimitTickInfoMap = new Object2ObjectOpenHashMap<>();
|
||||
+
|
||||
+ public void tickLimiterStart() {
|
||||
+ for (TickInfo tickInfo : entityLimitTickInfoMap.values()) {
|
||||
+ tickInfo.currentTick = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public EntityThrottlerReturn tickLimiterShouldSkip(Entity entity) {
|
||||
+ EntityThrottlerReturn retVal = new EntityThrottlerReturn();
|
||||
+ if (entity.isRemoved()) return retVal;
|
||||
+ KaiijuEntityLimits.EntityLimit entityLimit = KaiijuEntityLimits.getEntityLimit(entity);
|
||||
+
|
||||
+ if (entityLimit != null) {
|
||||
+ TickInfo tickInfo = entityLimitTickInfoMap.computeIfAbsent(entityLimit, el -> {
|
||||
+ TickInfo newTickInfo = new TickInfo();
|
||||
+ newTickInfo.toTick = entityLimit.limit();
|
||||
+ return newTickInfo;
|
||||
+ });
|
||||
+
|
||||
+ tickInfo.currentTick++;
|
||||
+ if (tickInfo.currentTick <= tickInfo.toRemove && entityLimit.removal() > 0) {
|
||||
+ retVal.skip = false;
|
||||
+ retVal.remove = true;
|
||||
+ return retVal;
|
||||
+ }
|
||||
+
|
||||
+ if (tickInfo.currentTick < tickInfo.continueFrom) {
|
||||
+ retVal.skip = true;
|
||||
+ return retVal;
|
||||
+ }
|
||||
+ if (tickInfo.currentTick - tickInfo.continueFrom < tickInfo.toTick) {
|
||||
+ retVal.skip = false;
|
||||
+ return retVal;
|
||||
+ }
|
||||
+ retVal.skip = true;
|
||||
+ return retVal;
|
||||
+ } else {
|
||||
+ retVal.skip = false;
|
||||
+ return retVal;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void tickLimiterFinish(RegionizedWorldData regionizedWorldData) {
|
||||
+ for (var entry : entityLimitTickInfoMap.entrySet()) {
|
||||
+ KaiijuEntityLimits.EntityLimit entityLimit = entry.getKey();
|
||||
+ TickInfo tickInfo = entry.getValue();
|
||||
+
|
||||
+ int additionals = 0;
|
||||
+ int nextContinueFrom = tickInfo.continueFrom + tickInfo.toTick;
|
||||
+ if (nextContinueFrom >= tickInfo.currentTick) {
|
||||
+ additionals = entityLimit.limit() - (tickInfo.currentTick - tickInfo.continueFrom);
|
||||
+ nextContinueFrom = 0;
|
||||
+ }
|
||||
+ tickInfo.continueFrom = nextContinueFrom;
|
||||
+ tickInfo.toTick = entityLimit.limit() + additionals;
|
||||
+
|
||||
+ if (tickInfo.toRemove == 0 && tickInfo.currentTick > entityLimit.removal()) {
|
||||
+ tickInfo.toRemove = tickInfo.currentTick - entityLimit.removal();
|
||||
+ } else if (tickInfo.toRemove != 0) {
|
||||
+ tickInfo.toRemove = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,155 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/tr7zw/entityculling/CullTask.java
|
||||
@@ -1,0 +_,152 @@
|
||||
+package dev.tr7zw.entityculling;
|
||||
+
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+import java.util.concurrent.Executor;
|
||||
+import java.util.concurrent.Executors;
|
||||
+import java.util.concurrent.TimeUnit;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||
+import com.logisticscraft.occlusionculling.OcclusionCullingInstance;
|
||||
+import com.logisticscraft.occlusionculling.util.Vec3d;
|
||||
+
|
||||
+import dev.tr7zw.entityculling.versionless.access.Cullable;
|
||||
+import me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig;
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.entity.decoration.ArmorStand;
|
||||
+import net.minecraft.world.entity.player.Player;
|
||||
+import net.minecraft.world.phys.AABB;
|
||||
+import net.minecraft.world.phys.Vec3;
|
||||
+
|
||||
+public class CullTask implements Runnable {
|
||||
+
|
||||
+ private volatile boolean requestCull = false;
|
||||
+ private volatile boolean scheduleNext = true;
|
||||
+ private volatile boolean inited = false;
|
||||
+
|
||||
+ private final OcclusionCullingInstance culling;
|
||||
+ private final Player checkTarget;
|
||||
+
|
||||
+ private final int hitboxLimit;
|
||||
+
|
||||
+ public long lastCheckedTime = 0;
|
||||
+
|
||||
+ // reused preallocated vars
|
||||
+ private final Vec3d lastPos = new Vec3d(0, 0, 0);
|
||||
+ private final Vec3d aabbMin = new Vec3d(0, 0, 0);
|
||||
+ private final Vec3d aabbMax = new Vec3d(0, 0, 0);
|
||||
+
|
||||
+ private static final Executor backgroundWorker = Executors.newCachedThreadPool(task -> {
|
||||
+ final TickThread worker = new TickThread("EntityCulling") {
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ task.run();
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ worker.setDaemon(true);
|
||||
+
|
||||
+ return worker;
|
||||
+ });
|
||||
+
|
||||
+ private final Executor worker;
|
||||
+
|
||||
+ public CullTask(
|
||||
+ OcclusionCullingInstance culling,
|
||||
+ Player checkTarget,
|
||||
+ int hitboxLimit,
|
||||
+ long checkIntervalMs
|
||||
+ ) {
|
||||
+ this.culling = culling;
|
||||
+ this.checkTarget = checkTarget;
|
||||
+ this.hitboxLimit = hitboxLimit;
|
||||
+ this.worker = CompletableFuture.delayedExecutor(checkIntervalMs, TimeUnit.MILLISECONDS, backgroundWorker);
|
||||
+ }
|
||||
+
|
||||
+ public void requestCullSignal() {
|
||||
+ this.requestCull = true;
|
||||
+ }
|
||||
+
|
||||
+ public void signalStop() {
|
||||
+ this.scheduleNext = false;
|
||||
+ }
|
||||
+
|
||||
+ public void setup() {
|
||||
+ if (!this.inited)
|
||||
+ this.inited = true;
|
||||
+ else
|
||||
+ return;
|
||||
+ this.worker.execute(this);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ try {
|
||||
+ if (this.checkTarget.tickCount > 10) {
|
||||
+ // getEyePosition can use a fixed delta as its debug only anyway
|
||||
+ Vec3 cameraMC = this.checkTarget.getEyePosition(0);
|
||||
+ if (requestCull || !(cameraMC.x == lastPos.x && cameraMC.y == lastPos.y && cameraMC.z == lastPos.z)) {
|
||||
+ long start = System.currentTimeMillis();
|
||||
+
|
||||
+ requestCull = false;
|
||||
+
|
||||
+ lastPos.set(cameraMC.x, cameraMC.y, cameraMC.z);
|
||||
+ culling.resetCache();
|
||||
+
|
||||
+ cullEntities(cameraMC, lastPos);
|
||||
+
|
||||
+ lastCheckedTime = (System.currentTimeMillis() - start);
|
||||
+ }
|
||||
+ }
|
||||
+ }finally {
|
||||
+ if (this.scheduleNext) {
|
||||
+ this.worker.execute(this);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void cullEntities(Vec3 cameraMC, Vec3d camera) {
|
||||
+ for (Entity entity : this.checkTarget.level().getEntities().getAll()) {
|
||||
+ if (!(entity instanceof Cullable cullable)) {
|
||||
+ continue; // Not sure how this could happen outside from mixin screwing up the inject into
|
||||
+ // Entity
|
||||
+ }
|
||||
+
|
||||
+ if (entity.getType().skipRaytracningCheck) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!cullable.isForcedVisible()) {
|
||||
+ if (entity.isCurrentlyGlowing() || isSkippableArmorstand(entity)) {
|
||||
+ cullable.setCulled(false);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!entity.position().closerThan(cameraMC, me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance)) {
|
||||
+ cullable.setCulled(false); // If your entity view distance is larger than tracingDistance just
|
||||
+ // render it
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ AABB boundingBox = entity.getBoundingBox();
|
||||
+ if (boundingBox.getXsize() > hitboxLimit || boundingBox.getYsize() > hitboxLimit
|
||||
+ || boundingBox.getZsize() > hitboxLimit) {
|
||||
+ cullable.setCulled(false); // To big to bother to cull
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ aabbMin.set(boundingBox.minX, boundingBox.minY, boundingBox.minZ);
|
||||
+ aabbMax.set(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ);
|
||||
+
|
||||
+ boolean visible = culling.isAABBVisible(aabbMin, aabbMax, camera);
|
||||
+
|
||||
+ cullable.setCulled(!visible);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private boolean isSkippableArmorstand(Entity entity) {
|
||||
+ if (!RayTrackingEntityTrackerConfig.skipMarkerArmorStands)
|
||||
+ return false;
|
||||
+ return entity instanceof ArmorStand && entity.isInvisible();
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,46 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/tr7zw/entityculling/DefaultChunkDataProvider.java
|
||||
@@ -1,0 +_,43 @@
|
||||
+package dev.tr7zw.entityculling;
|
||||
+
|
||||
+import com.logisticscraft.occlusionculling.DataProvider;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.Blocks;
|
||||
+import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
+import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
+
|
||||
+public class DefaultChunkDataProvider implements DataProvider {
|
||||
+ private final Level level;
|
||||
+
|
||||
+ public DefaultChunkDataProvider(Level level) {
|
||||
+ this.level = level;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean prepareChunk(int chunkX, int chunkZ) {
|
||||
+ return this.level.getChunkIfLoaded(chunkX, chunkZ) != null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isOpaqueFullCube(int x, int y, int z) {
|
||||
+ BlockPos pos = new BlockPos(x, y, z);
|
||||
+
|
||||
+ final ChunkAccess access = this.level.getChunkIfLoaded(pos);
|
||||
+ if (access == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (this.level.isOutsideBuildHeight(pos)) {
|
||||
+ return Blocks.VOID_AIR.defaultBlockState().isSolidRender();
|
||||
+ } else {
|
||||
+ return access.getBlockState(pos).isSolidRender();// 好孩子不要学坏叔叔这样绕过异步拦截()
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void cleanup() {
|
||||
+ DataProvider.super.cleanup();
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -0,0 +1,20 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/dev/tr7zw/entityculling/versionless/access/Cullable.java
|
||||
@@ -1,0 +_,17 @@
|
||||
+package dev.tr7zw.entityculling.versionless.access;
|
||||
+
|
||||
+public interface Cullable {
|
||||
+
|
||||
+ public void setTimeout();
|
||||
+
|
||||
+ public boolean isForcedVisible();
|
||||
+
|
||||
+ public void setCulled(boolean value);
|
||||
+
|
||||
+ public boolean isCulled();
|
||||
+
|
||||
+ public void setOutOfCamera(boolean value);
|
||||
+
|
||||
+ public boolean isOutOfCamera();
|
||||
+
|
||||
+}
|
||||
@@ -1,15 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MrHua269 <wangxyper@163.com>
|
||||
Date: Sun, 12 Jan 2025 15:26:09 +0800
|
||||
Subject: [PATCH] Pufferfish Sentry
|
||||
|
||||
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2b830cb288ceba390ed39cd33fc1ee855357a97e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java
|
||||
@@ -0,0 +1,133 @@
|
||||
@@ -1,0 +_,133 @@
|
||||
+package gg.pufferfish.pufferfish.sentry;
|
||||
+
|
||||
+import com.google.common.reflect.TypeToken;
|
||||
@@ -143,107 +134,3 @@ index 0000000000000000000000000000000000000000..2b830cb288ceba390ed39cd33fc1ee85
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c01e5b5de685eca7edbe8a87732efd45d4dd2557
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java
|
||||
@@ -0,0 +1,44 @@
|
||||
+package gg.pufferfish.pufferfish.sentry;
|
||||
+
|
||||
+import io.sentry.Sentry;
|
||||
+import org.apache.logging.log4j.Level;
|
||||
+import org.apache.logging.log4j.LogManager;
|
||||
+import org.apache.logging.log4j.Logger;
|
||||
+
|
||||
+public class SentryManager {
|
||||
+
|
||||
+ private static final Logger logger = LogManager.getLogger(SentryManager.class);
|
||||
+
|
||||
+ private SentryManager() {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ private static boolean initialized = false;
|
||||
+
|
||||
+ public static synchronized void init(Level logLevel) {
|
||||
+ if (initialized) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (logLevel == null) {
|
||||
+ logger.error("Invalid log level, defaulting to WARN.");
|
||||
+ logLevel = Level.WARN;
|
||||
+ }
|
||||
+ try {
|
||||
+ initialized = true;
|
||||
+
|
||||
+ Sentry.init(options -> {
|
||||
+ options.setDsn(me.earthme.luminol.config.modules.misc.SentryConfig.sentryDsn);
|
||||
+ options.setMaxBreadcrumbs(100);
|
||||
+ });
|
||||
+
|
||||
+ PufferfishSentryAppender appender = new PufferfishSentryAppender(logLevel);
|
||||
+ appender.start();
|
||||
+ ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender);
|
||||
+ logger.info("Sentry logging started!");
|
||||
+ } catch (Exception e) {
|
||||
+ logger.warn("Failed to initialize sentry!", e);
|
||||
+ initialized = false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/SentryConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/SentryConfig.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..55d6bb635b182d15471bfcd481a2b7c6ce26c00b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/SentryConfig.java
|
||||
@@ -0,0 +1,47 @@
|
||||
+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 org.apache.logging.log4j.Level;
|
||||
+
|
||||
+public class SentryConfig implements IConfigModule {
|
||||
+
|
||||
+ @ConfigInfo(baseName = "dsn", comments =
|
||||
+ " Sentry DSN for improved error logging, leave blank to disable,\n" +
|
||||
+ " Obtain from https://sentry.io/")
|
||||
+ public static String sentryDsn = "";
|
||||
+
|
||||
+ @ConfigInfo(baseName = "log_level", comments = " Logs with a level higher than or equal to this level will be recorded.")
|
||||
+ public static String logLevel = "WARN";
|
||||
+
|
||||
+ @ConfigInfo(baseName = "only_log_thrown", comments = " Only log with a Throwable will be recorded after enabling this.")
|
||||
+ public static boolean onlyLogThrown = true;
|
||||
+
|
||||
+ @Override
|
||||
+ public EnumConfigCategory getCategory() {
|
||||
+ return EnumConfigCategory.MISC;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBaseName() {
|
||||
+ return "sentry";
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onLoaded(CommentedFileConfig configInstance) {
|
||||
+ String sentryEnvironment = System.getenv("SENTRY_DSN");
|
||||
+
|
||||
+ sentryDsn = sentryEnvironment != null && !sentryEnvironment.isBlank()
|
||||
+ ? sentryEnvironment
|
||||
+ : configInstance.getOrElse("sentry.dsn", sentryDsn);
|
||||
+
|
||||
+ logLevel = configInstance.getOrElse("sentry.log-level", logLevel);
|
||||
+ onlyLogThrown = configInstance.getOrElse("sentry.only-log-thrown", onlyLogThrown);
|
||||
+
|
||||
+ if (sentryDsn != null && !sentryDsn.isBlank()) {
|
||||
+ gg.pufferfish.pufferfish.sentry.SentryManager.init(Level.getLevel(logLevel));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
@@ -0,0 +1,47 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java
|
||||
@@ -1,0 +_,44 @@
|
||||
+package gg.pufferfish.pufferfish.sentry;
|
||||
+
|
||||
+import io.sentry.Sentry;
|
||||
+import org.apache.logging.log4j.Level;
|
||||
+import org.apache.logging.log4j.LogManager;
|
||||
+import org.apache.logging.log4j.Logger;
|
||||
+
|
||||
+public class SentryManager {
|
||||
+
|
||||
+ private static final Logger logger = LogManager.getLogger(SentryManager.class);
|
||||
+
|
||||
+ private SentryManager() {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ private static boolean initialized = false;
|
||||
+
|
||||
+ public static synchronized void init(Level logLevel) {
|
||||
+ if (initialized) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (logLevel == null) {
|
||||
+ logger.error("Invalid log level, defaulting to WARN.");
|
||||
+ logLevel = Level.WARN;
|
||||
+ }
|
||||
+ try {
|
||||
+ initialized = true;
|
||||
+
|
||||
+ Sentry.init(options -> {
|
||||
+ options.setDsn(me.earthme.luminol.config.modules.misc.SentryConfig.sentryDsn);
|
||||
+ options.setMaxBreadcrumbs(100);
|
||||
+ });
|
||||
+
|
||||
+ PufferfishSentryAppender appender = new PufferfishSentryAppender(logLevel);
|
||||
+ appender.start();
|
||||
+ ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender);
|
||||
+ logger.info("Sentry logging started!");
|
||||
+ } catch (Exception e) {
|
||||
+ logger.warn("Failed to initialize sentry!", e);
|
||||
+ initialized = false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -0,0 +1,30 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/impl/RegionStatsImpl.java
|
||||
@@ -1,0 +_,27 @@
|
||||
+package me.earthme.luminol.api.impl;
|
||||
+
|
||||
+import io.papermc.paper.threadedregions.TickRegions;
|
||||
+import me.earthme.luminol.api.RegionStats;
|
||||
+
|
||||
+public class RegionStatsImpl implements RegionStats {
|
||||
+ private final TickRegions.RegionStats internal;
|
||||
+
|
||||
+ public RegionStatsImpl(TickRegions.RegionStats internal) {
|
||||
+ this.internal = internal;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getEntityCount() {
|
||||
+ return this.internal.getEntityCount();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getPlayerCount() {
|
||||
+ return this.internal.getPlayerCount();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getChunkCount() {
|
||||
+ return this.internal.getChunkCount();
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,50 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionImpl.java
|
||||
@@ -1,0 +_,47 @@
|
||||
+package me.earthme.luminol.api.impl;
|
||||
+
|
||||
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
|
||||
+import io.papermc.paper.threadedregions.TickRegions;
|
||||
+import me.earthme.luminol.api.ThreadedRegion;
|
||||
+import me.earthme.luminol.api.TickRegionData;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.World;
|
||||
+
|
||||
+import javax.annotation.Nullable;
|
||||
+
|
||||
+public class ThreadedRegionImpl implements ThreadedRegion {
|
||||
+ private final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> internal;
|
||||
+
|
||||
+ public ThreadedRegionImpl(ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> internal) {
|
||||
+ this.internal = internal;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public Location getCenterChunkPos() {
|
||||
+ final ChunkPos centerChunkPos = this.internal.getCenterChunk();
|
||||
+
|
||||
+ if (centerChunkPos == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return new Location(this.internal.regioniser.world.getWorld(), centerChunkPos.getMiddleBlockX(), 0, centerChunkPos.getMiddleBlockZ());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double getDeadSectionPercent() {
|
||||
+ return this.internal.getDeadSectionPercent();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public TickRegionData getTickRegionData() {
|
||||
+ return new TickRegionDataImpl(this.internal.getData());
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public World getWorld() {
|
||||
+ return this.internal.regioniser.world.getWorld();
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,56 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/impl/ThreadedRegionizerImpl.java
|
||||
@@ -1,0 +_,53 @@
|
||||
+package me.earthme.luminol.api.impl;
|
||||
+
|
||||
+import io.papermc.paper.threadedregions.TickRegions;
|
||||
+import me.earthme.luminol.api.ThreadedRegion;
|
||||
+import me.earthme.luminol.api.ThreadedRegionizer;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Collection;
|
||||
+import java.util.List;
|
||||
+
|
||||
+public class ThreadedRegionizerImpl implements ThreadedRegionizer {
|
||||
+ private final ServerLevel internal;
|
||||
+
|
||||
+ public ThreadedRegionizerImpl(ServerLevel internal) {
|
||||
+ this.internal = internal;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Collection<ThreadedRegion> getAllRegions() {
|
||||
+ final List<ThreadedRegion> ret = new ArrayList<>();
|
||||
+
|
||||
+ this.internal.regioniser.computeForAllRegions(region -> {
|
||||
+ final ThreadedRegion wrapped = new ThreadedRegionImpl(region);
|
||||
+
|
||||
+ ret.add(wrapped);
|
||||
+ });
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ThreadedRegion getAtSynchronized(int chunkX, int chunkZ) {
|
||||
+ final io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> got = this.internal.regioniser.getRegionAtSynchronised(chunkX, chunkZ);
|
||||
+
|
||||
+ if (got == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return new ThreadedRegionImpl(got);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ThreadedRegion getAtUnSynchronized(int chunkX, int chunkZ) {
|
||||
+ final io.papermc.paper.threadedregions.ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> got = this.internal.regioniser.getRegionAtUnsynchronised(chunkX, chunkZ);
|
||||
+
|
||||
+ if (got == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return new ThreadedRegionImpl(got);
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,33 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/api/impl/TickRegionDataImpl.java
|
||||
@@ -1,0 +_,30 @@
|
||||
+package me.earthme.luminol.api.impl;
|
||||
+
|
||||
+import io.papermc.paper.threadedregions.TickRegions;
|
||||
+import me.earthme.luminol.api.RegionStats;
|
||||
+import me.earthme.luminol.api.TickRegionData;
|
||||
+import org.bukkit.World;
|
||||
+
|
||||
+public class TickRegionDataImpl implements TickRegionData {
|
||||
+ private final TickRegions.TickRegionData internal;
|
||||
+
|
||||
+ public TickRegionDataImpl(TickRegions.TickRegionData internal) {
|
||||
+ this.internal = internal;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public World getWorld() {
|
||||
+ return this.internal.world.getWorld();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getCurrentTickCount() {
|
||||
+ return this.internal.getCurrentTick();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RegionStats getRegionStats() {
|
||||
+ return new RegionStatsImpl(this.internal.getRegionStats());
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -0,0 +1,73 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/commands/LuminolConfigCommand.java
|
||||
@@ -1,0 +_,70 @@
|
||||
+package me.earthme.luminol.commands;
|
||||
+
|
||||
+import me.earthme.luminol.config.LuminolConfig;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.format.TextColor;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+
|
||||
+public class LuminolConfigCommand extends Command {
|
||||
+ public LuminolConfigCommand(){
|
||||
+ super("luminolconfig");
|
||||
+ this.setPermission("luminol.commands.luminolconfig");
|
||||
+ this.setDescription("Manage config file");
|
||||
+ this.setUsage("/luminolconfig");
|
||||
+ }
|
||||
+
|
||||
+ @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){
|
||||
+ result.add("reload");
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
||||
+ if (!this.testPermission(sender)){
|
||||
+ sender.sendMessage(Component
|
||||
+ .text("No permission to execute this command!")
|
||||
+ .color(TextColor.color(255,0,0))
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ if (args.length < 1){
|
||||
+ sender.sendMessage(
|
||||
+ Component
|
||||
+ .text("Wrong use!\n")
|
||||
+ .color(TextColor.color(255,0,0))
|
||||
+ );
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ switch (args[0]){
|
||||
+ case "reload" -> {
|
||||
+ LuminolConfig.reloadAsync().thenAccept(nullValue -> sender.sendMessage(
|
||||
+ Component
|
||||
+ .text("Reloaded config file!")
|
||||
+ .color(TextColor.color(0,255,0))
|
||||
+ ));
|
||||
+ }
|
||||
+
|
||||
+ default -> sender.sendMessage(
|
||||
+ Component
|
||||
+ .text("Unknown action!\n")
|
||||
+ .color(TextColor.color(255,0,0))
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,50 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/commands/MembarCommand.java
|
||||
@@ -1,0 +_,47 @@
|
||||
+package me.earthme.luminol.commands;
|
||||
+
|
||||
+import me.earthme.luminol.config.modules.misc.MembarConfig;
|
||||
+import me.earthme.luminol.functions.GlobalServerMemoryBar;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.format.TextColor;
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class MembarCommand extends Command {
|
||||
+ public MembarCommand(@NotNull String name) {
|
||||
+ super(name);
|
||||
+ this.setPermission("luminol.commands.membar");
|
||||
+ this.setDescription("Show the memory usage through a bossbar");
|
||||
+ this.setUsage("/membar");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
||||
+ if (!testPermission(sender)){
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ 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)));
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (GlobalServerMemoryBar.isPlayerVisible(player)) {
|
||||
+ 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);
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,50 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/commands/RegionBarCommand.java
|
||||
@@ -1,0 +_,47 @@
|
||||
+package me.earthme.luminol.commands;
|
||||
+
|
||||
+import me.earthme.luminol.config.modules.misc.RegionBarConfig;
|
||||
+import me.earthme.luminol.functions.GlobalServerRegionBar;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.format.TextColor;
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class RegionBarCommand extends Command {
|
||||
+ public RegionBarCommand(@NotNull String name) {
|
||||
+ super(name);
|
||||
+ this.setPermission("luminol.commands.regionbar");
|
||||
+ this.setDescription("Show info about your current region through a bossbar");
|
||||
+ this.setUsage("/regionbar");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
||||
+ if (!testPermission(sender)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (!RegionBarConfig.regionbarEnabled) {
|
||||
+ sender.sendMessage(Component.text("Regionbar 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)));
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (GlobalServerRegionBar.isPlayerVisible(player)) {
|
||||
+ player.sendMessage(Component.text("Disabled region bar").color(TextColor.color(0, 255, 0)));
|
||||
+ GlobalServerRegionBar.setVisibilityForPlayer(player, false);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ player.sendMessage(Component.text("Enabled region bar").color(TextColor.color(0, 255, 0)));
|
||||
+ GlobalServerRegionBar.setVisibilityForPlayer(player, true);
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,53 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/commands/TpsBarCommand.java
|
||||
@@ -1,0 +_,50 @@
|
||||
+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;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class TpsBarCommand extends Command {
|
||||
+ public TpsBarCommand(@NotNull String name) {
|
||||
+ super(name);
|
||||
+ this.setPermission("luminol.commands.tpsbar");
|
||||
+ this.setDescription("Show the tps and mspt through a bossbar");
|
||||
+ this.setUsage("/tpsbar");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
||||
+ if (!testPermission(sender)){
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ 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)));
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (GlobalServerTpsBar.isPlayerVisible(player)) {
|
||||
+ 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);
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
@@ -0,0 +1,14 @@
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/me/earthme/luminol/config/ConfigInfo.java
|
||||
@@ -1,0 +_,11 @@
|
||||
+package me.earthme.luminol.config;
|
||||
+
|
||||
+import java.lang.annotation.Retention;
|
||||
+import java.lang.annotation.RetentionPolicy;
|
||||
+
|
||||
+@Retention(RetentionPolicy.RUNTIME)
|
||||
+public @interface ConfigInfo {
|
||||
+ String baseName();
|
||||
+
|
||||
+ String comments() default "";
|
||||
+}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user