9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-29 11:59:24 +00:00

Merge remote-tracking branch 'origin/ver/1.21.1' into ver/1.21.1

This commit is contained in:
HaHaWTH
2024-11-08 01:50:43 +08:00
80 changed files with 1980 additions and 315 deletions

View File

@@ -5,18 +5,22 @@ Subject: [PATCH] Bump Dependencies
diff --git a/build.gradle.kts b/build.gradle.kts
index 1cc87374beed7b4a2cfdd278b076e20b1e9febc8..936f9ac01b576c56ccd9f39c6c0e32d335ee3952 100644
index 1cc87374beed7b4a2cfdd278b076e20b1e9febc8..336b6891d246a43f8fb66bdcda04c565cc925c7e 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -12,8 +12,10 @@ java {
val annotationsVersion = "24.1.0"
@@ -9,11 +9,13 @@ java {
withJavadocJar()
}
-val annotationsVersion = "24.1.0"
+val annotationsVersion = "26.0.1" // Leaf - Bump Dependencies
val bungeeCordChatVersion = "1.20-R0.2"
val adventureVersion = "4.17.0"
-val slf4jVersion = "2.0.9"
-val log4jVersion = "2.17.1"
+// Leaf start - Bump Dependencies
+val slf4jVersion = "2.0.16"
+val log4jVersion = "2.23.1"
+val log4jVersion = "2.24.1"
+// Leaf end - Bump Dependencies
val apiAndDocs: Configuration by configurations.creating {
attributes {
@@ -27,22 +31,23 @@ index 1cc87374beed7b4a2cfdd278b076e20b1e9febc8..936f9ac01b576c56ccd9f39c6c0e32d3
// api dependencies are listed transitively to API consumers
- api("com.google.guava:guava:32.1.2-jre")
- api("com.google.code.gson:gson:2.10.1")
+ api("com.google.guava:guava:33.3.0-jre") // Leaf - Bump Dependencies
+ api("com.google.guava:guava:33.3.1-jre") // Leaf - Bump Dependencies
+ api("com.google.code.gson:gson:2.11.0") // Leaf - Bump Dependencies
// Paper start - adventure
api("net.md-5:bungeecord-chat:$bungeeCordChatVersion-deprecated+build.18") {
exclude("com.google.guava", "guava")
}
// Paper - adventure
api("org.yaml:snakeyaml:2.2")
- api("org.yaml:snakeyaml:2.2")
- api("org.joml:joml:1.10.5")
+ api("org.yaml:snakeyaml:2.3")
+ api("org.joml:joml:1.10.5") // Leaf - Bump Dependencies // Dreeam TODO - Waiting update to 1.10.8, Dont bump
// Paper start
api("com.googlecode.json-simple:json-simple:1.1.1") {
isTransitive = false // includes junit
}
- api("it.unimi.dsi:fastutil:8.5.6")
+ api("it.unimi.dsi:fastutil:8.5.14") // Leaf - Bump Dependencies
+ api("it.unimi.dsi:fastutil:8.5.15") // Leaf - Bump Dependencies
apiAndDocs(platform("net.kyori:adventure-bom:$adventureVersion"))
apiAndDocs("net.kyori:adventure-api")
apiAndDocs("net.kyori:adventure-text-minimessage")
@@ -51,7 +56,7 @@ index 1cc87374beed7b4a2cfdd278b076e20b1e9febc8..936f9ac01b576c56ccd9f39c6c0e32d3
api("org.apache.logging.log4j:log4j-api:$log4jVersion")
api("org.slf4j:slf4j-api:$slf4jVersion")
- api("io.sentry:sentry:5.4.0") // Pufferfish
+ api("io.sentry:sentry:8.0.0-alpha.4") // Pufferfish // Leaf - Bump Dependencies
+ api("io.sentry:sentry:8.0.0-beta.1") // Pufferfish // Leaf - Bump Dependencies
implementation("org.ow2.asm:asm:9.7.1")
implementation("org.ow2.asm:asm-commons:9.7.1")
@@ -72,7 +77,7 @@ index 1cc87374beed7b4a2cfdd278b076e20b1e9febc8..936f9ac01b576c56ccd9f39c6c0e32d3
// Paper start - add checker
- val checkerQual = "org.checkerframework:checker-qual:3.33.0"
+ val checkerQual = "org.checkerframework:checker-qual:3.46.0" // Leaf - Bump Dependencies
+ val checkerQual = "org.checkerframework:checker-qual:3.48.1" // Leaf - Bump Dependencies
compileOnlyApi(checkerQual)
testCompileOnly(checkerQual)
// Paper end
@@ -81,36 +86,40 @@ index 1cc87374beed7b4a2cfdd278b076e20b1e9febc8..936f9ac01b576c56ccd9f39c6c0e32d3
- testImplementation("org.apache.commons:commons-lang3:3.12.0")
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
- testImplementation("org.hamcrest:hamcrest:2.2")
- testImplementation("org.mockito:mockito-core:5.14.1")
+ // Leaf start - Bump Dependencies
+ testImplementation("org.apache.commons:commons-lang3:3.16.0")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.11.0")
+ testImplementation("org.apache.commons:commons-lang3:3.17.0")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.11.3")
+ testImplementation("org.hamcrest:hamcrest:3.0")
testImplementation("org.mockito:mockito-core:5.14.1")
+ testImplementation("org.mockito:mockito-core:5.14.2")
+ // Leaf end - Bump Dependencies
testImplementation("org.ow2.asm:asm-tree:9.7.1")
+
+ // Leaf - Bump Dependencies
+ // commons-lang3 is removed in maven-resolver-provider since 3.9.8
+ // Add this because bukkit api still need it.
+ compileOnly("org.apache.commons:commons-lang3:3.16.0")
+ compileOnly("org.apache.commons:commons-lang3:3.17.0")
}
// Paper start
@@ -165,12 +176,12 @@ tasks.withType<Javadoc> {
@@ -165,13 +176,13 @@ tasks.withType<Javadoc> {
options.use()
options.isDocFilesSubDirs = true
options.links(
- "https://guava.dev/releases/32.1.2-jre/api/docs/",
+ "https://guava.dev/releases/33.1.0-jre/api/docs/", // Leaf - Bump Dependencies
"https://javadoc.io/doc/org.yaml/snakeyaml/2.2/",
- "https://javadoc.io/doc/org.yaml/snakeyaml/2.2/",
+ "https://guava.dev/releases/33.3.1-jre/api/docs/", // Leaf - Bump Dependencies
+ "https://javadoc.io/doc/org.yaml/snakeyaml/2.3/", // Leaf - Bump Dependencies
"https://javadoc.io/doc/org.jetbrains/annotations/$annotationsVersion/", // Paper - we don't want Java 5 annotations
// "https://javadoc.io/doc/net.md-5/bungeecord-chat/$bungeeCordChatVersion/", // Paper - don't link to bungee chat
// Paper start - add missing javadoc links
- "https://javadoc.io/doc/org.joml/joml/1.10.5/index.html",
- "https://www.javadoc.io/doc/com.google.code.gson/gson/2.10.1",
+ "https://javadoc.io/doc/org.joml/joml/latest/index.html", // Leaf - Bump Dependencies
"https://www.javadoc.io/doc/com.google.code.gson/gson/2.10.1",
+ "https://www.javadoc.io/doc/com.google.code.gson/gson/2.11.0",
"https://jspecify.dev/docs/api/",
// Paper end
// Paper start
@@ -183,9 +194,9 @@ tasks.withType<Javadoc> {
"https://jd.advntr.dev/text-serializer-plain/$adventureVersion/",
"https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/",
@@ -119,7 +128,7 @@ index 1cc87374beed7b4a2cfdd278b076e20b1e9febc8..936f9ac01b576c56ccd9f39c6c0e32d3
+ "https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/2.20.0", // Leaf - Bump Dependencies
// Paper end
- "https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/1.7.3", // Paper
+ "https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/1.9.21", // Paper // Leaf - Bump Dependencies
+ "https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/1.9.22", // Paper // Leaf - Bump Dependencies
)
options.tags("apiNote:a:API Note:")

View File

@@ -6,7 +6,7 @@ Subject: [PATCH] Bump Dependencies
TODO - Dreeam: Bump & test dependencies, impl new features?
diff --git a/build.gradle.kts b/build.gradle.kts
index 0d250a691a0f28770cbd9f847d8cd00af866b583..86c4b60c478817001d622397972ddc1ce3a59a55 100644
index 0d250a691a0f28770cbd9f847d8cd00af866b583..776e4d697d6d9b4b66806f120066dbf35c66c480 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -22,7 +22,7 @@ dependencies {
@@ -14,7 +14,7 @@ index 0d250a691a0f28770cbd9f847d8cd00af866b583..86c4b60c478817001d622397972ddc1c
// Paper start
- implementation("org.jline:jline-terminal-jansi:3.21.0")
+ implementation("org.jline:jline-terminal-jansi:3.26.3") // Leaf - Bump Dependencies
+ implementation("org.jline:jline-terminal-jansi:3.27.1") // Leaf - Bump Dependencies
implementation("net.minecrell:terminalconsoleappender:1.3.0")
implementation("net.kyori:adventure-text-serializer-ansi:4.17.0") // Keep in sync with adventureVersion from Paper-API build file
/*
@@ -25,15 +25,15 @@ index 0d250a691a0f28770cbd9f847d8cd00af866b583..86c4b60c478817001d622397972ddc1c
- implementation("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - implementation
- log4jPlugins.annotationProcessorConfigurationName("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - Needed to generate meta for our Log4j plugins
+ // Leaf start - Bump Dependencies
+ implementation("org.apache.logging.log4j:log4j-core:2.23.1") // Paper - implementation
+ log4jPlugins.annotationProcessorConfigurationName("org.apache.logging.log4j:log4j-core:2.23.1") // Paper - Needed to generate meta for our Log4j plugins
+ implementation("org.apache.logging.log4j:log4j-core:2.24.1") // Paper - implementation
+ log4jPlugins.annotationProcessorConfigurationName("org.apache.logging.log4j:log4j-core:2.24.1") // Paper - Needed to generate meta for our Log4j plugins
runtimeOnly(log4jPlugins.output)
alsoShade(log4jPlugins.output)
- implementation("io.netty:netty-codec-haproxy:4.1.97.Final") // Paper - Add support for proxy protocol
+ implementation("io.netty:netty-codec-haproxy:4.1.112.Final") // Paper - Add support for proxy protocol
+ implementation("io.netty:netty-codec-haproxy:4.1.114.Final") // Paper - Add support for proxy protocol
// Paper end
- implementation("org.apache.logging.log4j:log4j-iostreams:2.22.1") // Paper - remove exclusion
+ implementation("org.apache.logging.log4j:log4j-iostreams:2.23.1") // Paper - remove exclusion
+ implementation("org.apache.logging.log4j:log4j-iostreams:2.24.1") // Paper - remove exclusion
+ // Leaf end - Bump Dependencies
implementation("org.ow2.asm:asm-commons:9.7.1")
implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files
@@ -41,11 +41,12 @@ index 0d250a691a0f28770cbd9f847d8cd00af866b583..86c4b60c478817001d622397972ddc1c
- runtimeOnly("org.xerial:sqlite-jdbc:3.46.0.0")
- runtimeOnly("com.mysql:mysql-connector-j:8.4.0")
- runtimeOnly("com.lmax:disruptor:3.4.4") // Paper
+ runtimeOnly("org.xerial:sqlite-jdbc:3.46.1.0") // Leaf - Bump Dependencies
+ runtimeOnly("com.mysql:mysql-connector-j:8.4.0") // Dreeam TODO - Update to 9.0.0
+ runtimeOnly("org.xerial:sqlite-jdbc:3.47.0.0") // Leaf - Bump Dependencies
+ runtimeOnly("com.mysql:mysql-connector-j:9.1.0") // Leaf - Bump Dependencies
+ runtimeOnly("com.lmax:disruptor:3.4.4") // Paper // Leaf - Bump Dependencies // Dreeam TODO - Waiting Log4j 3.x to support disruptor 4.0.0
// Paper start - Use Velocity cipher
implementation("com.velocitypowered:velocity-native:3.3.0-SNAPSHOT") {
- implementation("com.velocitypowered:velocity-native:3.3.0-SNAPSHOT") {
+ implementation("com.velocitypowered:velocity-native:3.4.0-SNAPSHOT") { // Leaf - Bump Dependencies
isTransitive = false
}
// Paper end - Use Velocity cipher
@@ -61,28 +62,32 @@ index 0d250a691a0f28770cbd9f847d8cd00af866b583..86c4b60c478817001d622397972ddc1c
// Purpur start
implementation("org.mozilla:rhino-runtime:1.7.15")
@@ -60,11 +64,11 @@ dependencies {
@@ -60,13 +64,13 @@ dependencies {
implementation("dev.omega24:upnp4j:1.0")
// Purpur end
- testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test
- testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
+ testImplementation("io.github.classgraph:classgraph:4.8.175") // Paper - mob goal test // Leaf - Bump Dependencies
+ testImplementation("org.junit.jupiter:junit-jupiter:5.11.0") // Leaf - Bump Dependencies
testImplementation("org.junit.platform:junit-platform-suite-engine:1.10.0")
- testImplementation("org.junit.platform:junit-platform-suite-engine:1.10.0")
- testImplementation("org.hamcrest:hamcrest:2.2")
- testImplementation("org.mockito:mockito-core:5.14.1")
+ testImplementation("io.github.classgraph:classgraph:4.8.177") // Paper - mob goal test // Leaf - Bump Dependencies
+ testImplementation("org.junit.jupiter:junit-jupiter:5.11.3") // Leaf - Bump Dependencies
+ testImplementation("org.junit.platform:junit-platform-suite-engine:1.10.3")
+ testImplementation("org.hamcrest:hamcrest:3.0")
+ testImplementation("org.mockito:mockito-core:5.14.") // Leaf - Bump Dependencies
+ testImplementation("org.mockito:mockito-core:5.14.2") // Leaf - Bump Dependencies
testImplementation("org.ow2.asm:asm-tree:9.7.1")
testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // Paper - CartesianTest
- testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // Paper - CartesianTest
+ testImplementation("org.junit-pioneer:junit-pioneer:2.3.0") // Paper - CartesianTest // Leaf - Bump Dependencies
implementation("net.neoforged:srgutils:1.0.9") // Paper - mappings handling
implementation("net.neoforged:AutoRenamingTool:2.0.3") // Paper - remap plugins
// Paper start - Remap reflection
@@ -79,6 +83,8 @@ dependencies {
implementation("me.lucko:spark-api:0.1-20240720.200737-2")
implementation("me.lucko:spark-paper:1.10.105-SNAPSHOT")
// Paper end - spark
+
+ implementation("io.netty:netty-all:4.1.112.Final") // Leaf - Bump Dependencies // Dreeam TODO - Update to 4.2.0
+ implementation("io.netty:netty-all:4.1.114.Final") // Leaf - Bump Dependencies // Dreeam TODO - Update to 4.2.0
}
paperweight {

View File

@@ -12,7 +12,7 @@ This format saves about 50% of disk space.
Documentation: https://github.com/xymb-endcrystalme/LinearRegionFileFormatTools
diff --git a/build.gradle.kts b/build.gradle.kts
index 32cebbf591b2f822ec32080aa8451f85c64b6787..e16e9b3b815065ed4aae1965edc3a68471470ec5 100644
index 776e4d697d6d9b4b66806f120066dbf35c66c480..c2f2783fc4cdf5f222498d9bd08db152677bbfdb 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -21,6 +21,11 @@ dependencies {
@@ -20,12 +20,12 @@ index 32cebbf591b2f822ec32080aa8451f85c64b6787..e16e9b3b815065ed4aae1965edc3a684
// Leaf end - Leaf Config
+ // LinearPaper start
+ implementation("com.github.luben:zstd-jni:1.5.6-4")
+ implementation("com.github.luben:zstd-jni:1.5.6-7")
+ implementation("org.lz4:lz4-java:1.8.0")
+ // LinearPaper end
+
// Paper start
implementation("org.jline:jline-terminal-jansi:3.26.3") // Leaf - Bump Dependencies
implementation("org.jline:jline-terminal-jansi:3.27.1") // Leaf - Bump Dependencies
implementation("net.minecrell:terminalconsoleappender:1.3.0")
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/ChunkSystemRegionFileStorage.java
index 73df26b27146bbad2106d57b22dd3c792ed3dd1d..d2f209dd61f4412478a4b8fbe3489787d30bf74b 100644
@@ -71,7 +71,7 @@ index 3218cbf84f54daf06e84442d5eb1a36d8da6b215..ec9b27177dc526510e86d85f48f167b4
synchronized (cache) {
regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfLoaded(chunkX, chunkZ);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c2049ace0261c0a76b06d7f3da3514e1c12194aa..b46c81a22fa6f278646ef9d2066ba57d58436aad 100644
index 645c97aef6abf63f0c631a506ccff0e3b9a49dec..ffdecadd2194dd5ab9bd0a814616acb68cf4c3f1 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -968,10 +968,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View File

@@ -0,0 +1,163 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Wed, 22 May 2024 14:14:30 -0700
Subject: [PATCH] Moonrise: Bitstorage optimisations
Original license: GPLv3
Original project: https://github.com/Tuinity/Moonrise
This patch is based on the following mixin:
"ca/spottedleaf/moonrise/mixin/bitstorage/SimpleBitStorageMixin.java"
Credit to https://lemire.me/blog/2019/02/08/faster-remainders-when-the-divisor-is-a-constant-beating-compilers-and-libdivide
and https://github.com/Vrganj for the algorithm to determine a magic value to use for both division and mod operations
Do not validate input, and optimise method to use our magic value, which does not perform an add
diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java
index 77699c5fa9681f9ec7aa05cbb50eb60828e193ab..1ba0bd5f0f90c691394307833612ef75ed4ab759 100644
--- a/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java
+++ b/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java
@@ -170,6 +170,28 @@ public final class IntegerUtil {
return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1
}
+ // Moonrise start - Bitstorage optimisations
+ // https://lemire.me/blog/2019/02/08/faster-remainders-when-the-divisor-is-a-constant-beating-compilers-and-libdivide
+
+ /**
+ * Usage:
+ * <pre>
+ * {@code
+ * static final long mult = getSimpleMultiplier(divisor, bits);
+ * long x = ...;
+ * long magic = x * mult;
+ * long divQ = magic >>> bits;
+ * long divR = ((magic & ((1 << bits) - 1)) * divisor) >>> bits;
+ * }
+ * </pre>
+ *
+ * @param bits The number of bits of precision for the returned result
+ */
+ public static long getUnsignedDivisorMagic(final long divisor, final int bits) {
+ return (((1L << bits) - 1L) / divisor) + 1;
+ }
+ // Moonrise end - Bitstorage optimisations
+
private IntegerUtil() {
throw new RuntimeException();
}
diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java
index 0b8b0cf58f637d72eae28e21266df14183f11fb1..397aaa8beb4256404921df8799eb66f12aecf602 100644
--- a/src/main/java/net/minecraft/util/SimpleBitStorage.java
+++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java
@@ -209,6 +209,20 @@ public class SimpleBitStorage implements BitStorage {
private final int divideAdd; private final long divideAddUnsigned; // Paper - Perf: Optimize SimpleBitStorage
private final int divideShift;
+ // Moonrise start - Bitstorage optimisations
+ private static final int[] BETTER_MAGIC = new int[33];
+ static {
+ // 20 bits of precision
+ // since index is always [0, 4095] (i.e 12 bits), multiplication by a magic value here (20 bits)
+ // fits exactly in an int and allows us to use integer arithmetic
+ for (int bits = 1; bits < BETTER_MAGIC.length; ++bits) {
+ BETTER_MAGIC[bits] = (int) ca.spottedleaf.concurrentutil.util.IntegerUtil.getUnsignedDivisorMagic(64L / bits, 20);
+ }
+ }
+ private final int magic;
+ private final int mulBits;
+ // Moonrise end - Bitstorage optimisations
+
public SimpleBitStorage(int elementBits, int size, int[] data) {
this(elementBits, size);
int i = 0;
@@ -262,6 +276,14 @@ public class SimpleBitStorage implements BitStorage {
} else {
this.data = new long[j];
}
+
+ // Moonrise start - Bitstorage optimisations
+ this.magic = BETTER_MAGIC[this.bits];
+ this.mulBits = (64 / this.bits) * this.bits;
+ if (this.size > 4096) {
+ throw new IllegalStateException("Size > 4096 not supported");
+ }
+ // Moonrise end - Bitstorage optimisations
}
private int cellIndex(int index) {
@@ -272,33 +294,54 @@ public class SimpleBitStorage implements BitStorage {
@Override
public final int getAndSet(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage
- int i = this.cellIndex(index);
- long l = this.data[i];
- int j = (index - i * this.valuesPerLong) * this.bits;
- int k = (int)(l >> j & this.mask);
- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j;
- return k;
+ // Moonrise start - Bitstorage optimisations
+ // assume index/value in range
+ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int
+ final int divQ = full >>> 20;
+ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20;
+
+ final long[] dataArray = this.data;
+
+ final long data = dataArray[divQ];
+ final long mask = this.mask;
+
+ final long write = data & ~(mask << divR) | ((long) value & mask) << divR;
+
+ dataArray[divQ] = write;
+
+ return (int) (data >>> divR & mask);
+ // Moonrise end - Bitstorage optimisations
}
@Override
public final void set(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage
- int i = this.cellIndex(index);
- long l = this.data[i];
- int j = (index - i * this.valuesPerLong) * this.bits;
- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j;
+ // Moonrise start - Bitstorage optimisations
+ // assume index/value in range
+ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int
+ final int divQ = full >>> 20;
+ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20;
+
+ final long[] dataArray = this.data;
+
+ final long data = dataArray[divQ];
+ final long mask = this.mask;
+
+ final long write = data & ~(mask << divR) | ((long) value & mask) << divR;
+
+ dataArray[divQ] = write;
+ // Moonrise end - Bitstorage optimisations
}
@Override
public final int get(int index) { // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage
- int i = this.cellIndex(index);
- long l = this.data[i];
- int j = (index - i * this.valuesPerLong) * this.bits;
- return (int)(l >> j & this.mask);
+ // Moonrise start - Bitstorage optimisations
+ // assume index in range
+ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int
+ final int divQ = full >>> 20;
+ final int divR = (full & 0xFFFFF) * this.mulBits >>> 20;
+
+ return (int) (this.data[divQ] >>> divR & this.mask);
+ // Moonrise end - Bitstorage optimisations
}
@Override

View File

@@ -1,205 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 13 Aug 2024 23:53:27 -0700
Subject: [PATCH] Moonrise: Store ticking blocks in chunk sections as positions
only
Original license: GPLv3
Original project: https://github.com/Tuinity/Moonrise
https://github.com/Tuinity/Moonrise/commit/fc9d35c4b0869a82d1939cf306f75b048a5524b2
Since we no longer use the state stored directly in the
IBlockDataList, it makes no sense to use IBlockDataList
at all.
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java
new file mode 100644
index 0000000000000000000000000000000000000000..a26c809aea87c56adfffc696caafc691992cae2e
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java
@@ -0,0 +1,79 @@
+package ca.spottedleaf.moonrise.common.list;
+
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+
+import java.util.Arrays;
+
+public final class IntList {
+
+ private final Int2IntOpenHashMap map = new Int2IntOpenHashMap();
+
+ {
+ this.map.defaultReturnValue(Integer.MIN_VALUE);
+ }
+
+ private static final int[] EMPTY_LIST = new int[0];
+
+ private int[] byIndex = EMPTY_LIST;
+ private int count;
+
+ public int size() {
+ return this.count;
+ }
+
+ public void setMinCapacity(final int len) {
+ final int[] byIndex = this.byIndex;
+ if (byIndex.length < len) {
+ this.byIndex = Arrays.copyOf(byIndex, len);
+ }
+ }
+
+ public int getRaw(final int index) {
+ return this.byIndex[index];
+ }
+
+ public boolean add(final int value) {
+ final int count = this.count;
+ final int currIndex = this.map.putIfAbsent(value, count);
+
+ if (currIndex != Integer.MIN_VALUE) {
+ return false; // already in this list
+ }
+
+ int[] list = this.byIndex;
+
+ if (list.length == count) {
+ // resize required
+ list = this.byIndex = Arrays.copyOf(list, (int) Math.max(4L, count * 2L)); // overflow results in negative
+ }
+
+ list[count] = value;
+ this.count = count + 1;
+
+ return true;
+ }
+
+ public boolean remove(final int value) {
+ final int index = this.map.remove(value);
+ if (index == Integer.MIN_VALUE) {
+ return false;
+ }
+
+ // move the entry at the end to this index
+ final int endIndex = --this.count;
+ final int end = this.byIndex[endIndex];
+ if (index != endIndex) {
+ // not empty after this call
+ this.map.put(end, index);
+ }
+ this.byIndex[index] = end;
+ this.byIndex[endIndex] = 0;
+
+ return true;
+ }
+
+ public void clear() {
+ this.count = 0;
+ this.map.clear();
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java
index a08ddb0598d44368af5b6bace971ee31edf9919e..0a67166b301274ef21ea4b9338b79db49a8892d4 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java
@@ -1,11 +1,11 @@
package ca.spottedleaf.moonrise.patches.block_counting;
-import ca.spottedleaf.moonrise.common.list.IBlockDataList;
+import ca.spottedleaf.moonrise.common.list.IntList;
public interface BlockCountingChunkSection {
public int moonrise$getSpecialCollidingBlocks();
- public IBlockDataList moonrise$getTickingBlockList();
+ public IntList moonrise$getTickingBlockList(); // Moonrise - Store ticking blocks in chunk sections as positions only
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 991859906cf1278663ba75bf0992f002e056b244..9ef8919e4cdac61e2e4dd2fe96aed96cb1d5959e 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -841,10 +841,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
continue;
}
- final ca.spottedleaf.moonrise.common.list.IBlockDataList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getTickingBlockList();
- if (tickList.size() == 0) {
- continue;
- }
+ final ca.spottedleaf.moonrise.common.list.IntList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection) section).moonrise$getTickingBlockList(); // Moonrise - Store ticking blocks in chunk sections as positions only
for (int i = 0; i < tickSpeed; ++i) {
final int tickingBlocks = tickList.size();
@@ -855,15 +852,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
continue;
}
- final long raw = tickList.getRaw(index);
- final int location = ca.spottedleaf.moonrise.common.list.IBlockDataList.getLocationFromRaw(raw);
- final int randomX = (location & 15);
- final int randomY = ((location >>> (4 + 4)) & 255);
- final int randomZ = ((location >>> 4) & 15);
- final BlockState state = states.get(randomX | (randomZ << 4) | (randomY << 8));
+ // Moonrise start - Store ticking blocks in chunk sections as positions only
+ final int location = tickList.getRaw(index);
+ final BlockState state = states.get(location);
+ // Moonrise end - Store ticking blocks in chunk sections as positions only
// do not use a mutable pos, as some random tick implementations store the input without calling immutable()!
- final BlockPos pos = new BlockPos(randomX | offsetX, randomY | offsetY, randomZ | offsetZ);
+ final BlockPos pos = new BlockPos((location & 15) | offsetX, ((location >>> (4 + 4)) & 15) | offsetY, ((location >>> 4) & 15) | offsetZ); // Moonrise - Store ticking blocks in chunk sections as positions only
state.randomTick((ServerLevel)(Object)this, pos, random);
if (tickFluids) {
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
index 33747ef8211066155cd70ce2818862cf3e79db53..249fab7ae35b60a64b359d6dc1a28d0ce8a69664 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -36,7 +36,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
}
private int specialCollidingBlocks;
- private final ca.spottedleaf.moonrise.common.list.IBlockDataList tickingBlocks = new ca.spottedleaf.moonrise.common.list.IBlockDataList();
+ private final ca.spottedleaf.moonrise.common.list.IntList tickingBlocks = new ca.spottedleaf.moonrise.common.list.IntList(); // Moonrise - Store ticking blocks in chunk sections as positions only
@Override
public final int moonrise$getSpecialCollidingBlocks() {
@@ -44,7 +44,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
}
@Override
- public final ca.spottedleaf.moonrise.common.list.IBlockDataList moonrise$getTickingBlockList() {
+ public final ca.spottedleaf.moonrise.common.list.IntList moonrise$getTickingBlockList() { // Moonrise - Store ticking blocks in chunk sections as positions only
return this.tickingBlocks;
}
// Paper end - block counting
@@ -128,12 +128,16 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
++this.specialCollidingBlocks;
}
+ // Moonrise start - Store ticking blocks in chunk sections as positions only
+ final int position = x | (z << 4) | (y << (4 + 4));
+
if (iblockdata1.isRandomlyTicking()) {
- this.tickingBlocks.remove(x, y, z);
+ this.tickingBlocks.remove(position);
}
if (state.isRandomlyTicking()) {
- this.tickingBlocks.add(x, y, z, state);
+ this.tickingBlocks.add(position);
}
+ // Moonrise end - Store ticking blocks in chunk sections as positions only
// Paper end - block counting
return iblockdata1;
@@ -200,7 +204,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
java.util.Objects.checkFromToIndex(0, paletteCount, raw.length);
for (int i = 0; i < paletteCount; ++i) {
- this.tickingBlocks.add(raw[i], state);
+ this.tickingBlocks.add(raw[i]); // Moonrise - Store ticking blocks in chunk sections as positions only
}
}

View File

@@ -0,0 +1,504 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 13 Aug 2024 23:53:27 -0700
Subject: [PATCH] Moonrise: block counting optimisations
Original license: GPLv3
Original project:
- https://github.com/Tuinity/Moonrise
- https://github.com/PaperMC/Paper
https://github.com/Tuinity/Moonrise/commit/fc9d35c4b0869a82d1939cf306f75b048a5524b2
https://github.com/Tuinity/Moonrise/commit/1374ea34eeb539bbefd35ffff8c0324bfbf065a2
Since we no longer use the state stored directly in the
IBlockDataList, it makes no sense to use IBlockDataList
at all.
And further more, we can store a position (ranging from 0-4095) into a short,
so we can use ShortList to cut the memory usage in half.
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca5928b132aadb11772af48680362c8fa770f115
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java
@@ -0,0 +1,79 @@
+package ca.spottedleaf.moonrise.common.list;
+
+import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap;
+
+import java.util.Arrays;
+
+public final class ShortList {
+
+ private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap();
+
+ {
+ this.map.defaultReturnValue(Short.MIN_VALUE);
+ }
+
+ private static final short[] EMPTY_LIST = new short[0];
+
+ private short[] byIndex = EMPTY_LIST;
+ private short count;
+
+ public int size() {
+ return (int) this.count;
+ }
+
+ public short getRaw(final int index) {
+ return this.byIndex[index];
+ }
+
+ public void setMinCapacity(final int len) {
+ final short[] byIndex = this.byIndex;
+ if (byIndex.length < len) {
+ this.byIndex = Arrays.copyOf(byIndex, len);
+ }
+ }
+
+ public boolean add(final short value) {
+ final int count = (int) this.count;
+ final short currIndex = this.map.putIfAbsent(value, (short) count);
+
+ if (currIndex != Short.MIN_VALUE) {
+ return false; // already in this list
+ }
+
+ short[] list = this.byIndex;
+
+ if (list.length == count) {
+ // resize required
+ list = this.byIndex = Arrays.copyOf(list, (int) Math.max(4L, count * 2L)); // overflow results in negative
+ }
+
+ list[count] = value;
+ this.count = (short) (count + 1);
+
+ return true;
+ }
+
+ public boolean remove(final short value) {
+ final short index = this.map.remove(value);
+ if (index == Short.MIN_VALUE) {
+ return false;
+ }
+
+ // move the entry at the end to this index
+ final short endIndex = --this.count;
+ final short end = this.byIndex[endIndex];
+ if (index != endIndex) {
+ // not empty after this call
+ this.map.put(end, index);
+ }
+ this.byIndex[(int) index] = end;
+ this.byIndex[(int) endIndex] = (short) 0;
+
+ return true;
+ }
+
+ public void clear() {
+ this.count = (short) 0;
+ this.map.clear();
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java
index aef4fc0d3c272febe675d1ac846b88e58b4e7533..7999509d62cbcf0f9e600d1f7c7480c932bd1c47 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java
@@ -2,9 +2,10 @@ package ca.spottedleaf.moonrise.patches.block_counting;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.shorts.ShortArrayList;
public interface BlockCountingBitStorage {
- public Int2ObjectOpenHashMap<IntArrayList> moonrise$countEntries();
+ public Int2ObjectOpenHashMap<ShortArrayList> moonrise$countEntries(); // Moonrise - block counting optimisations
}
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java
index a08ddb0598d44368af5b6bace971ee31edf9919e..326114473df6db690e9ced6f8749cbfd0cc17610 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingChunkSection.java
@@ -1,11 +1,11 @@
package ca.spottedleaf.moonrise.patches.block_counting;
-import ca.spottedleaf.moonrise.common.list.IBlockDataList;
+import ca.spottedleaf.moonrise.common.list.ShortList;
public interface BlockCountingChunkSection {
- public int moonrise$getSpecialCollidingBlocks();
+ public boolean moonrise$hasSpecialCollidingBlocks(); // Moonrise - block counting optimisations
- public IBlockDataList moonrise$getTickingBlockList();
+ public ShortList moonrise$getTickingBlockList(); // Moonrise - block counting optimisations
}
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
index 6a3f1d5362b29db321d6c03d0f5ab5e6c915a02d..fd86a5f34cc280caf62634639b427791ab899d0f 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java
@@ -1656,7 +1656,7 @@ public final class CollisionUtil {
continue;
}
- final boolean hasSpecial = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getSpecialCollidingBlocks() != 0;
+ final boolean hasSpecial = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$hasSpecialCollidingBlocks(); // Moonrise - block counting optimisations
final int sectionAdjust = !hasSpecial ? 1 : 0;
final net.minecraft.world.level.chunk.PalettedContainer<net.minecraft.world.level.block.state.BlockState> blocks = section.states;
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 991859906cf1278663ba75bf0992f002e056b244..ee0403cf2d6c088fa02a68432bb599094bc473f1 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -841,10 +841,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
continue;
}
- final ca.spottedleaf.moonrise.common.list.IBlockDataList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection)section).moonrise$getTickingBlockList();
- if (tickList.size() == 0) {
- continue;
- }
+ final ca.spottedleaf.moonrise.common.list.ShortList tickList = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection) section).moonrise$getTickingBlockList(); // Moonrise - block counting optimisations
for (int i = 0; i < tickSpeed; ++i) {
final int tickingBlocks = tickList.size();
@@ -855,15 +852,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
continue;
}
- final long raw = tickList.getRaw(index);
- final int location = ca.spottedleaf.moonrise.common.list.IBlockDataList.getLocationFromRaw(raw);
- final int randomX = (location & 15);
- final int randomY = ((location >>> (4 + 4)) & 255);
- final int randomZ = ((location >>> 4) & 15);
- final BlockState state = states.get(randomX | (randomZ << 4) | (randomY << 8));
+ // Moonrise start - block counting optimisations
+ final int location = (int) tickList.getRaw(index) & 0xFFFF;
+ final BlockState state = states.get(location);
+ // Moonrise end - block counting optimisations
// do not use a mutable pos, as some random tick implementations store the input without calling immutable()!
- final BlockPos pos = new BlockPos(randomX | offsetX, randomY | offsetY, randomZ | offsetZ);
+ final BlockPos pos = new BlockPos((location & 15) | offsetX, ((location >>> (4 + 4)) & 15) | offsetY, ((location >>> 4) & 15) | offsetZ); // Moonrise - block counting optimisations
state.randomTick((ServerLevel)(Object)this, pos, random);
if (tickFluids) {
diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java
index f852d2c0c0e37df78dbea28e183aee3572978dee..2d5bc7320cd933668a8dde1cb2e7e66b6a0c7ade 100644
--- a/src/main/java/net/minecraft/util/BitStorage.java
+++ b/src/main/java/net/minecraft/util/BitStorage.java
@@ -24,16 +24,18 @@ public interface BitStorage extends ca.spottedleaf.moonrise.patches.block_counti
// Paper start - block counting
// provide default impl in case mods implement this...
+ // Moonrise start - block counting optimisations
@Override
- public default it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.ints.IntArrayList> moonrise$countEntries() {
- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.ints.IntArrayList> ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>();
+ public default it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> moonrise$countEntries() {
+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>();
final int size = this.getSize();
for (int index = 0; index < size; ++index) {
final int paletteIdx = this.get(index);
ret.computeIfAbsent(paletteIdx, (final int key) -> {
- return new it.unimi.dsi.fastutil.ints.IntArrayList();
- }).add(index);
+ return new it.unimi.dsi.fastutil.shorts.ShortArrayList();
+ }).add((short) index);
+ // Moonrise end - block counting optimisations
}
return ret;
diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java
index 397aaa8beb4256404921df8799eb66f12aecf602..d11fad2a92fc39e9918b0000e737fcbfbe56a50c 100644
--- a/src/main/java/net/minecraft/util/SimpleBitStorage.java
+++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java
@@ -408,14 +408,14 @@ public class SimpleBitStorage implements BitStorage {
// Paper start - block counting
@Override
- public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.ints.IntArrayList> moonrise$countEntries() {
+ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> moonrise$countEntries() { // Moonrise - block counting optimisations
final int valuesPerLong = this.valuesPerLong;
final int bits = this.bits;
final long mask = this.mask;
final int size = this.size;
// we may be backed by global palette, so limit bits for init capacity
- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.ints.IntArrayList> ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(
+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>( // Moonrise - block counting optimisations
1 << Math.min(6, bits)
);
@@ -428,8 +428,10 @@ public class SimpleBitStorage implements BitStorage {
value >>= bits;
ret.computeIfAbsent(paletteIdx, (final int key) -> {
- return new it.unimi.dsi.fastutil.ints.IntArrayList();
- }).add(index);
+ // Moonrise start - block counting optimisations
+ return new it.unimi.dsi.fastutil.shorts.ShortArrayList();
+ }).add((short) index);
+ // Moonrise end - block counting optimisations
++li;
++index;
diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java
index b02a0d9c71550d39aad08ed0932043531b661305..e2c7c9ed8bf4dc2eb10fbed59c518a2a596a0e82 100644
--- a/src/main/java/net/minecraft/util/ZeroBitStorage.java
+++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java
@@ -64,20 +64,22 @@ public class ZeroBitStorage implements BitStorage {
}
// Paper start - block counting
+ // Moonrise start - block counting optimisations
@Override
- public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.ints.IntArrayList> moonrise$countEntries() {
+ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> moonrise$countEntries() {
final int size = this.size;
- final int[] raw = new int[size];
+ final short[] raw = new short[size];
for (int i = 0; i < size; ++i) {
- raw[i] = i;
+ raw[i] = (short) i;
}
- final it.unimi.dsi.fastutil.ints.IntArrayList coordinates = it.unimi.dsi.fastutil.ints.IntArrayList.wrap(raw, size);
+ final it.unimi.dsi.fastutil.shorts.ShortArrayList coordinates = it.unimi.dsi.fastutil.shorts.ShortArrayList.wrap(raw, size);
- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.ints.IntArrayList> ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1);
+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1);
ret.put(0, coordinates);
return ret;
+ // Moonrise end - block counting optimisations
}
// Paper end - block counting
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
index 33747ef8211066155cd70ce2818862cf3e79db53..5b54d956486cec3c39824b15e37bf090798c5047 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -28,23 +28,29 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
public short fluidStateCount; // Gale - Airplane - reduce entity fluid lookups if no fluids
// Paper start - block counting
- private static final it.unimi.dsi.fastutil.ints.IntArrayList FULL_LIST = new it.unimi.dsi.fastutil.ints.IntArrayList(16*16*16);
+ private static final it.unimi.dsi.fastutil.shorts.ShortArrayList FULL_LIST = new it.unimi.dsi.fastutil.shorts.ShortArrayList(16 * 16 * 16); // Moonrise - block counting optimisations
static {
- for (int i = 0; i < (16*16*16); ++i) {
+ for (short i = 0; i < (16 * 16 * 16); ++i) { // Moonrise - block counting optimisations
FULL_LIST.add(i);
}
}
- private int specialCollidingBlocks;
- private final ca.spottedleaf.moonrise.common.list.IBlockDataList tickingBlocks = new ca.spottedleaf.moonrise.common.list.IBlockDataList();
+ // Moonrise start - block counting optimisations
+ private boolean isClient;
+ private static final short CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS = (short) 9999;
+ private short specialCollidingBlocks;
+ private final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = new ca.spottedleaf.moonrise.common.list.ShortList();
+ // Moonrise end - block counting optimisations
@Override
- public final int moonrise$getSpecialCollidingBlocks() {
- return this.specialCollidingBlocks;
+ // Moonrise start - block counting optimisations
+ public final boolean moonrise$hasSpecialCollidingBlocks() {
+ return this.specialCollidingBlocks != 0;
}
+ // Moonrise end - block counting optimisations
@Override
- public final ca.spottedleaf.moonrise.common.list.IBlockDataList moonrise$getTickingBlockList() {
+ public final ca.spottedleaf.moonrise.common.list.ShortList moonrise$getTickingBlockList() { // Moonrise - block counting optimisations
return this.tickingBlocks;
}
// Paper end - block counting
@@ -84,6 +90,45 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
return this.setBlockState(x, y, z, state, true);
}
+ // Moonrise start - block counting optimisations
+ private void updateBlockCallback(final int x, final int y, final int z, final BlockState newState,
+ final BlockState oldState) {
+ if (oldState == newState) {
+ return;
+ }
+
+ if (this.isClient) {
+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(newState)) {
+ this.specialCollidingBlocks = CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS;
+ }
+ return;
+ }
+
+ final boolean isSpecialOld = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(oldState);
+ final boolean isSpecialNew = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(newState);
+ if (isSpecialOld != isSpecialNew) {
+ if (isSpecialOld) {
+ --this.specialCollidingBlocks;
+ } else {
+ ++this.specialCollidingBlocks;
+ }
+ }
+
+ final boolean oldTicking = oldState.isRandomlyTicking();
+ final boolean newTicking = newState.isRandomlyTicking();
+ if (oldTicking != newTicking) {
+ final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = this.tickingBlocks;
+ final short position = (short) (x | (z << 4) | (y << (4 + 4)));
+
+ if (oldTicking) {
+ tickingBlocks.remove(position);
+ } else {
+ tickingBlocks.add(position);
+ }
+ }
+ }
+ // Moonrise end - block counting optimisations
+
public BlockState setBlockState(int x, int y, int z, BlockState state, boolean lock) {
BlockState iblockdata1;
@@ -103,7 +148,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
}
}
- if (!fluid.isEmpty()) {
+ if (!!fluid.isRandomlyTicking()) { // Moonrise - block counting optimisations
--this.tickingFluidCount;
--this.fluidStateCount; // Gale - Airplane - reduce entity fluid lookups if no fluids
}
@@ -115,26 +160,12 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
}
}
- if (!fluid1.isEmpty()) {
+ if (!!fluid1.isRandomlyTicking()) { // Moonrise - block counting optimisations
++this.tickingFluidCount;
++this.fluidStateCount; // Gale - Airplane - reduce entity fluid lookups if no fluids
}
- // Paper start - block counting
- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(iblockdata1)) {
- --this.specialCollidingBlocks;
- }
- if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) {
- ++this.specialCollidingBlocks;
- }
-
- if (iblockdata1.isRandomlyTicking()) {
- this.tickingBlocks.remove(x, y, z);
- }
- if (state.isRandomlyTicking()) {
- this.tickingBlocks.add(x, y, z, state);
- }
- // Paper end - block counting
+ this.updateBlockCallback(x, y, z, state, iblockdata1); // Moonrise - block counting optimisations
return iblockdata1;
}
@@ -158,10 +189,12 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
public void recalcBlockCounts() {
// Paper start - block counting
// reset, then recalculate
- this.nonEmptyBlockCount = (short)0;
- this.tickingBlockCount = (short)0;
- this.tickingFluidCount = (short)0;
- this.specialCollidingBlocks = (short)0;
+ // Moonrise start - block counting optimisations
+ this.nonEmptyBlockCount = (short) 0;
+ this.tickingBlockCount = (short) 0;
+ this.tickingFluidCount = (short) 0;
+ this.specialCollidingBlocks = (short) 0;
+ // Moonrise end - block counting optimisations
this.tickingBlocks.clear();
if (this.maybeHas((final BlockState state) -> !state.isAir())) {
@@ -170,18 +203,20 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
final int paletteSize = palette.getSize();
final net.minecraft.util.BitStorage storage = data.storage();
- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.ints.IntArrayList> counts;
+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> counts; // Moonrise - block counting optimisations
if (paletteSize == 1) {
counts = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1);
counts.put(0, FULL_LIST);
} else {
- counts = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingBitStorage)storage).moonrise$countEntries();
+ counts = ((ca.spottedleaf.moonrise.patches.block_counting.BlockCountingBitStorage) storage).moonrise$countEntries(); // Moonrise - block counting optimisations
}
- for (final java.util.Iterator<it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry<it.unimi.dsi.fastutil.ints.IntArrayList>> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext();) {
- final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry<it.unimi.dsi.fastutil.ints.IntArrayList> entry = iterator.next();
+ // Moonrise start - block counting optimisations
+ for (final java.util.Iterator<it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry<it.unimi.dsi.fastutil.shorts.ShortArrayList>> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext(); ) {
+ final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry<it.unimi.dsi.fastutil.shorts.ShortArrayList> entry = iterator.next();
final int paletteIdx = entry.getIntKey();
- final it.unimi.dsi.fastutil.ints.IntArrayList coordinates = entry.getValue();
+ final it.unimi.dsi.fastutil.shorts.ShortArrayList coordinates = entry.getValue();
+ // Moonrise end - block counting optimisations
final int paletteCount = coordinates.size();
final BlockState state = palette.valueFor(paletteIdx);
@@ -191,25 +226,32 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
}
if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isSpecialCollidingBlock(state)) {
- this.specialCollidingBlocks += paletteCount;
+ this.specialCollidingBlocks += (short) paletteCount; // Moonrise - block counting optimisations
}
- this.nonEmptyBlockCount += paletteCount;
+ this.nonEmptyBlockCount += (short) paletteCount; // Moonrise - block counting optimisations
if (state.isRandomlyTicking()) {
- this.tickingBlockCount += paletteCount;
- final int[] raw = coordinates.elements();
+ // Moonrise start - block counting optimisations
+ this.tickingBlockCount += (short) paletteCount;
+ final short[] raw = coordinates.elements();
+ final int rawLen = raw.length;
+
+ final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = this.tickingBlocks;
+
+ tickingBlocks.setMinCapacity(Math.min((rawLen + tickingBlocks.size()) * 3 / 2, 16 * 16 * 16));
+ // Moonrise end - block counting optimisations
java.util.Objects.checkFromToIndex(0, paletteCount, raw.length);
for (int i = 0; i < paletteCount; ++i) {
- this.tickingBlocks.add(raw[i], state);
+ tickingBlocks.add(raw[i]); // Moonrise - block counting optimisations
}
}
final FluidState fluid = state.getFluidState();
if (!fluid.isEmpty()) {
- //this.nonEmptyBlockCount += count; // fix vanilla bug: make non empty block count correct
+ //this.nonEmptyBlockCount += count; // fix vanilla bug: make non-empty block count correct // Moonrise - block counting optimisations
if (fluid.isRandomlyTicking()) {
- this.tickingFluidCount += paletteCount;
+ this.tickingFluidCount += (short) paletteCount; // Moonrise - block counting optimisations
}
this.fluidStateCount++; // Gale - Airplane - reduce entity fluid lookups if no fluids
}
@@ -233,7 +275,11 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
datapaletteblock.read(buf);
this.biomes = datapaletteblock;
- this.recalcBlockCounts(); // Paper - block counting
+ // Moonrise start - block counting optimisations
+ this.isClient = true;
+ // force has special colliding blocks to be true
+ this.specialCollidingBlocks = this.nonEmptyBlockCount != (short) 0 && this.maybeHas(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil::isSpecialCollidingBlock) ? CLIENT_FORCED_SPECIAL_COLLIDING_BLOCKS : (short) 0;
+ // Moonrise end - block counting optimisations
}
public void readBiomes(FriendlyByteBuf buf) {

View File

@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 2 Sep 2024 16:36:20 -0700
Subject: [PATCH] Moonrise: Do not send chunk radius packet from
PlayerList#setViewDistance
Original license: GPLv3
Original project: https://github.com/Tuinity/Moonrise
https://github.com/Tuinity/Moonrise/commit/ae12fd4f7bff3d6917394db71a35624d176c47a7
The underlying player chunk loader will do this for us. This fixes
sending possibly the wrong view distance.
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
index a608f57ebca98eda88ad749d0aad021678be54f9..1f301caa36212c85b06a33c714cb1050c449fdba 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
@@ -864,7 +864,7 @@ public final class RegionizedPlayerChunkLoader {
final int clientViewDistance = getClientViewDistance(this.player);
final int sendViewDistance = getSendViewDistance(loadViewDistance, clientViewDistance, playerDistances.sendViewDistance, worldDistances.sendViewDistance);
- // TODO check PlayerList diff in paper chunk system patch
+ // Moonrise - Do not send chunk radius packet from PlayerList#setViewDistance
// send view distances
this.player.connection.send(this.updateClientChunkRadius(sendViewDistance));
this.player.connection.send(this.updateClientSimulationDistance(tickViewDistance));
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 7d3dec682ca469a4e3f3f9bcd4120e040e6a8737..9ba3c4dc0285d1edcfc5d03de88bf9789b37b30b 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1721,7 +1721,7 @@ public abstract class PlayerList {
public void setViewDistance(int viewDistance) {
this.viewDistance = viewDistance;
- this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance));
+ //this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); // Moonrise - Do not send chunk radius packet from PlayerList#setViewDistance
Iterator iterator = this.server.getAllLevels().iterator();
while (iterator.hasNext()) {

View File

@@ -0,0 +1,110 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 16:29:23 -0700
Subject: [PATCH] Moonrise: Optimise countEntries for low size SimpleBitStorage
Original license: GPLv3
Original project:
- https://github.com/Tuinity/Moonrise
- https://github.com/PaperMC/Paper
https://github.com/Tuinity/Moonrise/commit/c2e2f0b9f20abb4c2247ffbaba892b3e364f7424
We can use a simple array lookup table by palette id when the
number of palette entries is low. This eliminates the need for
the map lookup on each entry.
diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java
index d11fad2a92fc39e9918b0000e737fcbfbe56a50c..5f613be5424a4955ec6cba2a1d4db110bd421849 100644
--- a/src/main/java/net/minecraft/util/SimpleBitStorage.java
+++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java
@@ -407,39 +407,66 @@ public class SimpleBitStorage implements BitStorage {
}
// Paper start - block counting
+ // Moonrise start - Optimise countEntries for low size SimpleBitStorage
@Override
public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> moonrise$countEntries() { // Moonrise - block counting optimisations
final int valuesPerLong = this.valuesPerLong;
final int bits = this.bits;
- final long mask = this.mask;
+ final long mask = (1L << bits) - 1L;
final int size = this.size;
- // we may be backed by global palette, so limit bits for init capacity
- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>( // Moonrise - block counting optimisations
- 1 << Math.min(6, bits)
- );
-
- int index = 0;
-
- for (long value : this.data) {
- int li = 0;
- do {
- final int paletteIdx = (int)(value & mask);
- value >>= bits;
+ if (bits <= 6) {
+ final it.unimi.dsi.fastutil.shorts.ShortArrayList[] byId = new it.unimi.dsi.fastutil.shorts.ShortArrayList[1 << bits];
+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1 << bits);
+
+ int index = 0;
+
+ for (long value : this.data) {
+ int li = 0;
+ do {
+ final int paletteIdx = (int) (value & mask);
+ value >>= bits;
+ ++li;
+
+ final it.unimi.dsi.fastutil.shorts.ShortArrayList coords = byId[paletteIdx];
+ if (coords != null) {
+ coords.add((short) index++);
+ continue;
+ } else {
+ final it.unimi.dsi.fastutil.shorts.ShortArrayList newCoords = new it.unimi.dsi.fastutil.shorts.ShortArrayList(64);
+ byId[paletteIdx] = newCoords;
+ newCoords.add((short) index++);
+ ret.put(paletteIdx, newCoords);
+ continue;
+ }
+ } while (li < valuesPerLong && index < size);
+ }
- ret.computeIfAbsent(paletteIdx, (final int key) -> {
- // Moonrise start - block counting optimisations
- return new it.unimi.dsi.fastutil.shorts.ShortArrayList();
- }).add((short) index);
- // Moonrise end - block counting optimisations
+ return ret;
+ } else {
+ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<it.unimi.dsi.fastutil.shorts.ShortArrayList> ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(
+ 1 << 6
+ );
+
+ int index = 0;
+
+ for (long value : this.data) {
+ int li = 0;
+ do {
+ final int paletteIdx = (int) (value & mask);
+ value >>= bits;
+ ++li;
+
+ ret.computeIfAbsent(paletteIdx, (final int key) -> {
+ return new it.unimi.dsi.fastutil.shorts.ShortArrayList(64);
+ }).add((short) index++);
+ } while (li < valuesPerLong && index < size);
+ }
- ++li;
- ++index;
- } while (li < valuesPerLong && index < size);
+ return ret;
}
-
- return ret;
}
+ // Moonrise end - Optimise countEntries for low size SimpleBitStorage
// Paper end - block counting
public static class InitializationException extends RuntimeException {

View File

@@ -0,0 +1,325 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 24 Oct 2024 08:20:45 -0700
Subject: [PATCH] Moonrise: fluid method optimisations
Original license: GPLv3
Original project:
- https://github.com/Tuinity/Moonrise
- https://github.com/PaperMC/Paper
This patch is based on the following mixin:
"ca/spottedleaf/moonrise/mixin/fluid/FlowingFluidMixin.java"
"ca/spottedleaf/moonrise/mixin/fluid/FluidStateMixin.java"
"ca/spottedleaf/moonrise/mixin/fluid/MappedRegistryMixin.java"
Use cached result to avoid indirection
For FlowingFluid#canPassThroughWall, try to avoid going to the cache for simple cases; additionally use better caching strategy
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java b/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java
new file mode 100644
index 0000000000000000000000000000000000000000..107c97089354edd35f330582f5e0c8a18e792a6e
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/fluid/FluidFluidState.java
@@ -0,0 +1,5 @@
+package ca.spottedleaf.moonrise.patches.fluid;
+
+public interface FluidFluidState {
+ public void moonrise$initCaches();
+}
diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java
index f22d22ebcedcc9c20225677844c86a1ad27c4211..92c2c37363fe31147f94f645c49e54ac626951cd 100644
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
@@ -78,6 +78,19 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
};
private final Object tagAdditionLock = new Object();
+ // Moonrise start - fluid method optimisations
+ private void injectFluidRegister(
+ final ResourceKey<?> resourceKey,
+ final T object
+ ) {
+ if (resourceKey.registryKey() == (Object) net.minecraft.core.registries.Registries.FLUID) {
+ for (final net.minecraft.world.level.material.FluidState possibleState : ((net.minecraft.world.level.material.Fluid) object).getStateDefinition().getPossibleStates()) {
+ ((ca.spottedleaf.moonrise.patches.fluid.FluidFluidState) (Object) possibleState).moonrise$initCaches();
+ }
+ }
+ }
+ // Moonrise end - fluid method optimisations
+
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle) {
this(key, lifecycle, false);
}
@@ -145,6 +158,7 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
this.toId.put(value, i);
this.registrationInfos.put(key, info);
this.registryLifecycle = this.registryLifecycle.add(info.lifecycle());
+ this.injectFluidRegister(key, value); // Moonrise - fluid method optimisations
return reference;
}
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
index cd45bfb51294e3510792320e2a159f1c6d554ce1..727b9c93a903d29d67548d34332eeedbdaac1f89 100644
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
@@ -65,6 +65,48 @@ public abstract class FlowingFluid extends Fluid {
// Gale end - Airplane - improve fluid direction caching - use our own cache
private final Map<FluidState, VoxelShape> shapes = Maps.newIdentityHashMap();
+ // Moonrise start - fluid method optimisations
+ private FluidState sourceFalling;
+ private FluidState sourceNotFalling;
+
+ private static final int TOTAL_FLOWING_STATES = FALLING.getPossibleValues().size() * LEVEL.getPossibleValues().size();
+ private static final int MIN_LEVEL = LEVEL.getPossibleValues().stream().sorted().findFirst().get().intValue();
+
+ // index = (falling ? 1 : 0) + level*2
+ private FluidState[] flowingLookUp;
+ private volatile boolean init;
+
+ private static final int COLLISION_OCCLUSION_CACHE_SIZE = 2048;
+ private static final ThreadLocal<ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[]> COLLISION_OCCLUSION_CACHE = ThreadLocal.withInitial(() -> new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[COLLISION_OCCLUSION_CACHE_SIZE]);
+
+
+ /**
+ * Due to init order, we need to use callbacks to initialise our state
+ */
+ private void init() {
+ synchronized (this) {
+ if (this.init) {
+ return;
+ }
+ this.flowingLookUp = new FluidState[TOTAL_FLOWING_STATES];
+ final FluidState defaultFlowState = this.getFlowing().defaultFluidState();
+ for (int i = 0; i < TOTAL_FLOWING_STATES; ++i) {
+ final int falling = i & 1;
+ final int level = (i >>> 1) + MIN_LEVEL;
+
+ this.flowingLookUp[i] = defaultFlowState.setValue(FALLING, falling == 1 ? Boolean.TRUE : Boolean.FALSE)
+ .setValue(LEVEL, Integer.valueOf(level));
+ }
+
+ final FluidState defaultFallState = this.getSource().defaultFluidState();
+ this.sourceFalling = defaultFallState.setValue(FALLING, Boolean.TRUE);
+ this.sourceNotFalling = defaultFallState.setValue(FALLING, Boolean.FALSE);
+
+ this.init = true;
+ }
+ }
+ // Moonrise end - fluid method optimisations
+
public FlowingFluid() {}
@Override
@@ -249,78 +291,65 @@ public abstract class FlowingFluid extends Fluid {
}
}
- private boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) {
- // Gale start - Airplane - improve fluid direction caching - modify to use our cache
- /*
- Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap;
-
- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) {
- object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FlowingFluid.OCCLUSION_CACHE.get();
- } else {
- object2bytelinkedopenhashmap = null;
+ // Moonrise start - fluid method optimisations
+ private static boolean canPassThroughWall(final Direction direction, final BlockGetter level,
+ final BlockPos fromPos, final BlockState fromState,
+ final BlockPos toPos, final BlockState toState) {
+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState) fromState).moonrise$emptyCollisionShape() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState) toState).moonrise$emptyCollisionShape()) {
+ // don't even try to cache simple cases
+ return true;
}
- */
- gg.airplane.structs.FluidDirectionCache<Block.BlockStatePairKey> cache = null;
-
- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) {
- cache = localFluidDirectionCache.get();
+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState) fromState).moonrise$occludesFullBlock() | ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState) toState).moonrise$occludesFullBlock()) {
+ // don't even try to cache simple cases
+ return false;
}
+ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[] cache = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState) fromState).moonrise$hasCache() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState) toState).moonrise$hasCache() ?
+ COLLISION_OCCLUSION_CACHE.get() : null;
- Block.BlockStatePairKey block_a;
+ final int keyIndex
+ = (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState) fromState).moonrise$uniqueId1() ^ ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState) toState).moonrise$uniqueId2() ^ ((ca.spottedleaf.moonrise.patches.collisions.util.CollisionDirection) (Object) direction).moonrise$uniqueId())
+ & (COLLISION_OCCLUSION_CACHE_SIZE - 1);
- /*
- if (object2bytelinkedopenhashmap != null) {
- block_a = new Block.BlockStatePairKey(state, fromState, face);
- byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a);
-
- if (b0 != 127) {
- return b0 != 0;
- }
- } else {
- block_a = null;
- }
- */
if (cache != null) {
- block_a = new Block.BlockStatePairKey(state, fromState, face);
- Boolean flag = cache.getValue(block_a);
- if (flag != null) {
- return flag;
- }
- } else {
- block_a = null;
- }
-
- VoxelShape voxelshape = state.getCollisionShape(world, pos);
- VoxelShape voxelshape1 = fromState.getCollisionShape(world, fromPos);
- boolean flag = !Shapes.mergedFaceOccludes(voxelshape, voxelshape1, face);
-
- /*
- if (object2bytelinkedopenhashmap != null) {
- if (object2bytelinkedopenhashmap.size() == 200) {
- object2bytelinkedopenhashmap.removeLastByte();
+ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey cached = cache[keyIndex];
+ if (cached != null && cached.first() == fromState && cached.second() == toState && cached.direction() == direction) {
+ return cached.result();
}
-
- object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0));
}
- */
+ final VoxelShape shape1 = fromState.getCollisionShape(level, fromPos);
+ final VoxelShape shape2 = toState.getCollisionShape(level, toPos);
+ final boolean result = !Shapes.mergedFaceOccludes(shape1, shape2, direction);
if (cache != null) {
- cache.putValue(block_a, flag);
+ // we can afford to replace in-use keys more often due to the excessive caching the collision patch does in mergedFaceOccludes
+ cache[keyIndex] = new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey(fromState, toState, direction, result);
}
- // Gale end - Airplane - improve fluid direction caching - modify to use our cache
- return flag;
+ return result;
}
+ // Moonrise end - fluid method optimisations
public abstract Fluid getFlowing();
public FluidState getFlowing(int level, boolean falling) {
- return (FluidState) ((FluidState) this.getFlowing().defaultFluidState().setValue(FlowingFluid.LEVEL, level)).setValue(FlowingFluid.FALLING, falling);
+ // Moonrise start - fluid method optimisations
+ final int amount = level;
+ if (!this.init) {
+ this.init();
+ }
+ final int index = (falling ? 1 : 0) | ((amount - MIN_LEVEL) << 1);
+ return this.flowingLookUp[index];
+ // Moonrise end - fluid method optimisations
}
public abstract Fluid getSource();
public FluidState getSource(boolean falling) {
- return (FluidState) this.getSource().defaultFluidState().setValue(FlowingFluid.FALLING, falling);
+ // Moonrise start - fluid method optimisations
+ if (!this.init) {
+ this.init();
+ }
+ return falling ? this.sourceFalling : this.sourceNotFalling;
+ // Moonrise end - fluid method optimisations
}
protected abstract boolean canConvertToSource(Level world);
diff --git a/src/main/java/net/minecraft/world/level/material/FluidState.java b/src/main/java/net/minecraft/world/level/material/FluidState.java
index 14bb12d2a0066e8b020f2e0e670a7a5c74633623..49e07b51e7a516d71abc1976069be2d8b523c83c 100644
--- a/src/main/java/net/minecraft/world/level/material/FluidState.java
+++ b/src/main/java/net/minecraft/world/level/material/FluidState.java
@@ -21,7 +21,7 @@ import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
-public final class FluidState extends StateHolder<Fluid, FluidState> {
+public final class FluidState extends StateHolder<Fluid, FluidState> implements ca.spottedleaf.moonrise.patches.fluid.FluidFluidState { // Moonrise - fluid method optimisations
public static final Codec<FluidState> CODEC = codec(BuiltInRegistries.FLUID.byNameCodec(), Fluid::defaultFluidState).stable();
public static final int AMOUNT_MAX = 9;
public static final int AMOUNT_FULL = 8;
@@ -32,20 +32,38 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
this.isEmpty = fluid.isEmpty(); // Paper - Perf: moved from isEmpty()
}
+ // Moonrise start - fluid method optimisations
+ private int amount;
+ //private boolean isEmpty;
+ private boolean isSource;
+ private float ownHeight;
+ private boolean isRandomlyTicking;
+ private BlockState legacyBlock;
+
+ @Override
+ public final void moonrise$initCaches() {
+ this.amount = this.getType().getAmount((FluidState) (Object) this);
+ //this.isEmpty = this.getType().isEmpty();
+ this.isSource = this.getType().isSource((FluidState) (Object) this);
+ this.ownHeight = this.getType().getOwnHeight((FluidState) (Object) this);
+ this.isRandomlyTicking = this.getType().isRandomlyTicking();
+ }
+ // Moonrise end - fluid method optimisations
+
public Fluid getType() {
return this.owner;
}
public boolean isSource() {
- return this.getType().isSource(this);
+ return this.isSource; // Moonrise - fluid method optimisations
}
public boolean isSourceOfType(Fluid fluid) {
- return this.owner == fluid && this.owner.isSource(this);
+ return this.isSource && this.owner == fluid; // Moonrise - fluid method optimisations
}
public boolean isEmpty() {
- return this.isEmpty; // Paper - Perf: moved into constructor
+ return this.isEmpty; // Moonrise - Perf: moved into constructor
}
public float getHeight(BlockGetter world, BlockPos pos) {
@@ -53,11 +71,11 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
}
public float getOwnHeight() {
- return this.getType().getOwnHeight(this);
+ return this.ownHeight; // Moonrise - fluid method optimisations
}
public int getAmount() {
- return this.getType().getAmount(this);
+ return this.amount; // Moonrise - fluid method optimisations
}
public boolean shouldRenderBackwardUpFace(BlockGetter world, BlockPos pos) {
@@ -83,7 +101,7 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
}
public boolean isRandomlyTicking() {
- return this.getType().isRandomlyTicking();
+ return this.isRandomlyTicking; // Moonrise - fluid method optimisations
}
public void randomTick(Level world, BlockPos pos, RandomSource random) {
@@ -95,7 +113,12 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
}
public BlockState createLegacyBlock() {
- return this.getType().createLegacyBlock(this);
+ // Moonrise start - fluid method optimisations
+ if (this.legacyBlock != null) {
+ return this.legacyBlock;
+ }
+ return this.legacyBlock = this.getType().createLegacyBlock((FluidState) (Object) this);
+ // Moonrise end - fluid method optimisations
}
@Nullable

View File

@@ -0,0 +1,364 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 24 Oct 2024 08:20:45 -0700
Subject: [PATCH] Moonrise: optimise palette reads
Original license: GPLv3
Original project:
- https://github.com/Tuinity/Moonrise
- https://github.com/PaperMC/Paper
This patch is based on the following mixin:
"ca/spottedleaf/moonrise/mixin/fast_palette/CrudeIncrementalIntIdentityHashBiMapMixin.java"
"ca/spottedleaf/moonrise/mixin/fast_palette/HashMapPaletteMixin.java"
"ca/spottedleaf/moonrise/mixin/fast_palette/LinearPaletteMixin.java"
"ca/spottedleaf/moonrise/mixin/fast_palette/PaletteMixin.java"
"ca/spottedleaf/moonrise/mixin/fast_palette/PalettedContainerMixin.java"
"ca/spottedleaf/moonrise/mixin/fast_palette/SingleValuePaletteMixin.java"
Replace palette read with optimised version
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a7abd239a9c59aa98947e7993962d75e9051902
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPalette.java
@@ -0,0 +1,9 @@
+package ca.spottedleaf.moonrise.patches.fast_palette;
+
+public interface FastPalette<T> {
+
+ public default T[] moonrise$getRawPalette(final FastPaletteData<T> src) {
+ return null;
+ }
+
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java
new file mode 100644
index 0000000000000000000000000000000000000000..4503f3495846a7d7ed082b9e24636044e4fbccd1
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/fast_palette/FastPaletteData.java
@@ -0,0 +1,9 @@
+package ca.spottedleaf.moonrise.patches.fast_palette;
+
+public interface FastPaletteData<T> {
+
+ public T[] moonrise$getPalette();
+
+ public void moonrise$setPalette(final T[] palette);
+
+}
diff --git a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
index 61dee55417bc802e25b9ba2f271d32d8c12844a9..5794ce906fd562f84f09f45ebb6d742dbc3ff3df 100644
--- a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
+++ b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
@@ -7,7 +7,7 @@ import java.util.Iterator;
import javax.annotation.Nullable;
import net.minecraft.core.IdMap;
-public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
+public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K>, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette<K> { // Moonrise - optimise palette reads
private static final int NOT_FOUND = -1;
private static final Object EMPTY_SLOT = null;
private static final float LOADFACTOR = 0.8F;
@@ -17,6 +17,16 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
private int nextId;
private int size;
+ // Moonrise start - optimise palette reads
+ private ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<K> reference;
+
+ @Override
+ public final K[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<K> src) {
+ this.reference = src;
+ return this.byId;
+ }
+ // Moonrise end - optimise palette reads
+
private CrudeIncrementalIntIdentityHashBiMap(int size) {
this.keys = (K[])(new Object[size]);
this.values = new int[size];
@@ -88,6 +98,12 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
this.byId = crudeIncrementalIntIdentityHashBiMap.byId;
this.nextId = crudeIncrementalIntIdentityHashBiMap.nextId;
this.size = crudeIncrementalIntIdentityHashBiMap.size;
+ // Moonrise start - optimise palette reads
+ final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<K> ref = this.reference;
+ if (ref != null) {
+ ref.moonrise$setPalette(this.byId);
+ }
+ // Moonrise end - optimise palette reads
}
public void addMapping(K value, int id) {
diff --git a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java
index c5e1040c239874dcf20b79472bf690ee7f0a9e5f..02b97e22fd9a122cc8f1628ef3205e87145a89fb 100644
--- a/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java
+++ b/src/main/java/net/minecraft/world/level/chunk/HashMapPalette.java
@@ -8,12 +8,19 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.VarInt;
import net.minecraft.util.CrudeIncrementalIntIdentityHashBiMap;
-public class HashMapPalette<T> implements Palette<T> {
+public class HashMapPalette<T> implements Palette<T>, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette<T> { // Moonrise - optimise palette reads
private final IdMap<T> registry;
private final CrudeIncrementalIntIdentityHashBiMap<T> values;
private final PaletteResize<T> resizeHandler;
private final int bits;
+ // Moonrise start - optimise palette reads
+ @Override
+ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<T> container) {
+ return ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette<T>) this.values).moonrise$getRawPalette(container);
+ }
+ // Moonrise end - optimise palette reads
+
public HashMapPalette(IdMap<T> idList, int bits, PaletteResize<T> listener, List<T> entries) {
this(idList, bits, listener);
entries.forEach(this.values::add);
diff --git a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java
index f4c3f2a49b8d023b8ef67529eba30cf31467d8bf..e070b9d805b86c0cf08804d1b14e580ab9986d7d 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LinearPalette.java
@@ -7,13 +7,20 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.VarInt;
import org.apache.commons.lang3.Validate;
-public class LinearPalette<T> implements Palette<T> {
+public class LinearPalette<T> implements Palette<T>, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette<T> { // Moonrise - optimise palette reads
private final IdMap<T> registry;
private final T[] values;
private final PaletteResize<T> resizeHandler;
private final int bits;
private int size;
+ // Moonrise start - optimise palette reads
+ @Override
+ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<T> container) {
+ return this.values;
+ }
+ // Moonrise end - optimise palette reads
+
private LinearPalette(IdMap<T> idList, int bits, PaletteResize<T> listener, List<T> list) {
this.registry = idList;
this.values = (T[])(new Object[1 << bits]);
diff --git a/src/main/java/net/minecraft/world/level/chunk/Palette.java b/src/main/java/net/minecraft/world/level/chunk/Palette.java
index e379f39cc6e03723a5323d8392b4c10bfde65115..91b16f0df26daa45f5a30eb36bdc9adac794779a 100644
--- a/src/main/java/net/minecraft/world/level/chunk/Palette.java
+++ b/src/main/java/net/minecraft/world/level/chunk/Palette.java
@@ -5,7 +5,7 @@ import java.util.function.Predicate;
import net.minecraft.core.IdMap;
import net.minecraft.network.FriendlyByteBuf;
-public interface Palette<T> {
+public interface Palette<T> extends ca.spottedleaf.moonrise.patches.fast_palette.FastPalette<T> { // Moonrise - optimise palette reads
int idFor(T object);
boolean maybeHas(Predicate<T> predicate);
diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
index 21e33bb69c58c99ddc497f57b77561f19ed19c37..38298a20daaef2dfe6d3939bffb7660ac406a786 100644
--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
@@ -58,6 +58,33 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
// this.threadingDetector.checkAndUnlock(); // Paper - disable this
}
+ // Moonrise start - optimise palette reads
+ private void updateData(final PalettedContainer.Data<T> data) {
+ if (data != null) {
+ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<T>) (Object) data).moonrise$setPalette(
+ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette<T>) data.palette).moonrise$getRawPalette((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<T>) (Object) data)
+ );
+ }
+ }
+
+ private T readPaletteSlow(final PalettedContainer.Data<T> data, final int paletteIdx) {
+ return data.palette.valueFor(paletteIdx);
+ }
+
+ private T readPalette(final PalettedContainer.Data<T> data, final int paletteIdx) {
+ final T[] palette = ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<T>) (Object) data).moonrise$getPalette();
+ if (palette == null) {
+ return this.readPaletteSlow(data, paletteIdx);
+ }
+
+ final T ret = palette[paletteIdx];
+ if (ret == null) {
+ throw new IllegalArgumentException("Palette index out of bounds");
+ }
+ return ret;
+ }
+ // Moonrise end - optimise palette reads
+
// Paper start - Anti-Xray - Add preset values
@Deprecated @io.papermc.paper.annotation.DoNotUse public static <T> Codec<PalettedContainer<T>> codecRW(IdMap<T> idList, Codec<T> entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue) { return PalettedContainer.codecRW(idList, entryCodec, paletteProvider, defaultValue, null); }
public static <T> Codec<PalettedContainer<T>> codecRW(IdMap<T> idList, Codec<T> entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue, T @org.jetbrains.annotations.Nullable [] presetValues) {
@@ -130,6 +157,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
}
}
// Paper end
+ this.updateData(this.data); // Moonrise - optimise palette reads
}
// Paper start - Anti-Xray - Add preset values
@@ -139,6 +167,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
this.registry = idList;
this.strategy = paletteProvider;
this.data = data;
+ this.updateData(this.data); // Moonrise - optimise palette reads
}
// Paper start - Anti-Xray - Add preset values
@@ -150,6 +179,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
this.registry = idList;
this.data = this.createOrReuseData(null, 0);
this.data.palette.idFor(object);
+ this.updateData(this.data); // Moonrise - optimise palette reads
}
private PalettedContainer.Data<T> createOrReuseData(@Nullable PalettedContainer.Data<T> previousData, int bits) {
@@ -176,6 +206,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
data2.copyFrom(data.palette, data.storage);
this.data = data2;
this.addPresetValues();
+ this.updateData(this.data); // Moonrise - optimise palette reads
return object == null ? -1 : data2.palette.idFor(object);
// Paper end
}
@@ -208,9 +239,12 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
}
private synchronized T getAndSet(int index, T value) { // Paper - synchronize
- int i = this.data.palette.idFor(value);
- int j = this.data.storage.getAndSet(index, i);
- return this.data.palette.valueFor(j);
+ // Moonrise start - optimise palette reads
+ final int paletteIdx = this.data.palette.idFor(value);
+ final PalettedContainer.Data<T> data = this.data;
+ final int prev = data.storage.getAndSet(index, paletteIdx);
+ return this.readPalette(data, prev);
+ // Moonrise end - optimise palette reads
}
public void set(int x, int y, int z, T value) {
@@ -234,8 +268,10 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
}
public T get(int index) { // Paper - public
- PalettedContainer.Data<T> data = this.data;
- return data.palette.valueFor(data.storage.get(index));
+ // Moonrise start - optimise palette reads
+ final PalettedContainer.Data<T> data = this.data;
+ return this.readPalette(data, data.storage.get(index));
+ // Moonrise end - optimise palette reads
}
@Override
@@ -256,6 +292,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
buf.readLongArray(data.storage.getRaw());
this.data = data;
this.addPresetValues(); // Paper - Anti-Xray - Add preset values (inefficient, but this isn't used by the server)
+ this.updateData(this.data); // Moonrise - optimise palette reads
} finally {
this.release();
}
@@ -451,7 +488,44 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
void accept(T object, int count);
}
- static record Data<T>(PalettedContainer.Configuration<T> configuration, BitStorage storage, Palette<T> palette) {
+ // Moonrise start - optimise palette reads
+ public static final class Data<T> implements ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<T> {
+
+ private final PalettedContainer.Configuration<T> configuration;
+ private final BitStorage storage;
+ private final Palette<T> palette;
+
+ private T[] moonrise$palette;
+
+ public Data(final PalettedContainer.Configuration<T> configuration, final BitStorage storage, final Palette<T> palette) {
+ this.configuration = configuration;
+ this.storage = storage;
+ this.palette = palette;
+ }
+
+ public PalettedContainer.Configuration<T> configuration() {
+ return this.configuration;
+ }
+
+ public BitStorage storage() {
+ return this.storage;
+ }
+
+ public Palette<T> palette() {
+ return this.palette;
+ }
+
+ @Override
+ public final T[] moonrise$getPalette() {
+ return this.moonrise$palette;
+ }
+
+ @Override
+ public final void moonrise$setPalette(final T[] palette) {
+ this.moonrise$palette = palette;
+ }
+
+ // Moonrise end - optimise palette reads
public void copyFrom(Palette<T> palette, BitStorage storage) {
for (int i = 0; i < storage.getSize(); i++) {
T object = palette.valueFor(storage.get(i));
diff --git a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java
index 24b608cfcd6f39db02e682e5d8162dc4ad9fd6d6..868ebabdcb76f4c61c9fb01e8cc75ab77845f29c 100644
--- a/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java
+++ b/src/main/java/net/minecraft/world/level/chunk/SingleValuePalette.java
@@ -8,12 +8,24 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.VarInt;
import org.apache.commons.lang3.Validate;
-public class SingleValuePalette<T> implements Palette<T> {
+public class SingleValuePalette<T> implements Palette<T>, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette<T> { // Moonrise - optimise palette reads
private final IdMap<T> registry;
@Nullable
private T value;
private final PaletteResize<T> resizeHandler;
+ // Moonrise start - optimise palette reads
+ private T[] rawPalette;
+
+ @Override
+ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<T> container) {
+ if (this.rawPalette != null) {
+ return this.rawPalette;
+ }
+ return this.rawPalette = (T[]) new Object[]{this.value};
+ }
+ // Moonrise end - optimise palette reads
+
public SingleValuePalette(IdMap<T> idList, PaletteResize<T> listener, List<T> entries) {
this.registry = idList;
this.resizeHandler = listener;
@@ -33,6 +45,11 @@ public class SingleValuePalette<T> implements Palette<T> {
return this.resizeHandler.onResize(1, object);
} else {
this.value = object;
+ // Moonrise start - optimise palette reads
+ if (this.rawPalette != null) {
+ this.rawPalette[0] = object;
+ }
+ // Moonrise end - optimise palette reads
return 0;
}
}
@@ -58,6 +75,11 @@ public class SingleValuePalette<T> implements Palette<T> {
@Override
public void read(FriendlyByteBuf buf) {
this.value = this.registry.byIdOrThrow(buf.readVarInt());
+ // Moonrise start - optimise palette reads
+ if (this.rawPalette != null) {
+ this.rawPalette[0] = this.value;
+ }
+ // Moonrise end - optimise palette reads
}
@Override

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Remove useless creating stats json bases on player name logic
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 509cf388b501fc446dc9bcd8e79bd7018ef33180..e562e401f4548fd5ec0968e3eab06c65348d3ddd 100644
index 9ba3c4dc0285d1edcfc5d03de88bf9789b37b30b..8722e0ca68d3077c6754b6f9f6474858bd0201bd 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1688,6 +1688,8 @@ public abstract class PlayerList {

View File

@@ -142,7 +142,7 @@ index 66614635b27dbcc6d4de027f1b1e32f0fd4b4dba..bbe9ff565f40663bd6a44baa46e9d558
this.cserver.getPluginManager().callEvent(event);
command = event.getMessage().substring(1);
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index e562e401f4548fd5ec0968e3eab06c65348d3ddd..4f1d226bc7c5eea06e837e99f268827ca94e221f 100644
index 8722e0ca68d3077c6754b6f9f6474858bd0201bd..d8c54a86890c0495dac8f2bff43075e4db00447f 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -759,6 +759,7 @@ public abstract class PlayerList {

View File

@@ -151,7 +151,7 @@ index 2e2caf1c92cd3616fe40a0cadd5e91f1ebae382d..cf02a980f0110ec9e1277bda846c67b9
if (packet == null || this.processedDisconnect) { // Spigot
return;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 4f1d226bc7c5eea06e837e99f268827ca94e221f..34b70d75295c4c7551ddd3569e3961d80e679a46 100644
index d8c54a86890c0495dac8f2bff43075e4db00447f..536943f9d9cf756a552188b4050f890e8345f524 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1642,7 +1642,7 @@ public abstract class PlayerList {

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Cache player profileResult
diff --git a/build.gradle.kts b/build.gradle.kts
index f1f6e53dfb1c4646b4eb2e122309ff5d7f06cb45..d7a72ae0f8bb0fadf304da62e6a3ca7cd03770fa 100644
index c2f2783fc4cdf5f222498d9bd08db152677bbfdb..e392f3fdc9b87c34f068743fff7ea486b19fa393 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -26,6 +26,10 @@ dependencies {
@@ -17,7 +17,7 @@ index f1f6e53dfb1c4646b4eb2e122309ff5d7f06cb45..d7a72ae0f8bb0fadf304da62e6a3ca7c
+ // Leaf end - Libraries
+
// Paper start
implementation("org.jline:jline-terminal-jansi:3.26.3") // Leaf - Bump Dependencies
implementation("org.jline:jline-terminal-jansi:3.27.1") // Leaf - Bump Dependencies
implementation("net.minecrell:terminalconsoleappender:1.3.0")
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index 2fd40cf41d54e450939d11b8ea183ab248072e22..3539397dba1246f345cd3cd210a6e6db876b1c89 100644

View File

@@ -46,7 +46,7 @@ index 74bf36f75b59b1e21b72afcf653447864d7c3f80..ef2d70c1bd21cff6a080205c38bbe8bf
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 9ef8919e4cdac61e2e4dd2fe96aed96cb1d5959e..f3c86193df3b7e1802f1e6fb91ba87506c834d79 100644
index ee0403cf2d6c088fa02a68432bb599094bc473f1..0874d1da44c82c87a8061233f1ed089ee0e0179d 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -559,6 +559,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Configurable connection message
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index c24c4de08fa2b787eba3417c20904d0fe1357688..08008d10efc88b0f152c3b2c82562c41d6bd38cb 100644
index 536943f9d9cf756a552188b4050f890e8345f524..cf5892892013ae54fc0a0e7826d820398f5ffa82 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -455,7 +455,7 @@ public abstract class PlayerList {

View File

@@ -3,21 +3,24 @@ From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Tue, 17 Sep 2024 02:35:13 -0400
Subject: [PATCH] Replace Entity active effects map with optimized collection
Dreeam TODO: check this
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 2539f688102a3c9c10ddeff39f3562668e9010be..827162f51cc58bd090ddc3576e5fe21043075e8d 100644
index 2539f688102a3c9c10ddeff39f3562668e9010be..d44e48719fcf51f6d425b9c18835ad44339177df 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -199,7 +199,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -199,6 +199,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
public static final String ATTRIBUTES_FIELD = "attributes";
private final AttributeMap attributes;
public CombatTracker combatTracker = new CombatTracker(this);
- public final Map<Holder<MobEffect>, MobEffectInstance> activeEffects = Maps.newHashMap();
+ public final Map<Holder<MobEffect>, MobEffectInstance> activeEffects = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(0); // Leaf - Replace Entity active effects map with optimized collection
+ // Need to figure out the difference of mem access pattern between hash map and obj2obj hash map (separate chaining vs open addressing)
+ // Benchmark is needed for get calls for this active effects map.
+ // Also need to check whether call from out of main using bukkit api
+ //public final Map<Holder<MobEffect>, MobEffectInstance> activeEffects = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(0); // Leaf - Replace Entity active effects map with optimized collection
public final Map<Holder<MobEffect>, MobEffectInstance> activeEffects = Maps.newHashMap();
private final NonNullList<ItemStack> lastHandItemStacks;
private final NonNullList<ItemStack> lastArmorItemStacks;
private ItemStack lastBodyItemStack;
@@ -1011,8 +1011,9 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -1011,8 +1015,9 @@ public abstract class LivingEntity extends Entity implements Attackable {
private void updateSynchronizedMobEffectParticles() {
// Leaf start - Remove stream in entity visible effects filter
List<ParticleOptions> list = new ArrayList<>();
@@ -28,7 +31,7 @@ index 2539f688102a3c9c10ddeff39f3562668e9010be..827162f51cc58bd090ddc3576e5fe210
if (effect.isVisible()) {
list.add(effect.getParticleOptions());
}
@@ -1020,7 +1021,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -1020,7 +1025,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
// Leaf end - Remove stream in entity visible effects filter
this.entityData.set(LivingEntity.DATA_EFFECT_PARTICLES, list);

View File

@@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Sat, 7 Sep 2024 02:12:55 -0400
Subject: [PATCH] Replace criterion map with optimized collection
diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java
index 061acf80f2c4fa62fe618958f2cede3e4563039d..2c43a6dc1ce15d87cf9a35c102675d09e5ab4b92 100644
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
+++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java
@@ -64,7 +64,7 @@ public class PlayerAdvancements {
private AdvancementHolder lastSelectedTab;
private boolean isFirstPacket = true;
private final Codec<PlayerAdvancements.Data> codec;
- public final Map<net.minecraft.advancements.critereon.SimpleCriterionTrigger<?>, Set<CriterionTrigger.Listener<?>>> criterionData = new java.util.IdentityHashMap<>(); // Paper - fix advancement data player leakage
+ public final Map<net.minecraft.advancements.critereon.SimpleCriterionTrigger<?>, Set<CriterionTrigger.Listener<?>>> criterionData = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(); // Paper - fix advancement data player leakage // Leaf - Replace criterion map with optimized collection
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerManager, ServerAdvancementManager advancementLoader, Path filePath, ServerPlayer owner) {
this.playerList = playerManager;

View File

@@ -31,7 +31,7 @@ index 5e89428321d91edb893826b0eb0b9050d327d310..3e8882e4779d6037025e7ee26ebbb46a
private DensityFunction wrapNew(DensityFunction function) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java b/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java
index 9df053ddff459d4aab478106c6e66a5fc3cda8f6..49e2aee0093eb8fa34fc7fe11f376c1dd67aa5f1 100644
index 7ba3a3ca57b55f796a90b700b930f365c3508484..2a0cd84c8a530bc34b6bc8034bd7156131837139 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/SurfaceRules.java
@@ -314,8 +314,14 @@ public class SurfaceRules {

View File

@@ -6,7 +6,7 @@ Subject: [PATCH] Do not place player if the server is full
Fix https://github.com/PaperMC/Paper/issues/10668
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 2614933317f102a0f559374d2bb8efc70b230e85..27015c62e1c45d36e58ae1323417739836632933 100644
index cf5892892013ae54fc0a0e7826d820398f5ffa82..29bb61346b7fee7c32e5e3357d42365757f203d9 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -380,6 +380,13 @@ public abstract class PlayerList {

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Configurable player knockback zombie
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 827162f51cc58bd090ddc3576e5fe21043075e8d..328630ff8df5bf67e5df190443e436e996942257 100644
index d44e48719fcf51f6d425b9c18835ad44339177df..d99a80657db3a24f79f094d7dbf81faab506937c 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -2037,6 +2037,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -2041,6 +2041,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
public void knockback(double d0, double d1, double d2, @Nullable Entity attacker, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause cause) { // Paper - knockback events
@@ -17,7 +17,7 @@ index 827162f51cc58bd090ddc3576e5fe21043075e8d..328630ff8df5bf67e5df190443e436e9
d0 *= 1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
if (true || d0 > 0.0D) { // CraftBukkit - Call event even when force is 0
//this.hasImpulse = true; // CraftBukkit - Move down
@@ -2064,6 +2066,20 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -2068,6 +2070,20 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
}

View File

@@ -78,10 +78,10 @@ index 6469cd96f0ecb98f4e15e9865837d8c6a07128ad..846ddd4fcbb14db6f3eac9169de6850c
ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - fix slot desync - always refresh player inventory
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 328630ff8df5bf67e5df190443e436e996942257..b6402881d5ee626e07996c3ceac1ac49ce2751c1 100644
index d99a80657db3a24f79f094d7dbf81faab506937c..241e2598973939b7d19768cd9ca7cd8f3818c053 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3413,7 +3413,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -3417,7 +3417,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
ItemStack itemstack1 = itemstack;
ItemStack itemstack2 = this.getItemBySlot(enumitemslot);
@@ -90,7 +90,7 @@ index 328630ff8df5bf67e5df190443e436e996942257..b6402881d5ee626e07996c3ceac1ac49
// Paper start - PlayerArmorChangeEvent
if (this instanceof ServerPlayer && enumitemslot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) {
final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack1);
@@ -3497,7 +3497,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -3501,7 +3501,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
equipmentChanges.forEach((enumitemslot, itemstack) -> {
ItemStack itemstack1 = itemstack.copy();

View File

@@ -12,7 +12,7 @@ before spawning, it checks isSpawnPositionOk() for the position which loads the
This patch ensures the chunk at the random location is loaded before trying to spawn the reinforcement zombie in it.
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
index ac9a63c70b5ddfb528eff559ca1464051d8865f4..7836f6142f1066d7f59724929ff7d8a2074bdfed 100644
index aa1fd8f2fba06292e93aba279cf18640b6909add..49c37853a0c26cef749a8a5ef4130554c0319ad9 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -384,6 +384,12 @@ public class Zombie extends Monster {

View File

@@ -23,7 +23,7 @@ But it is still recommending to use those packet based, virtual entity
based NPC plugins, e.g. ZNPC Plus, Adyeshach, Fancy NPC, etc.
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
index e42677bb004201efe1702779a78cc8d0ca05e80f..6676be8304e9415099ed423d3315180cafebd928 100644
index e42677bb004201efe1702779a78cc8d0ca05e80f..3fa04bad6f5263c626c22ef0a795947391e1e710 100644
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
@@ -42,6 +42,12 @@ class PaperEventManager {
@@ -31,7 +31,7 @@ index e42677bb004201efe1702779a78cc8d0ca05e80f..6676be8304e9415099ed423d3315180c
throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously.");
} else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) {
+ // Leaf start - Multithreaded tracker
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) {
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled && Thread.currentThread() instanceof org.dreeam.leaf.async.tracker.MultithreadedTracker.MultithreadedTrackerThread) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent);
+ return;
+ }
@@ -300,7 +300,7 @@ index 05125144ce0cb50fa6ac769fa025cda010c93f14..189bfe0e97943f3f560fa3c2674013e2
set.clear();
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index f3c86193df3b7e1802f1e6fb91ba87506c834d79..9211869969aad355433129c519ddd6e73f8657df 100644
index 0874d1da44c82c87a8061233f1ed089ee0e0179d..6d8fb4fe9733bd1e83af7f8c148bdb54fa26a14b 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -2398,7 +2398,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.

View File

@@ -20,7 +20,7 @@ index fca917561944017e032ea39ffb22cbd2c89b9f51..b4a51c54eb6a93d107a45fb01c9a3c9f
// Paper end - Affects Spawning API
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
index 7836f6142f1066d7f59724929ff7d8a2074bdfed..4b21a70ce040320eb8b1db9aa2de22bfafe4c3bb 100644
index 49c37853a0c26cef749a8a5ef4130554c0319ad9..776e0295f0ba38157cabdc7ab5d0a3f845bad158 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -392,7 +392,7 @@ public class Zombie extends Monster {

View File

@@ -18,6 +18,23 @@ index 11b7f15755dde766140c29bedca456c80d53293f..749d00449ac3f3c79bfc73a5517ea3a0
super(run, name);
this.id = id;
}
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
index 3fa04bad6f5263c626c22ef0a795947391e1e710..411bc27324c34e4cad1849512a4531214d7fe9d2 100644
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
@@ -48,6 +48,12 @@ class PaperEventManager {
return;
}
// Leaf end - Multithreaded tracker
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && Thread.currentThread() instanceof org.dreeam.leaf.async.locate.AsyncLocator.AsyncLocatorThread) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent);
+ return;
+ }
+ // Leaf end - Async locator
throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
}
// Leaves start - skip photographer
diff --git a/src/main/java/net/minecraft/server/commands/LocateCommand.java b/src/main/java/net/minecraft/server/commands/LocateCommand.java
index 39f5deea47d8f573c3cfec5df431216ee806c32c..51994f272737f8754aac41dc0c55f43f45617519 100644
--- a/src/main/java/net/minecraft/server/commands/LocateCommand.java
@@ -231,51 +248,6 @@ index d8ce44a180f848f4c9c04967470c4359af979b2f..90abb83a6baa60bbcbedc7d818c3bc9f
user.swing(hand, true);
return InteractionResultHolder.success(itemstack);
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
index 00ed0d5ad535faa36111ab28bb0cf1317eb067ec..477aa4f069ab18de2c764f74dc26db52a95d6206 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
@@ -132,12 +132,35 @@ public abstract class ChunkGenerator {
final List<org.bukkit.generator.structure.Structure> apiStructures = structures.stream().map(Holder::value).map(nms -> org.bukkit.craftbukkit.generator.structure.CraftStructure.minecraftToBukkit(nms)).toList();
if (!apiStructures.isEmpty()) {
final io.papermc.paper.event.world.StructuresLocateEvent event = new io.papermc.paper.event.world.StructuresLocateEvent(bukkitWorld, origin, apiStructures, radius, skipReferencedStructures);
- if (!event.callEvent()) {
- return null;
- }
- if (event.getResult() != null) {
- return Pair.of(io.papermc.paper.util.MCUtil.toBlockPos(event.getResult().pos()), world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(event.getResult().structure())));
+ // Leaf start - Async locator - Ensure event is called on server thread
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled &&
+ Thread.currentThread() instanceof org.dreeam.leaf.async.locate.AsyncLocator.AsyncLocatorThread) {
+ final java.util.concurrent.atomic.AtomicBoolean shouldReturn = new java.util.concurrent.atomic.AtomicBoolean(false);
+ CompletableFuture<Pair<BlockPos, Holder<Structure>>> futureEvent = net.minecraft.server.MinecraftServer.getServer().submit(() -> {
+ if (!event.callEvent()) {
+ shouldReturn.set(true);
+ return null;
+ }
+ if (event.getResult() != null) {
+ shouldReturn.set(true);
+ return Pair.of(io.papermc.paper.util.MCUtil.toBlockPos(event.getResult().pos()), world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(event.getResult().structure())));
+ }
+ shouldReturn.set(false);
+ return null;
+ });
+ Pair<BlockPos, Holder<Structure>> result = futureEvent.join();
+ if (shouldReturn.get()) {
+ return result;
+ }
+ } else {
+ if (!event.callEvent()) {
+ return null;
+ }
+ if (event.getResult() != null) {
+ return Pair.of(io.papermc.paper.util.MCUtil.toBlockPos(event.getResult().pos()), world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(event.getResult().structure())));
+ }
}
+ // Leaf end - Async locator - Ensure event is called on server thread
center = io.papermc.paper.util.MCUtil.toBlockPosition(event.getOrigin());
radius = event.getRadius();
skipReferencedStructures = event.shouldFindUnexplored();
diff --git a/src/main/java/org/dreeam/leaf/async/locate/AsyncLocator.java b/src/main/java/org/dreeam/leaf/async/locate/AsyncLocator.java
new file mode 100644
index 0000000000000000000000000000000000000000..0eaa9b60ac139db47a028970557c3a84166efc49

View File

@@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 7 Nov 2017 00:01:04 -0500
Subject: [PATCH] EMC: Don't use snapshots for TileEntity::getOwner
Original license: MIT
Original project: https://github.com/starlis/empirecraft
Also see EMC-Default-don-t-use-blockstate-snapshots.patch
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
index 73c9f91457683e8e6bd8293b4393ccbd984eddb7..7b38835bdac33dce9ed7ca1c0b3d43fdc2224d0c 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -398,7 +398,7 @@ public abstract class BlockEntity {
// CraftBukkit start - add method
public InventoryHolder getOwner() {
// Paper start
- return getOwner(true);
+ return getOwner(org.dreeam.leaf.config.modules.opt.TileEntitySnapshotCreation.enabled); // Leaf - EMC - don't use snapshots
}
public InventoryHolder getOwner(boolean useSnapshot) {
// Paper end
diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/TileEntitySnapshotCreation.java b/src/main/java/org/dreeam/leaf/config/modules/opt/TileEntitySnapshotCreation.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c0d34c15c12f9587f518de17e3a3d5289e21f9c
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/config/modules/opt/TileEntitySnapshotCreation.java
@@ -0,0 +1,18 @@
+package org.dreeam.leaf.config.modules.opt;
+
+import org.dreeam.leaf.config.ConfigModules;
+import org.dreeam.leaf.config.EnumConfigCategory;
+
+public class TileEntitySnapshotCreation extends ConfigModules {
+
+ public String getBasePath() {
+ return EnumConfigCategory.PERF.getBaseKeyName();
+ }
+
+ public static boolean enabled = true;
+
+ @Override
+ public void onLoaded() {
+ enabled = config.getBoolean(getBasePath() + ".create-snapshot-on-retrieving-blockstate", enabled);
+ }
+}

View File

@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 28 Jun 2018 22:13:44 -0400
Subject: [PATCH] EMC: Default don't use blockstate snapshots
Original license: MIT
Original project: https://github.com/starlis/empirecraft
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index ac11f18690434922179b61ffcc3036dea025b0cb..72d30afa4c03aa82329f321a3a3ddd507cf94502 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -331,7 +331,7 @@ public class CraftBlock implements Block {
@Override
public BlockState getState() {
- return CraftBlockStates.getBlockState(this);
+ return CraftBlockStates.getBlockState(this, org.dreeam.leaf.config.modules.opt.TileEntitySnapshotCreation.enabled); // Leaf - EMC - default to not use snapshots
}
// Paper start
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index b7ff7af2513204b151340538d50a65c850bdb75f..836fe576a0250a3b002e91b8587935f3e83e5fd6 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -236,7 +236,7 @@ public final class CraftBlockStates {
public static BlockState getBlockState(Block block) {
// Paper start
- return CraftBlockStates.getBlockState(block, true);
+ return CraftBlockStates.getBlockState(block, org.dreeam.leaf.config.modules.opt.TileEntitySnapshotCreation.enabled); // Leaf - default to not use snapshots
}
public static BlockState getBlockState(Block block, boolean useSnapshot) {
// Paper end

View File

@@ -0,0 +1,59 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Fri, 25 Oct 2024 22:27:07 -0400
Subject: [PATCH] Cache tile entity position
Check if there is a way to cache isRemoved without problem
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
index ae693e08434d251ee57b89d606d3cbd51288d496..61d6f80af62fcc48c16def1905cc57c417fe90a4 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -1002,13 +1002,16 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
private class RebindableTickingBlockEntityWrapper implements TickingBlockEntity {
private TickingBlockEntity ticker;
+ private BlockPos cachedPos; // Leaf - Cache tile entity position
RebindableTickingBlockEntityWrapper(final LevelChunk wrapped, final TickingBlockEntity tickingblockentity) {
this.ticker = tickingblockentity;
+ this.cachedPos = this.ticker.getPos(); // Leaf - Cache tile entity position
}
void rebind(TickingBlockEntity wrapped) {
this.ticker = wrapped;
+ this.cachedPos = this.ticker.getPos(); // Leaf - Cache tile entity position
}
@Override
@@ -1023,7 +1026,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@Override
public BlockPos getPos() {
- return this.ticker.getPos();
+ return this.cachedPos; // Leaf - Cache tile entity position
}
@Override
@@ -1041,10 +1044,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
private final T blockEntity;
private final BlockEntityTicker<T> ticker;
private boolean loggedInvalidBlockState;
+ private BlockPos cachedPos; // Leaf - Cache tile entity position
BoundTickingBlockEntity(final BlockEntity tileentity, final BlockEntityTicker blockentityticker) {
this.blockEntity = (T) tileentity; // CraftBukkit - decompile error
this.ticker = blockentityticker;
+ this.cachedPos = this.blockEntity.getBlockPos(); // Leaf - Cache tile entity position
}
@Override
@@ -1088,7 +1093,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@Override
public BlockPos getPos() {
- return this.blockEntity.getBlockPos();
+ return this.cachedPos; // Leaf - Cache tile entity position
}
@Override

View File

@@ -0,0 +1,216 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Mon, 1 Nov 2077 00:00:00 +0800
Subject: [PATCH] TT20 Lag compensation
This patch was ported from project: https://github.com/snackbag/TT20
Project license: AGPL-3.0
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 09e55f62b4cea5b058e04356252f4f56957646b8..279289e0c3dc65fed0ee4b2f5b0ef077ab433d5e 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1628,6 +1628,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.server.spark.tickStart(); // Paper - spark
new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper - Server Tick Events
+ // Leaf start - Lag compensation tick hook
+ if (org.dreeam.leaf.config.modules.misc.LagCompensation.enabled) {
+ org.dreeam.leaf.misc.LagCompensation.TPSCalculator.onTick();
+ }
+ // Leaf end - Lag Compensation tick hook
+
++this.tickCount;
this.tickRateManager.tick();
this.tickChildren(shouldKeepTicking);
diff --git a/src/main/java/net/minecraft/world/level/material/LavaFluid.java b/src/main/java/net/minecraft/world/level/material/LavaFluid.java
index 2d492d849ff73a738dfbcb16507feb89bf19a962..0e70f0b88d67c2da4094fd73998d1bddf835b724 100644
--- a/src/main/java/net/minecraft/world/level/material/LavaFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/LavaFluid.java
@@ -180,7 +180,13 @@ public abstract class LavaFluid extends FlowingFluid {
@Override
public int getTickDelay(LevelReader world) {
- return world.dimensionType().ultraWarm() ? world.getWorldBorder().world.purpurConfig.lavaSpeedNether : world.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur
+ // Leaf start - Lag compensation
+ if (org.dreeam.leaf.config.modules.misc.LagCompensation.enabled && org.dreeam.leaf.config.modules.misc.LagCompensation.enableForLava) {
+ return world.dimensionType().ultraWarm() ? org.dreeam.leaf.misc.LagCompensation.tt20(world.getWorldBorder().world.purpurConfig.lavaSpeedNether, true) : org.dreeam.leaf.misc.LagCompensation.tt20(world.getWorldBorder().world.purpurConfig.lavaSpeedNotNether, true); // Purpur // Leaf
+ } else {
+ return world.dimensionType().ultraWarm() ? world.getWorldBorder().world.purpurConfig.lavaSpeedNether : world.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur
+ }
+ // Leaf end - Lag compensation
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
index 9dcdb2f4001115db0c26fdbf86531dbe6098485d..53a28a4026c50a66e53241ffe660b4d72600db39 100644
--- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
@@ -122,7 +122,13 @@ public abstract class WaterFluid extends FlowingFluid {
@Override
public int getTickDelay(LevelReader world) {
- return 5;
+ // Leaf start - Lag compensation
+ if (org.dreeam.leaf.config.modules.misc.LagCompensation.enabled && org.dreeam.leaf.config.modules.misc.LagCompensation.enableForWater) {
+ return org.dreeam.leaf.misc.LagCompensation.tt20(5, true);
+ } else {
+ return 5;
+ }
+ // Leaf end - Lag compensation
}
@Override
diff --git a/src/main/java/org/dreeam/leaf/config/modules/misc/LagCompensation.java b/src/main/java/org/dreeam/leaf/config/modules/misc/LagCompensation.java
new file mode 100644
index 0000000000000000000000000000000000000000..d90ab4cb8c69318f8bf77af12e2840fb5d519931
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/config/modules/misc/LagCompensation.java
@@ -0,0 +1,26 @@
+package org.dreeam.leaf.config.modules.misc;
+
+import org.dreeam.leaf.config.ConfigModules;
+import org.dreeam.leaf.config.EnumConfigCategory;
+
+public class LagCompensation extends ConfigModules {
+
+ public String getBasePath() {
+ return EnumConfigCategory.MISC.getBaseKeyName() + ".lag-compensation";
+ }
+
+ public static boolean enabled = false;
+ public static boolean enableForWater = false;
+ public static boolean enableForLava = false;
+
+ @Override
+ public void onLoaded() {
+ config.addComment(getBasePath(), """
+ This section contains lag compensation features,
+ which could ensure basic playing experience during a lag.""");
+
+ enabled = config.getBoolean(getBasePath() + ".enabled", enabled);
+ enableForWater = config.getBoolean(getBasePath() + ".enable-for-water", enableForWater);
+ enableForLava = config.getBoolean(getBasePath() + ".enable-for-lava", enableForLava);
+ }
+}
diff --git a/src/main/java/org/dreeam/leaf/misc/LagCompensation.java b/src/main/java/org/dreeam/leaf/misc/LagCompensation.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ec73caf7163ed0a66fc2dfec781e190163d06b8
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/misc/LagCompensation.java
@@ -0,0 +1,114 @@
+package org.dreeam.leaf.misc;
+
+import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
+
+import java.util.Collections;
+import java.util.List;
+
+public class LagCompensation {
+
+ public static float tt20(float ticks, boolean limitZero) {
+ float newTicks = (float) rawTT20(ticks);
+
+ if (limitZero) return newTicks > 0 ? newTicks : 1;
+ else return newTicks;
+ }
+
+ public static int tt20(int ticks, boolean limitZero) {
+ int newTicks = (int) Math.ceil(rawTT20(ticks));
+
+ if (limitZero) return newTicks > 0 ? newTicks : 1;
+ else return newTicks;
+ }
+
+ public static double tt20(double ticks, boolean limitZero) {
+ double newTicks = rawTT20(ticks);
+
+ if (limitZero) return newTicks > 0 ? newTicks : 1;
+ else return newTicks;
+ }
+
+ public static double rawTT20(double ticks) {
+ return ticks == 0 ? 0 : ticks * TPSCalculator.getMostAccurateTPS() / TPSCalculator.MAX_TPS;
+ }
+
+ public static class TPSCalculator {
+ public static Long lastTick;
+ public static Long currentTick;
+ private static double allMissedTicks = 0;
+ private static final List<Double> tpsHistory = Collections.synchronizedList(new DoubleArrayList());
+ private static final int historyLimit = 40;
+
+ public static final int MAX_TPS = 20;
+ public static final int FULL_TICK = 50;
+
+ private TPSCalculator() {}
+
+ public static void onTick() {
+ if (currentTick != null) {
+ lastTick = currentTick;
+ }
+
+ currentTick = System.currentTimeMillis();
+ addToHistory(getTPS());
+ clearMissedTicks();
+ missedTick();
+ }
+
+ private static void addToHistory(double tps) {
+ if (tpsHistory.size() >= historyLimit) {
+ tpsHistory.removeFirst();
+ }
+
+ tpsHistory.add(tps);
+ }
+
+ public static long getMSPT() {
+ return currentTick - lastTick;
+ }
+
+ public static double getAverageTPS() {
+ double sum = 0.0;
+ for (double value : tpsHistory) {
+ sum += value;
+ }
+ return tpsHistory.isEmpty() ? 0.1 : sum / tpsHistory.size();
+ }
+
+ public static double getTPS() {
+ if (lastTick == null) return -1;
+ if (getMSPT() <= 0) return 0.1;
+
+ double tps = 1000 / (double) getMSPT();
+ return tps > MAX_TPS ? MAX_TPS : tps;
+ }
+
+ public static void missedTick() {
+ if (lastTick == null) return;
+
+ long mspt = getMSPT() <= 0 ? 50 : getMSPT();
+ double missedTicks = (mspt / (double) FULL_TICK) - 1;
+ allMissedTicks += missedTicks <= 0 ? 0 : missedTicks;
+ }
+
+ public static double getMostAccurateTPS() {
+ return Math.min(getTPS(), getAverageTPS());
+ }
+
+ public double getAllMissedTicks() {
+ return allMissedTicks;
+ }
+
+ public static int applicableMissedTicks() {
+ return (int) Math.floor(allMissedTicks);
+ }
+
+ public static void clearMissedTicks() {
+ allMissedTicks -= applicableMissedTicks();
+ }
+
+ public void resetMissedTicks() {
+ allMissedTicks = 0;
+ }
+ }
+}
\ No newline at end of file