diff --git a/patches/api/0006-Bump-Dependencies.patch b/patches/api/0006-Bump-Dependencies.patch index cf486905..a9b254c7 100644 --- a/patches/api/0006-Bump-Dependencies.patch +++ b/patches/api/0006-Bump-Dependencies.patch @@ -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 { +@@ -165,13 +176,13 @@ tasks.withType { 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 { "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:") diff --git a/patches/server/0016-Bump-Dependencies.patch b/patches/server/0016-Bump-Dependencies.patch index ccb69388..5f723151 100644 --- a/patches/server/0016-Bump-Dependencies.patch +++ b/patches/server/0016-Bump-Dependencies.patch @@ -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 { diff --git a/patches/server/0049-Linear-region-file-format.patch b/patches/server/0049-Linear-region-file-format.patch index eef2b9a4..836998d5 100644 --- a/patches/server/0049-Linear-region-file-format.patch +++ b/patches/server/0049-Linear-region-file-format.patch @@ -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 +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: ++ *
++     * {@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;
++     * }
++     * 
++ * ++ * @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 diff --git a/patches/server/0059-Moonrise-Optimize-nearby-players-for-spawning-iterat.patch b/patches/server/0060-Moonrise-Optimize-nearby-players-for-spawning-iterat.patch similarity index 100% rename from patches/server/0059-Moonrise-Optimize-nearby-players-for-spawning-iterat.patch rename to patches/server/0060-Moonrise-Optimize-nearby-players-for-spawning-iterat.patch diff --git a/patches/server/0060-Moonrise-Store-ticking-blocks-in-chunk-sections-as-p.patch b/patches/server/0060-Moonrise-Store-ticking-blocks-in-chunk-sections-as-p.patch deleted file mode 100644 index f2d15536..00000000 --- a/patches/server/0060-Moonrise-Store-ticking-blocks-in-chunk-sections-as-p.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -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 - } - } - diff --git a/patches/server/0061-Moonrise-block-counting-optimisations.patch b/patches/server/0061-Moonrise-block-counting-optimisations.patch new file mode 100644 index 00000000..e0d58f12 --- /dev/null +++ b/patches/server/0061-Moonrise-block-counting-optimisations.patch @@ -0,0 +1,504 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +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 moonrise$countEntries(); ++ public Int2ObjectOpenHashMap 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 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 moonrise$countEntries() { +- final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); ++ public default it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap 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 moonrise$countEntries() { ++ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap 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 ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>( ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap 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 moonrise$countEntries() { ++ public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap 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 ret = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(1); ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap 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 counts; ++ final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap 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> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext();) { +- final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry entry = iterator.next(); ++ // Moonrise start - block counting optimisations ++ for (final java.util.Iterator> iterator = counts.int2ObjectEntrySet().fastIterator(); iterator.hasNext(); ) { ++ final it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry 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) { diff --git a/patches/server/0061-Moonrise-Optimise-BiomeManager-getFiddle.patch b/patches/server/0062-Moonrise-Optimise-BiomeManager-getFiddle.patch similarity index 100% rename from patches/server/0061-Moonrise-Optimise-BiomeManager-getFiddle.patch rename to patches/server/0062-Moonrise-Optimise-BiomeManager-getFiddle.patch diff --git a/patches/server/0063-Moonrise-Do-not-send-chunk-radius-packet-from-Player.patch b/patches/server/0063-Moonrise-Do-not-send-chunk-radius-packet-from-Player.patch new file mode 100644 index 00000000..f424663c --- /dev/null +++ b/patches/server/0063-Moonrise-Do-not-send-chunk-radius-packet-from-Player.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +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()) { diff --git a/patches/server/0062-Moonrise-Add-direct-lookup-by-chunk-for-NearbyPlayer.patch b/patches/server/0064-Moonrise-Add-direct-lookup-by-chunk-for-NearbyPlayer.patch similarity index 100% rename from patches/server/0062-Moonrise-Add-direct-lookup-by-chunk-for-NearbyPlayer.patch rename to patches/server/0064-Moonrise-Add-direct-lookup-by-chunk-for-NearbyPlayer.patch diff --git a/patches/server/0063-Moonrise-Optimise-checkInsideBlocks.patch b/patches/server/0065-Moonrise-Optimise-checkInsideBlocks.patch similarity index 100% rename from patches/server/0063-Moonrise-Optimise-checkInsideBlocks.patch rename to patches/server/0065-Moonrise-Optimise-checkInsideBlocks.patch diff --git a/patches/server/0064-Moonrise-Avoid-streams-for-block-retrieval-in-Entity.patch b/patches/server/0066-Moonrise-Avoid-streams-for-block-retrieval-in-Entity.patch similarity index 100% rename from patches/server/0064-Moonrise-Avoid-streams-for-block-retrieval-in-Entity.patch rename to patches/server/0066-Moonrise-Avoid-streams-for-block-retrieval-in-Entity.patch diff --git a/patches/server/0067-Moonrise-Optimise-countEntries-for-low-size-SimpleBi.patch b/patches/server/0067-Moonrise-Optimise-countEntries-for-low-size-SimpleBi.patch new file mode 100644 index 00000000..2ce2cf37 --- /dev/null +++ b/patches/server/0067-Moonrise-Optimise-countEntries-for-low-size-SimpleBi.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +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 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 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 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 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 { diff --git a/patches/server/0068-Moonrise-fluid-method-optimisations.patch b/patches/server/0068-Moonrise-fluid-method-optimisations.patch new file mode 100644 index 00000000..6bc60e9e --- /dev/null +++ b/patches/server/0068-Moonrise-fluid-method-optimisations.patch @@ -0,0 +1,325 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +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 implements WritableRegistry { + }; + 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> key, Lifecycle lifecycle) { + this(key, lifecycle, false); + } +@@ -145,6 +158,7 @@ public class MappedRegistry implements WritableRegistry { + 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 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 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 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 { ++public final class FluidState extends StateHolder implements ca.spottedleaf.moonrise.patches.fluid.FluidFluidState { // Moonrise - fluid method optimisations + public static final Codec 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 { + 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 { + } + + 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 { + } + + 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 { + } + + 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 diff --git a/patches/server/0069-Moonrise-optimise-palette-reads.patch b/patches/server/0069-Moonrise-optimise-palette-reads.patch new file mode 100644 index 00000000..d6affb17 --- /dev/null +++ b/patches/server/0069-Moonrise-optimise-palette-reads.patch @@ -0,0 +1,364 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +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 { ++ ++ public default T[] moonrise$getRawPalette(final FastPaletteData 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 { ++ ++ 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 implements IdMap { ++public class CrudeIncrementalIntIdentityHashBiMap implements IdMap, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // 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 implements IdMap { + private int nextId; + private int size; + ++ // Moonrise start - optimise palette reads ++ private ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData reference; ++ ++ @Override ++ public final K[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData 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 implements IdMap { + 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 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 implements Palette { ++public class HashMapPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Moonrise - optimise palette reads + private final IdMap registry; + private final CrudeIncrementalIntIdentityHashBiMap values; + private final PaletteResize resizeHandler; + private final int bits; + ++ // Moonrise start - optimise palette reads ++ @Override ++ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { ++ return ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette) this.values).moonrise$getRawPalette(container); ++ } ++ // Moonrise end - optimise palette reads ++ + public HashMapPalette(IdMap idList, int bits, PaletteResize listener, List 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 implements Palette { ++public class LinearPalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Moonrise - optimise palette reads + private final IdMap registry; + private final T[] values; + private final PaletteResize 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 container) { ++ return this.values; ++ } ++ // Moonrise end - optimise palette reads ++ + private LinearPalette(IdMap idList, int bits, PaletteResize listener, List 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 { ++public interface Palette extends ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Moonrise - optimise palette reads + int idFor(T object); + + boolean maybeHas(Predicate 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 implements PaletteResize, PalettedContainer + // this.threadingDetector.checkAndUnlock(); // Paper - disable this + } + ++ // Moonrise start - optimise palette reads ++ private void updateData(final PalettedContainer.Data data) { ++ if (data != null) { ++ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData) (Object) data).moonrise$setPalette( ++ ((ca.spottedleaf.moonrise.patches.fast_palette.FastPalette) data.palette).moonrise$getRawPalette((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData) (Object) data) ++ ); ++ } ++ } ++ ++ private T readPaletteSlow(final PalettedContainer.Data data, final int paletteIdx) { ++ return data.palette.valueFor(paletteIdx); ++ } ++ ++ private T readPalette(final PalettedContainer.Data data, final int paletteIdx) { ++ final T[] palette = ((ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData) (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 Codec> codecRW(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue) { return PalettedContainer.codecRW(idList, entryCodec, paletteProvider, defaultValue, null); } + public static Codec> codecRW(IdMap idList, Codec entryCodec, PalettedContainer.Strategy paletteProvider, T defaultValue, T @org.jetbrains.annotations.Nullable [] presetValues) { +@@ -130,6 +157,7 @@ public class PalettedContainer implements PaletteResize, 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 implements PaletteResize, 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 implements PaletteResize, 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 createOrReuseData(@Nullable PalettedContainer.Data previousData, int bits) { +@@ -176,6 +206,7 @@ public class PalettedContainer implements PaletteResize, 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 implements PaletteResize, 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 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 implements PaletteResize, PalettedContainer + } + + public T get(int index) { // Paper - public +- PalettedContainer.Data data = this.data; +- return data.palette.valueFor(data.storage.get(index)); ++ // Moonrise start - optimise palette reads ++ final PalettedContainer.Data data = this.data; ++ return this.readPalette(data, data.storage.get(index)); ++ // Moonrise end - optimise palette reads + } + + @Override +@@ -256,6 +292,7 @@ public class PalettedContainer implements PaletteResize, 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 implements PaletteResize, PalettedContainer + void accept(T object, int count); + } + +- static record Data(PalettedContainer.Configuration configuration, BitStorage storage, Palette palette) { ++ // Moonrise start - optimise palette reads ++ public static final class Data implements ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData { ++ ++ private final PalettedContainer.Configuration configuration; ++ private final BitStorage storage; ++ private final Palette palette; ++ ++ private T[] moonrise$palette; ++ ++ public Data(final PalettedContainer.Configuration configuration, final BitStorage storage, final Palette palette) { ++ this.configuration = configuration; ++ this.storage = storage; ++ this.palette = palette; ++ } ++ ++ public PalettedContainer.Configuration configuration() { ++ return this.configuration; ++ } ++ ++ public BitStorage storage() { ++ return this.storage; ++ } ++ ++ public Palette 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 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 implements Palette { ++public class SingleValuePalette implements Palette, ca.spottedleaf.moonrise.patches.fast_palette.FastPalette { // Moonrise - optimise palette reads + private final IdMap registry; + @Nullable + private T value; + private final PaletteResize resizeHandler; + ++ // Moonrise start - optimise palette reads ++ private T[] rawPalette; ++ ++ @Override ++ public final T[] moonrise$getRawPalette(final ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData container) { ++ if (this.rawPalette != null) { ++ return this.rawPalette; ++ } ++ return this.rawPalette = (T[]) new Object[]{this.value}; ++ } ++ // Moonrise end - optimise palette reads ++ + public SingleValuePalette(IdMap idList, PaletteResize listener, List entries) { + this.registry = idList; + this.resizeHandler = listener; +@@ -33,6 +45,11 @@ public class SingleValuePalette implements Palette { + 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 implements Palette { + @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 diff --git a/patches/server/0065-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch b/patches/server/0070-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch similarity index 100% rename from patches/server/0065-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch rename to patches/server/0070-Redirect-vanilla-getProfiler-in-PathNavigationRegion.patch diff --git a/patches/server/0066-Fix-MC-65198.patch b/patches/server/0071-Fix-MC-65198.patch similarity index 100% rename from patches/server/0066-Fix-MC-65198.patch rename to patches/server/0071-Fix-MC-65198.patch diff --git a/patches/server/0067-Including-5s-in-getTPS.patch b/patches/server/0072-Including-5s-in-getTPS.patch similarity index 100% rename from patches/server/0067-Including-5s-in-getTPS.patch rename to patches/server/0072-Including-5s-in-getTPS.patch diff --git a/patches/server/0068-Remove-useless-creating-stats-json-bases-on-player-n.patch b/patches/server/0073-Remove-useless-creating-stats-json-bases-on-player-n.patch similarity index 93% rename from patches/server/0068-Remove-useless-creating-stats-json-bases-on-player-n.patch rename to patches/server/0073-Remove-useless-creating-stats-json-bases-on-player-n.patch index 92020111..8cbfd3a7 100644 --- a/patches/server/0068-Remove-useless-creating-stats-json-bases-on-player-n.patch +++ b/patches/server/0073-Remove-useless-creating-stats-json-bases-on-player-n.patch @@ -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 { diff --git a/patches/server/0069-Don-t-throw-exception-on-missing-ResourceKey-value.patch b/patches/server/0074-Don-t-throw-exception-on-missing-ResourceKey-value.patch similarity index 100% rename from patches/server/0069-Don-t-throw-exception-on-missing-ResourceKey-value.patch rename to patches/server/0074-Don-t-throw-exception-on-missing-ResourceKey-value.patch diff --git a/patches/server/0070-Improve-Purpur-AFK-system.patch b/patches/server/0075-Improve-Purpur-AFK-system.patch similarity index 99% rename from patches/server/0070-Improve-Purpur-AFK-system.patch rename to patches/server/0075-Improve-Purpur-AFK-system.patch index 7d7b17e2..7eba2959 100644 --- a/patches/server/0070-Improve-Purpur-AFK-system.patch +++ b/patches/server/0075-Improve-Purpur-AFK-system.patch @@ -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 { diff --git a/patches/server/0071-Virtual-Thread-for-async-scheduler.patch b/patches/server/0076-Virtual-Thread-for-async-scheduler.patch similarity index 100% rename from patches/server/0071-Virtual-Thread-for-async-scheduler.patch rename to patches/server/0076-Virtual-Thread-for-async-scheduler.patch diff --git a/patches/server/0072-Mirai-Configurable-chat-message-signatures.patch b/patches/server/0077-Mirai-Configurable-chat-message-signatures.patch similarity index 99% rename from patches/server/0072-Mirai-Configurable-chat-message-signatures.patch rename to patches/server/0077-Mirai-Configurable-chat-message-signatures.patch index 8e35cc2a..d7353de6 100644 --- a/patches/server/0072-Mirai-Configurable-chat-message-signatures.patch +++ b/patches/server/0077-Mirai-Configurable-chat-message-signatures.patch @@ -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 { diff --git a/patches/server/0073-Cache-player-profileResult.patch b/patches/server/0078-Cache-player-profileResult.patch similarity index 96% rename from patches/server/0073-Cache-player-profileResult.patch rename to patches/server/0078-Cache-player-profileResult.patch index 14827e0e..2e1ea892 100644 --- a/patches/server/0073-Cache-player-profileResult.patch +++ b/patches/server/0078-Cache-player-profileResult.patch @@ -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 diff --git a/patches/server/0074-Prevent-change-non-editable-sign-warning-spam-in-con.patch b/patches/server/0079-Prevent-change-non-editable-sign-warning-spam-in-con.patch similarity index 100% rename from patches/server/0074-Prevent-change-non-editable-sign-warning-spam-in-con.patch rename to patches/server/0079-Prevent-change-non-editable-sign-warning-spam-in-con.patch diff --git a/patches/server/0075-Matter-Secure-Seed.patch b/patches/server/0080-Matter-Secure-Seed.patch similarity index 99% rename from patches/server/0075-Matter-Secure-Seed.patch rename to patches/server/0080-Matter-Secure-Seed.patch index b863ca1d..3ffd5f9a 100644 --- a/patches/server/0075-Matter-Secure-Seed.patch +++ b/patches/server/0080-Matter-Secure-Seed.patch @@ -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. diff --git a/patches/server/0076-Matter-Seed-Command.patch b/patches/server/0081-Matter-Seed-Command.patch similarity index 100% rename from patches/server/0076-Matter-Seed-Command.patch rename to patches/server/0081-Matter-Seed-Command.patch diff --git a/patches/server/0077-Ignore-terminal-provider-warning.patch b/patches/server/0082-Ignore-terminal-provider-warning.patch similarity index 100% rename from patches/server/0077-Ignore-terminal-provider-warning.patch rename to patches/server/0082-Ignore-terminal-provider-warning.patch diff --git a/patches/server/0078-Fix-console-freeze-above-JAVA-22.patch b/patches/server/0083-Fix-console-freeze-above-JAVA-22.patch similarity index 100% rename from patches/server/0078-Fix-console-freeze-above-JAVA-22.patch rename to patches/server/0083-Fix-console-freeze-above-JAVA-22.patch diff --git a/patches/server/0079-Fix-console-output-display-on-Pterodactyl-panel.patch b/patches/server/0084-Fix-console-output-display-on-Pterodactyl-panel.patch similarity index 100% rename from patches/server/0079-Fix-console-output-display-on-Pterodactyl-panel.patch rename to patches/server/0084-Fix-console-output-display-on-Pterodactyl-panel.patch diff --git a/patches/server/0080-Faster-Random-Generator.patch b/patches/server/0085-Faster-Random-Generator.patch similarity index 100% rename from patches/server/0080-Faster-Random-Generator.patch rename to patches/server/0085-Faster-Random-Generator.patch diff --git a/patches/server/0081-Don-t-save-primed-tnt-entity.patch b/patches/server/0086-Don-t-save-primed-tnt-entity.patch similarity index 100% rename from patches/server/0081-Don-t-save-primed-tnt-entity.patch rename to patches/server/0086-Don-t-save-primed-tnt-entity.patch diff --git a/patches/server/0082-Don-t-save-falling-block-entity.patch b/patches/server/0087-Don-t-save-falling-block-entity.patch similarity index 100% rename from patches/server/0082-Don-t-save-falling-block-entity.patch rename to patches/server/0087-Don-t-save-falling-block-entity.patch diff --git a/patches/server/0083-Configurable-connection-message.patch b/patches/server/0088-Configurable-connection-message.patch similarity index 98% rename from patches/server/0083-Configurable-connection-message.patch rename to patches/server/0088-Configurable-connection-message.patch index 936e58e0..34932d80 100644 --- a/patches/server/0083-Configurable-connection-message.patch +++ b/patches/server/0088-Configurable-connection-message.patch @@ -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 { diff --git a/patches/server/0084-Configurable-unknown-command-message.patch b/patches/server/0089-Configurable-unknown-command-message.patch similarity index 100% rename from patches/server/0084-Configurable-unknown-command-message.patch rename to patches/server/0089-Configurable-unknown-command-message.patch diff --git a/patches/server/0085-Airplane-Remove-stream-in-PoiCompetitorScan.patch b/patches/server/0090-Airplane-Remove-stream-in-PoiCompetitorScan.patch similarity index 100% rename from patches/server/0085-Airplane-Remove-stream-in-PoiCompetitorScan.patch rename to patches/server/0090-Airplane-Remove-stream-in-PoiCompetitorScan.patch diff --git a/patches/server/0086-Remove-stream-in-BlockBehaviour-cache-blockstate.patch b/patches/server/0091-Remove-stream-in-BlockBehaviour-cache-blockstate.patch similarity index 100% rename from patches/server/0086-Remove-stream-in-BlockBehaviour-cache-blockstate.patch rename to patches/server/0091-Remove-stream-in-BlockBehaviour-cache-blockstate.patch diff --git a/patches/server/0087-Remove-stream-in-RecipeManager-getRecipeFor.patch b/patches/server/0092-Remove-stream-in-RecipeManager-getRecipeFor.patch similarity index 100% rename from patches/server/0087-Remove-stream-in-RecipeManager-getRecipeFor.patch rename to patches/server/0092-Remove-stream-in-RecipeManager-getRecipeFor.patch diff --git a/patches/server/0088-Remove-stream-in-entity-visible-effects-filter.patch b/patches/server/0093-Remove-stream-in-entity-visible-effects-filter.patch similarity index 100% rename from patches/server/0088-Remove-stream-in-entity-visible-effects-filter.patch rename to patches/server/0093-Remove-stream-in-entity-visible-effects-filter.patch diff --git a/patches/server/0089-Remove-stream-and-double-iteration-in-enough-deep-sl.patch b/patches/server/0094-Remove-stream-and-double-iteration-in-enough-deep-sl.patch similarity index 100% rename from patches/server/0089-Remove-stream-and-double-iteration-in-enough-deep-sl.patch rename to patches/server/0094-Remove-stream-and-double-iteration-in-enough-deep-sl.patch diff --git a/patches/server/0090-Remove-stream-in-trial-spawner-ticking.patch b/patches/server/0095-Remove-stream-in-trial-spawner-ticking.patch similarity index 100% rename from patches/server/0090-Remove-stream-in-trial-spawner-ticking.patch rename to patches/server/0095-Remove-stream-in-trial-spawner-ticking.patch diff --git a/patches/server/0091-Remove-stream-in-Brain.patch b/patches/server/0096-Remove-stream-in-Brain.patch similarity index 100% rename from patches/server/0091-Remove-stream-in-Brain.patch rename to patches/server/0096-Remove-stream-in-Brain.patch diff --git a/patches/server/0092-Remove-stream-in-BehaviorUtils.patch b/patches/server/0097-Remove-stream-in-BehaviorUtils.patch similarity index 100% rename from patches/server/0092-Remove-stream-in-BehaviorUtils.patch rename to patches/server/0097-Remove-stream-in-BehaviorUtils.patch diff --git a/patches/server/0093-Remove-stream-in-YieldJobSite.patch b/patches/server/0098-Remove-stream-in-YieldJobSite.patch similarity index 100% rename from patches/server/0093-Remove-stream-in-YieldJobSite.patch rename to patches/server/0098-Remove-stream-in-YieldJobSite.patch diff --git a/patches/server/0094-Replace-Entity-active-effects-map-with-optimized-col.patch b/patches/server/0099-Replace-Entity-active-effects-map-with-optimized-col.patch similarity index 69% rename from patches/server/0094-Replace-Entity-active-effects-map-with-optimized-col.patch rename to patches/server/0099-Replace-Entity-active-effects-map-with-optimized-col.patch index 67b44a16..57d6d007 100644 --- a/patches/server/0094-Replace-Entity-active-effects-map-with-optimized-col.patch +++ b/patches/server/0099-Replace-Entity-active-effects-map-with-optimized-col.patch @@ -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, MobEffectInstance> activeEffects = Maps.newHashMap(); -+ public final Map, 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, MobEffectInstance> activeEffects = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(0); // Leaf - Replace Entity active effects map with optimized collection + public final Map, MobEffectInstance> activeEffects = Maps.newHashMap(); private final NonNullList lastHandItemStacks; private final NonNullList 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 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); diff --git a/patches/server/0095-Replace-brain-maps-with-optimized-collection.patch b/patches/server/0100-Replace-brain-maps-with-optimized-collection.patch similarity index 100% rename from patches/server/0095-Replace-brain-maps-with-optimized-collection.patch rename to patches/server/0100-Replace-brain-maps-with-optimized-collection.patch diff --git a/patches/server/0101-Replace-criterion-map-with-optimized-collection.patch b/patches/server/0101-Replace-criterion-map-with-optimized-collection.patch new file mode 100644 index 00000000..769a68e5 --- /dev/null +++ b/patches/server/0101-Replace-criterion-map-with-optimized-collection.patch @@ -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 codec; +- public final Map, Set>> criterionData = new java.util.IdentityHashMap<>(); // Paper - fix advancement data player leakage ++ public final Map, Set>> 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; diff --git a/patches/server/0096-Reduce-worldgen-allocations.patch b/patches/server/0102-Reduce-worldgen-allocations.patch similarity index 98% rename from patches/server/0096-Reduce-worldgen-allocations.patch rename to patches/server/0102-Reduce-worldgen-allocations.patch index a07bccbf..f61e49b6 100644 --- a/patches/server/0096-Reduce-worldgen-allocations.patch +++ b/patches/server/0102-Reduce-worldgen-allocations.patch @@ -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 { diff --git a/patches/server/0097-Fix-MC-183518.patch b/patches/server/0103-Fix-MC-183518.patch similarity index 100% rename from patches/server/0097-Fix-MC-183518.patch rename to patches/server/0103-Fix-MC-183518.patch diff --git a/patches/server/0098-Use-caffeine-cache-kickPermission-instead-of-using-g.patch b/patches/server/0104-Use-caffeine-cache-kickPermission-instead-of-using-g.patch similarity index 100% rename from patches/server/0098-Use-caffeine-cache-kickPermission-instead-of-using-g.patch rename to patches/server/0104-Use-caffeine-cache-kickPermission-instead-of-using-g.patch diff --git a/patches/server/0099-Do-not-place-player-if-the-server-is-full.patch b/patches/server/0105-Do-not-place-player-if-the-server-is-full.patch similarity index 97% rename from patches/server/0099-Do-not-place-player-if-the-server-is-full.patch rename to patches/server/0105-Do-not-place-player-if-the-server-is-full.patch index 77d78b4e..38f578e8 100644 --- a/patches/server/0099-Do-not-place-player-if-the-server-is-full.patch +++ b/patches/server/0105-Do-not-place-player-if-the-server-is-full.patch @@ -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 { diff --git a/patches/server/0100-Fix-MC-200418.patch b/patches/server/0106-Fix-MC-200418.patch similarity index 100% rename from patches/server/0100-Fix-MC-200418.patch rename to patches/server/0106-Fix-MC-200418.patch diff --git a/patches/server/0101-Fix-MC-119417.patch b/patches/server/0107-Fix-MC-119417.patch similarity index 100% rename from patches/server/0101-Fix-MC-119417.patch rename to patches/server/0107-Fix-MC-119417.patch diff --git a/patches/server/0102-Fix-MC-223153.patch b/patches/server/0108-Fix-MC-223153.patch similarity index 100% rename from patches/server/0102-Fix-MC-223153.patch rename to patches/server/0108-Fix-MC-223153.patch diff --git a/patches/server/0103-Optimize-LeavesProtocolManager-init-protocol.patch b/patches/server/0109-Optimize-LeavesProtocolManager-init-protocol.patch similarity index 100% rename from patches/server/0103-Optimize-LeavesProtocolManager-init-protocol.patch rename to patches/server/0109-Optimize-LeavesProtocolManager-init-protocol.patch diff --git a/patches/server/0104-Cache-CraftEntityType-minecraftToBukkit-convert.patch b/patches/server/0110-Cache-CraftEntityType-minecraftToBukkit-convert.patch similarity index 100% rename from patches/server/0104-Cache-CraftEntityType-minecraftToBukkit-convert.patch rename to patches/server/0110-Cache-CraftEntityType-minecraftToBukkit-convert.patch diff --git a/patches/server/0105-Configurable-player-knockback-zombie.patch b/patches/server/0111-Configurable-player-knockback-zombie.patch similarity index 93% rename from patches/server/0105-Configurable-player-knockback-zombie.patch rename to patches/server/0111-Configurable-player-knockback-zombie.patch index 8e10f99b..0a01c8c5 100644 --- a/patches/server/0105-Configurable-player-knockback-zombie.patch +++ b/patches/server/0111-Configurable-player-knockback-zombie.patch @@ -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 { } } diff --git a/patches/server/0106-Hide-specified-item-components-to-clients.patch b/patches/server/0112-Hide-specified-item-components-to-clients.patch similarity index 98% rename from patches/server/0106-Hide-specified-item-components-to-clients.patch rename to patches/server/0112-Hide-specified-item-components-to-clients.patch index 882a310a..e6c86a38 100644 --- a/patches/server/0106-Hide-specified-item-components-to-clients.patch +++ b/patches/server/0112-Hide-specified-item-components-to-clients.patch @@ -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(); diff --git a/patches/server/0107-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch b/patches/server/0113-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch similarity index 100% rename from patches/server/0107-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch rename to patches/server/0113-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch diff --git a/patches/server/0108-Paper-PR-Reduce-work-done-in-CraftMapCanvas.drawImag.patch b/patches/server/0114-Paper-PR-Reduce-work-done-in-CraftMapCanvas.drawImag.patch similarity index 100% rename from patches/server/0108-Paper-PR-Reduce-work-done-in-CraftMapCanvas.drawImag.patch rename to patches/server/0114-Paper-PR-Reduce-work-done-in-CraftMapCanvas.drawImag.patch diff --git a/patches/server/0109-Paper-PR-Throttle-failed-spawn-attempts.patch b/patches/server/0115-Paper-PR-Throttle-failed-spawn-attempts.patch similarity index 100% rename from patches/server/0109-Paper-PR-Throttle-failed-spawn-attempts.patch rename to patches/server/0115-Paper-PR-Throttle-failed-spawn-attempts.patch diff --git a/patches/server/0110-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch b/patches/server/0116-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch similarity index 95% rename from patches/server/0110-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch rename to patches/server/0116-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch index 0f7f1b58..040805ab 100644 --- a/patches/server/0110-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch +++ b/patches/server/0116-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch @@ -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 { diff --git a/patches/server/0111-Dont-send-useless-entity-packets.patch b/patches/server/0117-Dont-send-useless-entity-packets.patch similarity index 100% rename from patches/server/0111-Dont-send-useless-entity-packets.patch rename to patches/server/0117-Dont-send-useless-entity-packets.patch diff --git a/patches/server/0112-Don-t-spawn-if-lastSpawnState-is-null.patch b/patches/server/0118-Don-t-spawn-if-lastSpawnState-is-null.patch similarity index 100% rename from patches/server/0112-Don-t-spawn-if-lastSpawnState-is-null.patch rename to patches/server/0118-Don-t-spawn-if-lastSpawnState-is-null.patch diff --git a/patches/server/0113-Multithreaded-Tracker.patch b/patches/server/0119-Multithreaded-Tracker.patch similarity index 99% rename from patches/server/0113-Multithreaded-Tracker.patch rename to patches/server/0119-Multithreaded-Tracker.patch index 4372ce6b..38d7848d 100644 --- a/patches/server/0113-Multithreaded-Tracker.patch +++ b/patches/server/0119-Multithreaded-Tracker.patch @@ -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. diff --git a/patches/server/0114-Nitori-Async-playerdata-Save.patch b/patches/server/0120-Nitori-Async-playerdata-Save.patch similarity index 100% rename from patches/server/0114-Nitori-Async-playerdata-Save.patch rename to patches/server/0120-Nitori-Async-playerdata-Save.patch diff --git a/patches/server/0115-Change-max-stack-count.patch b/patches/server/0121-Change-max-stack-count.patch similarity index 100% rename from patches/server/0115-Change-max-stack-count.patch rename to patches/server/0121-Change-max-stack-count.patch diff --git a/patches/server/0116-Reduce-object-complexity-to-make-block-isValid-calls.patch b/patches/server/0122-Reduce-object-complexity-to-make-block-isValid-calls.patch similarity index 100% rename from patches/server/0116-Reduce-object-complexity-to-make-block-isValid-calls.patch rename to patches/server/0122-Reduce-object-complexity-to-make-block-isValid-calls.patch diff --git a/patches/server/0117-Optimize-nearby-alive-players-for-spawning.patch b/patches/server/0123-Optimize-nearby-alive-players-for-spawning.patch similarity index 98% rename from patches/server/0117-Optimize-nearby-alive-players-for-spawning.patch rename to patches/server/0123-Optimize-nearby-alive-players-for-spawning.patch index 037db9ad..839e76db 100644 --- a/patches/server/0117-Optimize-nearby-alive-players-for-spawning.patch +++ b/patches/server/0123-Optimize-nearby-alive-players-for-spawning.patch @@ -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 { diff --git a/patches/server/0118-Cache-blockstate-cache.patch b/patches/server/0124-Cache-blockstate-cache.patch similarity index 100% rename from patches/server/0118-Cache-blockstate-cache.patch rename to patches/server/0124-Cache-blockstate-cache.patch diff --git a/patches/server/0119-Fix-MC-177381.patch b/patches/server/0125-Fix-MC-177381.patch similarity index 100% rename from patches/server/0119-Fix-MC-177381.patch rename to patches/server/0125-Fix-MC-177381.patch diff --git a/patches/server/0120-Asynchronous-locator.patch b/patches/server/0126-Asynchronous-locator.patch similarity index 86% rename from patches/server/0120-Asynchronous-locator.patch rename to patches/server/0126-Asynchronous-locator.patch index e7622606..bd83e631 100644 --- a/patches/server/0120-Asynchronous-locator.patch +++ b/patches/server/0126-Asynchronous-locator.patch @@ -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 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>> 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> 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 diff --git a/patches/server/0121-Virtual-thread-for-chat-executor.patch b/patches/server/0127-Virtual-thread-for-chat-executor.patch similarity index 100% rename from patches/server/0121-Virtual-thread-for-chat-executor.patch rename to patches/server/0127-Virtual-thread-for-chat-executor.patch diff --git a/patches/server/0122-Use-QuickSort-in-NearestLivingEntitySensor.patch b/patches/server/0128-Use-QuickSort-in-NearestLivingEntitySensor.patch similarity index 100% rename from patches/server/0122-Use-QuickSort-in-NearestLivingEntitySensor.patch rename to patches/server/0128-Use-QuickSort-in-NearestLivingEntitySensor.patch diff --git a/patches/server/0123-Further-reduce-memory-footprint-of-CompoundTag.patch b/patches/server/0129-Further-reduce-memory-footprint-of-CompoundTag.patch similarity index 100% rename from patches/server/0123-Further-reduce-memory-footprint-of-CompoundTag.patch rename to patches/server/0129-Further-reduce-memory-footprint-of-CompoundTag.patch diff --git a/patches/server/0124-Optimize-Entity-distanceToSqr.patch b/patches/server/0130-Optimize-Entity-distanceToSqr.patch similarity index 100% rename from patches/server/0124-Optimize-Entity-distanceToSqr.patch rename to patches/server/0130-Optimize-Entity-distanceToSqr.patch diff --git a/patches/server/0131-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch b/patches/server/0131-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch new file mode 100644 index 00000000..71b573c3 --- /dev/null +++ b/patches/server/0131-EMC-Don-t-use-snapshots-for-TileEntity-getOwner.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +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); ++ } ++} diff --git a/patches/server/0132-EMC-Default-don-t-use-blockstate-snapshots.patch b/patches/server/0132-EMC-Default-don-t-use-blockstate-snapshots.patch new file mode 100644 index 00000000..826020a3 --- /dev/null +++ b/patches/server/0132-EMC-Default-don-t-use-blockstate-snapshots.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +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 diff --git a/patches/server/0133-Cache-tile-entity-position.patch b/patches/server/0133-Cache-tile-entity-position.patch new file mode 100644 index 00000000..0161909b --- /dev/null +++ b/patches/server/0133-Cache-tile-entity-position.patch @@ -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 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 diff --git a/patches/server/0134-TT20-Lag-compensation.patch b/patches/server/0134-TT20-Lag-compensation.patch new file mode 100644 index 00000000..9234aca0 --- /dev/null +++ b/patches/server/0134-TT20-Lag-compensation.patch @@ -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 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 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